本文以FasionMNIST/加州房价数据集为例,介绍KerasAPI进行分类问题/回归问题模型训练的方法
Tensorflow版本
Tensorflow和keara都需要2.0及以上版本
import tensorflow as tf
from tensorflow import keras
print(tf.__version__)
print(keras.__version__)
分类MLP构建
数据集
fashion MNIST dataset,数据集有60000张衣服鞋子的图片,大小为28X28。
Keras可以通过keras.datasets方法来下载主流的数据集,fashion MNIST dataset已经区分了训练集(50000张)和测试集(10000张), 但最好从训练集中划出一部分作为验证集(Validation set)
import tensorflow as tf
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()
# 由于数据是最大值为255的灰度图像,除于255进行归一化
X_valid, X_train = X_train_full[:5000] / 255., X_train_full[5000:] / 255.
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test / 255.
模型训练
定义网络层
Sequential API方法
Sequential网络层定义有两种方法,一种是add layers方法,有点笨拙
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
model.add(keras.layers.Dense(300, activation="relu"))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
另外一种整体括号内定义网络层,推荐这种方法
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(300, activation="relu"),
keras.layers.Dense(100, activation="relu"),
keras.layers.Dense(10, activation="softmax")
])
解释:
Sequential是Keras最简单的网络结构定义方式,按照从上到下(代码文本)讲单层的网络连接起来
Flatten的作用是将28X28的数组转化为1D的格式
第4/5行分别定义了两个隐藏层,大小为300/100个神经元,激活函数未relu
第6行定义输出层,由于是多分类问题,使用了“softmax”作为激活函数。
使用model_summary()可以查看模型的结构
使用model.get_layer(), layer.get_weight()可以查看模型的参数
定义损失函数、优化器等
model.compile(loss="sparse_categorical_crossentropy",
optimizer="sgd",
metrics=["accuracy"])
模型训练
和sk-learn一样调用fit()方法
history = model.fit(X_train, y_train, epochs=30,
validation_data=(X_valid, y_valid))
可以方便的运用history数据进行训练过程的可视化
import pandas as pd
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 1)
测试集评估
model.evaluate(X_test, y_test)
模型保存
测试集上能达到要求就可以进行模型保存了,也可以将其部署到生产环境。
# kears模型的格式为h5
model.save("my_keras_FasionMNist_model.h5")
模型预测
# 载入模型
model = keras.models.load_model("my_keras_FasionMNist_model.h5")
X_new = X_test[:1] # 以一个样本为例子,输入是28X28的数组
y_proba = model.predict(X_new) # 由于是10分类问题,softmax输出结果是一个在10分类上概率和为1的10维数组
y_proba.round(2)
y_pred = np.argmax(model.predict(X_new), axis=-1)# 求概率和最大,axis=-1为在每个10维度数组内求
y_pred
回归MLP构建
以加州房价预测数据集为例,模型开发和分类问题类似,就不分模块一一介绍了。
主要区别:
由于输出房价是1维数据,只需要一个神经元,且训练label也是房价,因此不需要激活函数
loss function为MSE
由于数据集比较简单,为防止过拟合,仅适用一个hidden layer,且神经元的个数设置为更低的值
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# load数据集
housing = fetch_california_housing()
X_train_full, X_test, y_train_full, y_test = train_test_split(housing.data, housing.target, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, random_state=42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_valid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)
# 模型定义和训练
model = keras.models.Sequential([
keras.layers.Dense(30, activation="relu", input_shape=X_train.shape[1:]),
keras.layers.Dense(1)
])
model.compile(loss="mean_squared_error", optimizer=keras.optimizers.SGD(lr=1e-3))
history = model.fit(X_train, y_train, epochs=20, validation_data=(X_valid, y_valid))
#模型训练epoch过程MSE可视化
plt.plot(pd.DataFrame(history.history))
plt.grid(True)
plt.gca().set_ylim(0, 1)
plt.show()
mse_test = model.evaluate(X_test, y_test)
X_new = X_test[:3]
y_pred = model.predict(X_new)