深度学习模型调试和监控(7.2)

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.png

图 7.10 TensorBoard指标监控


7.11.png

图 7.11 TensorBoard:激活函数直方图

词嵌入标签可以查看字典中1000个单词的词嵌入位置和空间的关系。因为词嵌入空间是128维,TensorBoard根据所选的降维算法(比如,PCA或者t-SNE)自动降为2D或者3D。在图7.12中,你能清晰地看到两个簇:褒义词和贬义词。


7.12.png

图7.12 TensorBoard:3D交互词嵌入可视化

Graph标签显示Keras模型中low-level的TensorFlow操作图,见图7.13。你用Keras构建模型时可能看似简单,但其实挺复杂,它有许多相关的梯度下降过程。这只是Keras简化了原始TensorFlow从头定义模型。


7.13.png

图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.png

图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.png

图7.15 带形状信息的模型

7.2.3 小结
  • Keras callback能监控模型训练,以及基于模型状态采取行动

  • TensorBoard可以在浏览器上可视化模型。你也可以在Keras模型中用TensorBoard的callback。

未完待续。。。


侠天,专注于大数据、机器学习和数学相关的内容,并有个人公众号:bigdata_ny分享相关技术文章。

若发现以上文章有任何不妥,请联系我。

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容