7.2 深度学习模型调试和监控
本小节学习如何监控模型训练的过程。
7.2.1 模型训练中应用回调
当你训练模型时,有许多情况是在起始阶段预估不了的。比如,你不能给出具体需要多少个epoch达到优化的验证损失。到目前为止的所有例子,都是采用先训练足够的epoch直到开始过拟合,然后使用前面得到的最优epoch值重新训练一次模型。当然这种方法有点浪费资源。
解决上述问题的更好方式是,当你监测到验证损失不再优化时停止模型训练。这可以通过Keras callback实现。callback是一个类实例对象,调用 fit 函数时传入模型,并在模型训练过程调用。它可以访问模型状态和性能的各种数据,也能中断模型训练、保存模型、加载不同的权重数据或者改变模型状态。
下面是使用 callback 的各种方式:
- 模型快照:在模型训练过程中,在不同的时间点保存模型的当前权重
- Early stopping:当验证损失不再优化时,中断模型训练
- 动态调整参数值:比如,优化器的学习率
- 记录训练集和验证集指标,或者可视化表示学习:
keras.callbacks 模块包含一系列内建的callback,不限于下面的列表:
keras.callbacks.ModelCheckpoint
keras.callbacks.EarlyStopping
keras.callbacks.LearningRateScheduler keras.callbacks.ReduceLROnPlateau
keras.callbacks.CSVLogger
下面讲解 ModelCheckpoint、EarlyStopping和ReduceLROnPlateau。
ModelCheckpoint和EarlyStopping回调
EarlyStopping回调可以使模型训练固定epoch后终止。比如,当一开始过拟合时终止模型训练,这能避免重新训练模型。EarlyStopping回调需要和ModelCheckpoint结合使用,ModelCheckpoint回调能在模型训练过程中持续的保存模型,你也可以选择只保留当前最新的模型。
import keras
'''Callbacks are passed to the model
via the callbacks argument in fit,
which takes a list of callbacks.
You can pass any number of callbacks.
'''
callbacks_list = [
'''Interrupts training when improvement stops
'''
keras.callbacks.EarlyStopping(
'''Monitors the model’s validation accuracy
'''
monitor='acc',
'''Interrupts training when accuracy
has stopped improving for more than
one epoch (that is, two epochs)
'''
patience=1,
),
'''Saves the current weights after every epoch
'''
keras.callbacks.ModelCheckpoint(
''' Path to the destination model file
'''
filepath='my_model.h5',
'''These two arguments mean you won’t overwrite
the model file unless val_loss has improved,
which allows you to keep the best model
seen during training.
'''
monitor='val_loss',
save_best_only=True,
)
]
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
'''You monitor accuracy,
so it should be part of the model’s metrics.
'''
metrics=['acc'])
'''Note that because the callback will
monitor validation loss and validation accuracy,
you need to pass validation_data to the call to fit.
'''
model.fit(x, y,
epochs=10,
batch_size=32,
callbacks=callbacks_list,
validation_data=(x_val, y_val))
ReduceLROnPlateau回调
当验证损失不再优化时,使用 ReduceLROnPlateau 回调减小学习率。减小或者增加学习率可以摆脱模型训练中的局部极小值。下面是 ReduceLROnPlateau 回调的示例:
callbacks_list = [
keras.callbacks.ReduceLROnPlateau(
'''Monitors the model’s validation loss
'''
monitor='val_loss',
'''Divides the learning rate by 10
when triggered
'''
factor=0.1,
'''The callback is triggered after the validation
loss has stopped improving for 10 epochs.
'''
patience=10,
)
]
'''Because the callback will monitor
the validation loss, you need to pass
validation_data to the call to fit.
'''
model.fit(x, y,
epochs=10,
batch_size=32,
callbacks=callbacks_list,
validation_data=(x_val, y_val))
编写自定义回调
在模型训练中,如果你需要执行的某操作没有相应的内建回调callback,可以通过实现keras.callbacks.Callback的子类自定义实现callback。你能实现任意数量的下列方法,它们在模型训练的不同时间点调用:
on_epoch_begin:在每个epoch开始时调用
on_epoch_end:在每个epoch结尾时调用
on_batch_begin:在每个batch处理前调用
on_batch_end:在每个batch处理后调用
on_train_begin:在每个训练开始时调用
on_train_end:在每个训练结尾时调用
上述方法以logs参数调用。logs参数是一个字典,其包含了一系列与当前batch或epoch相关的信息:比如训练集和验证集指标等。除此之外,callback可以访问下面的属性:
- self.model:回调调用的模型引用
- self.validation_data:传入fit函数作为验证集的数据
下面是一个简单的自定义函数,它将验证集的第一个样本每个epoch结尾处模型的每个layer的激活函数保存到磁盘上(比如Numpy数组):
import keras
import numpy as np
class ActivationLogger(keras.callbacks.Callback):
def set_model(self, model):
'''Called by the parent model before training,
to inform the callback of what model will be calling it
'''
self.model = model
layer_outputs = [layer.output for layer in model.layers]
'''Model instance that returns the activations of every layer
'''
self.activations_model = keras.models.Model(model.input,
layer_outputs)
def on_epoch_end(self, epoch, logs=None):
if self.validation_data is None:
raise RuntimeError('Requires validation_data.')
'''Obtains the first input sample of the validation data
'''
validation_sample = self.validation_data[0][0:1]
activations = self.activations_model.predict(validation_sample)
'''Saves arrays to disk
'''
f = open('activations_at_epoch_' + str(epoch) + '.npz', 'w')
np.savez(f, activations)
f.close()
上述的自定义回调函数看似挺容易。你可以继续深挖Keras的callback。
7.2.2 TensorBoard介绍
TensorBoard是TensorFlow可视化框架。为了更好的研究或者开发模型,你需要丰富、频繁的回调来对模型进行实验。实验的关键点在于获取模型性能的各种信息。
这小节介绍TensorBoard,它是TensorFlow基于浏览器的可视化工具。注意,TensorBoard只适用于以TensorFlow为后端的Keras模型。
TensorBoard主要目的是辅助用户可视化地监控模型训练的细节。你可以在浏览器上访问到以下信息:
- 可视化监测指标
- 可视化模型结构
- 可视化激活函数和梯度的直方图
- 三维可视化词嵌入
下面用一个简单的例子展示上述功能。你将训练一个 1D 卷积模型解决IMDB情感分析的任务。
# Listing 7.7 Text-classification model to use with TensorBoard
import keras
from keras import layers
from keras.datasets import imdb
from keras.preprocessing import sequence
'''Number of words to consider as features
'''
max_features = 2000
'''Cuts off texts after this number of words
(among max_features most common words)
'''
max_len = 500
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
x_test = sequence.pad_sequences(x_test, maxlen=max_len)
model = keras.models.Sequential()
model.add(layers.Embedding(max_features, 128,
input_length=max_len,
name='embed'))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.MaxPooling1D(5))
model.add(layers.Conv1D(32, 7, activation='relu')) model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(1))
model.summary()
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
使用TensorBoard前你需要创建存储log文件的目录。
# Listing 7.8 Creating a directory for TensorBoard log files
$ mkdir my_log_dir
接着启动带有TensorBoard callback实例的模型训练。这个callback将在指定位置写入log事件。
# Listing 7.9 Training the model with a TensorBoard callback
callbacks = [
keras.callbacks.TensorBoard(
'''Log files will be written at this location.
'''
log_dir='my_log_dir',
'''Records activation histograms every 1 epoch
'''
histogram_freq=1,
'''Records embedding data every 1 epoch
'''
embeddings_freq=1,
)
]
history = model.fit(x_train, y_train,
epochs=20,
batch_size=128,
validation_split=0.2,
callbacks=callbacks)
这时可以通过命令行启动TensorBoard服务,其tensorboard可用pip安装:
$ tensorboard --logdir=my_log_dir
然后你可以通过http://localhost:6006 访问模型训练,见图7.10。除了训练集和验证集指标外,你也可以看到直方图,见图7.11。
图 7.10 TensorBoard指标监控
图 7.11 TensorBoard:激活函数直方图
词嵌入标签可以查看字典中1000个单词的词嵌入位置和空间的关系。因为词嵌入空间是128维,TensorBoard根据所选的降维算法(比如,PCA或者t-SNE)自动降为2D或者3D。在图7.12中,你能清晰地看到两个簇:褒义词和贬义词。
图7.12 TensorBoard:3D交互词嵌入可视化
Graph标签显示Keras模型中low-level的TensorFlow操作图,见图7.13。你用Keras构建模型时可能看似简单,但其实挺复杂,它有许多相关的梯度下降过程。这只是Keras简化了原始TensorFlow从头定义模型。
图7.13 TensorBoard:TensorFlow图可视化
Keras也提供layer级别的模型可视化:keras.utils.plot_model工具。使用该工具需要安装Python的pydot和pydot-ng库,以及graphviz库。下面来简单看下:
from keras.utils import plot_model
plot_model(model, to_file='model.png')
上述代码生成PNG图见7.14。
图7.14 用plot_model绘制的模型layer可视化
你也可以显示layer图的形状信息,用plot_model和show_shapes选项,见图7.15:
from keras.utils import plot_model
plot_model(model, show_shapes=True, to_file='model.png')
图7.15 带形状信息的模型
7.2.3 小结
Keras callback能监控模型训练,以及基于模型状态采取行动
TensorBoard可以在浏览器上可视化模型。你也可以在Keras模型中用TensorBoard的callback。
未完待续。。。
侠天,专注于大数据、机器学习和数学相关的内容,并有个人公众号:bigdata_ny分享相关技术文章。
若发现以上文章有任何不妥,请联系我。