3.模型训练
3.1.Keras版本模型训练
• 构建模型(顺序模型、函数式模型、子类模型)
• 模型训练: model.fit()
• 模型验证: model.evaluate()
• 模型预测: model.predict()
• 使用样本加权和类别加权
回调函数
• ModelCheckpoint:定期保存模型。
• EarlyStopping:当训练不再改善验证指标时,停止培训。
• TensorBoard:定期编写可在TensorBoard中可视化的模型日志(更多详细信息,请参见“可视化”部分)。
• CSVLogger:将损失和指标数据流式传输到CSV文件。
多输入、多输出模型
import tensorflow as tf
3.1.1.keras版本模型训练
相关函数
构建模型(顺序模型、函数式模型、子类模型)
模型训练:model.fit()
模型验证:model.evaluate()
模型预测: model.predict()
1 构建模型
inputs = tf.keras.Input(shape=(32,)) #(数据维度32)
x = tf.keras.layers.Dense(64, activation='relu')(inputs) #(64个神经元,)
x = tf.keras.layers.Dense(64, activation='relu')(x)#(64个神经元)
predictions = tf.keras.layers.Dense(10)(x) #(输出是10类)
#- inputs(模型输入)
#- output(模型输出)
model = tf.keras.Model(inputs=inputs, outputs=predictions)
#指定损失函数 (loss) tf.keras.optimizers.RMSprop
#优化器 (optimizer) tf.keras.losses.SparseCategoricalCrossentropy
#指标 (metrics) ['accuracy']
model.compile(optimizer=tf.keras.optimizers.Adam(0.001), #优化器
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), #损失函数
metrics=['accuracy']) #评估函数
###构建数据集
import numpy as np
x_train = np.random.random((1000, 32))
y_train = np.random.randint(10, size=(1000, ))
x_val = np.random.random((200, 32))
y_val = np.random.randint(10, size=(200, ))
x_test = np.random.random((200, 32))
y_test = np.random.randint(10, size=(200, ))
2 模型训练
通过将数据切成大小为“ batch_size”的“批”来训练模型,并针对给定数量的“epoch”重复遍历整个数据集
model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data= (x_val, y_val) )
Train on 1000 samples, validate on 200 samples
Epoch 1/5
1000/1000 [==============================] - 0s 188us/sample - loss: 2.3188 - accuracy: 0.1040 - val_loss: 2.3260 - val_accuracy: 0.0900
...
Epoch 5/5
1000/1000 [==============================] - 0s 163us/sample - loss: 2.2661 - accuracy: 0.1660 - val_loss: 2.3346 - val_accuracy: 0.0650
自动划分验证集
在前面的例子中,我们使用validation_data参数将Numpy数组的元组传递(x_val, y_val)给模型,以在每个时期结束时评估验证损失和验证指标。
还有一个选择:参数validation_split允许您自动保留部分训练数据以供验证。参数值代表要保留用于验证的数据的一部分,因此应将其设置为大于0且小于1的数字。
例如,validation_split=0.2表示“使用20%的数据进行验证”,而validation_split=0.6表示“使用60%的数据用于验证”。
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
Train on 800 samples, validate on 200 samples
800/800 [==============================] - 0s 100us/sample - loss: 2.2449 - accuracy: 0.1787 - val_loss: 2.2530 - val_accuracy: 0.2050
3 模型验证
返回 test loss 和metrics
# Evaluate the model on the test data using `evaluate`
print('\n# Evaluate on test data')
results = model.evaluate(x_test, y_test, batch_size=128)
print('test loss, test acc:', results)
# Generate predictions (probabilities -- the output of the last layer)
# on new data using `predict`
print('\n# Generate predictions for 3 samples')
predictions = model.predict(x_test[:3])
print('predictions shape:', predictions.shape)
# Evaluate on test data
test loss, test acc: [2.3240616512298584, 0.08]
# Generate predictions for 3 samples
predictions shape: (3, 10)
3.1.2.使用样本加权和类别加权
除了输入数据和目标数据外,还可以在使用时将样本权重或类权重传递给模型fit
1 构建模型
# 将生成模型封装为函数,并为每层起名
def get_uncompiled_model():
inputs = tf.keras.Input(shape=(32,), name='digits')
x = tf.keras.layers.Dense(64, activation='relu', name='dense_1')(inputs)
x = tf.keras.layers.Dense(64, activation='relu', name='dense_2')(x)
outputs = tf.keras.layers.Dense(10, name='predictions')(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
return model
def get_compiled_model():
model = get_uncompiled_model()
model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-3),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['sparse_categorical_accuracy'])
return model
2 模型训练
类别加权
import numpy as np
# 设置每个类别对应的权重,类别5:加权
class_weight = {0: 1., 1: 1., 2: 1., 3: 1., 4: 1.,
5: 2.,
6: 1., 7: 1., 8: 1., 9: 1.}
print('Fit with class weight')
model = get_compiled_model()
model.fit(x_train, y_train,
class_weight=class_weight,
batch_size=64,
epochs=4)
Fit with class weight
Train on 1000 samples
Epoch 1/4
1000/1000 [==============================] - 1s 826us/sample - loss: 2.5088 - sparse_categorical_accuracy: 0.0800
...
Epoch 4/4
1000/1000 [==============================] - 0s 75us/sample - loss: 2.4648 - sparse_categorical_accuracy: 0.0900
样本加权
# 设置与y_train相同维度的权重
sample_weight = np.ones(shape=(len(y_train),))
# 对于所有y_train为5的数值加权
sample_weight[y_train == 5] = 2.
model = get_compiled_model()model.fit(x_train, y_train,
sample_weight=sample_weight,
batch_size=64,
epochs=4)
Train on 1000 samples
Epoch 1/4
1000/1000 [==============================] - 1s 901us/sample - loss: 2.5171 - sparse_categorical_accuracy: 0.0820
...
Epoch 4/4
1000/1000 [==============================] - 0s 83us/sample - loss: 2.4733 - sparse_categorical_accuracy: 0.0880
3.1.3.使用回调函数
Keras中的回调是在训练期间(在某个时期开始时,在批处理结束时,在某个时期结束时等)在不同时间点调用的对象,这些对象可用于实现以下行为:
在训练过程中的不同时间点进行验证(除了内置的按时间段验证)
定期或在超过特定精度阈值时对模型进行检查
当训练似乎停滞不前时,更改模型的学习率
当训练似乎停滞不前时,对顶层进行微调
在训练结束或超出特定性能阈值时发送电子邮件或即时消息通知 等等。 回调可以作为列表传递给model.fit
1 EarlyStopping(早停)
monitor: 被监测的数据。
min_delta: 在被监测的数据中被认为是提升的最小变化, 例如,小于 min_delta 的绝对变化会被认为没有提升。
patience: 没有进步的训练轮数,在这之后训练就会被停止。
verbose: 详细信息模式。
mode: {auto, min, max} 其中之一。如果是 min 模式,学习速率会被降低如果被监测的数据已经停止下降; 在 max 模式,学习塑料会被降低如果被监测的数据已经停止上升; 在 auto 模式,方向会被从被监测的数据中自动推断出来。
model = get_compiled_model()
callbacks = [
tf.keras.callbacks.EarlyStopping(
# 当‘val_loss’不再下降时候停止训练
monitor='val_loss',
# “不再下降”被定义为“减少不超过1e-2”
min_delta=1e-2,
# “不再改善”进一步定义为“至少2个epoch”
patience=2,
verbose=1)]
model.fit(x_train, y_train,
epochs=20,
batch_size=64,
callbacks=callbacks,
validation_split=0.2)
Train on 800 samples, validate on 200 samples
Epoch 1/20
800/800 [==============================] - 1s 1ms/sample - loss: 2.3292 - sparse_categorical_accuracy: 0.0938 - val_loss: 2.3100 - val_sparse_categorical_accuracy: 0.0750
Epoch 2/20
800/800 [==============================] - 0s 100us/sample - loss: 2.3007 - sparse_categorical_accuracy: 0.1238 - val_loss: 2.3065 - val_sparse_categorical_accuracy: 0.0800
Epoch 3/20
800/800 [==============================] - 0s 97us/sample - loss: 2.2889 - sparse_categorical_accuracy: 0.1312 - val_loss: 2.3065 - val_sparse_categorical_accuracy: 0.1100
2 checkpoint模型
在相对较大的数据集上训练模型时,至关重要的是要定期保存模型的checkpoint。
最简单的方法是使用ModelCheckpoint回调:
model = get_compiled_model()
callbacks = [
tf.keras.callbacks.ModelCheckpoint(
# 模型保存路径
filepath='mymodel_{epoch}',
# 下面的两个参数意味着当且仅当`val_loss`分数提高时,我们才会覆盖当前检查点。
save_best_only=True,
monitor='val_loss',
#加入这个仅仅保存模型权重
save_weights_only=True,
verbose=1)
]
mode