作者|Andre Ye
编译|VK
起源|Towards Data Science

回调函数是神经网络训练的重要组成部分

回调操作能够在训练的各个阶段执行,可能是在epoch之间,在解决一个batch之后,甚至在满足某个条件的状况下。回调能够利用许多创造性的办法来改良训练和性能,节俭计算资源,并提供无关神经网络外部产生的事件的论断。

本文将具体介绍重要回调的基本原理和代码,以及创立自定义回调的过程。


ReduceLROnPlateau是Keras中默认蕴含的回调。神经网络的学习率决定了梯度的比例因子,因而过高的学习率会导致优化器超过最优值,而学习率过低则会导致训练工夫过长。很难找到一个动态的、成果很好的、不变的学习率。

顾名思义,“升高高原学习率”就是在损失指标进行改善或达到稳固时升高学习率。个别学习率缩小2到10倍,这有助于磨难参数的最佳值。

要应用ReduceLROnPlateau,必须首先创立回调对象。有四个参数很重要:

  • monitor,它用来监督指标
  • factor,它是新的学习率将被升高(乘以)的因子
  • persistence,回调激活之前期待的停滞epoch数
  • min_lr,它能够升高到的最小学习率。这能够避免不必要和不无益的缩小。
from keras.callbacks import ReduceLROnPlateaureduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,                              patience=5, min_lr=0.001)model.fit(X_train, Y_train, callbacks=[reduce_lr])

当应用model.fit时,能够指定回调参数。留神,这能够承受一个列表,因而能够安顿多个回调。

LearningRateScheduler是ReduceLROnPlateau的另一种抉择,它容许用户依据epoch来安顿学习率。如果你晓得(可能来自以前的钻研或试验)网络的学习率在从epochs 1-10时应该是x, 在epochs 10-20是应该是y,LearningRateScheduler能够帮忙实现这些变动。以上epoch的数字能够任意变动。

创立学习率调度器须要一个用户定义的函数,该函数将epoch和learning rate作为参数。返回对象应该是新的学习率。

from keras.callbacks import LearningRateSchedulerdef scheduler(epoch, lr): #定义回调schedule   if lr < 0.001: return lr * 1.5 #如果lr太小,减少lr   elif epoch < 5: return lr #前五个epoch,不扭转lr   elif epoch < 10: return lr * tf.math.exp(-0.1) #第五到第十个epoch,缩小lr   else: return lr * tf.math.exp(-0.05) #第10个epoch之后,缩小量更少  callback = LearningRateScheduler(scheduler) #创立回调对象model.fit(X_train, y_train, epochs=15, callbacks=[callback])

而后,将其转换为Keras回调后,就能够用于模型的训练。这些调度程序十分有用,容许对网络进行管制,但倡议在第一次训练网络时应用ReduceLROnPlateau,因为它更具适应性。而后,能够进行可视化模型,看是否能提供对于如何结构一个适当的LR调度器的相干想法。

此外,你能够同时应用ReduceLROnPlateau和LearningRateScheduler,例如,应用调度程序硬编码一些学习速率(例如在前10个epoch不更改),同时利用自适应能力,在高原上升高学习率以晋升性能。

EarlyStopping能够十分有助于避免在训练模型时产生额定的冗余运行。冗余运行会导致昂扬的计算成本。当网络在给定的时间段内没有失去改善时,网络实现训练并停止使用计算资源。与ReduceLROnPlateau相似,EarlyStopping须要monitor。

from keras.callbacks import EarlyStopping  callback = EarlyStopping(monitor='loss', patience=5)model.fit(X_train, y_train, epochs=15, callbacks=[callback])

TerminateOnNaN有助于避免在训练中产生梯度爆炸问题,因为输出NaN会导致网络的其余局部发生爆炸。如果不采纳TerminateOnNaN,Keras并不阻止网络的训练。另外,nan会导致对计算能力的需要减少。为了避免这些状况产生,增加TerminateOnNaN是一个很好的安全检查。

rom keras.callbacks import TerminateOnNaNmodel.fit(X_train, y_train, epochs=15, callbacks = [TerminateOnNaN()])

因为许多起因,ModelCheckpoint能够以某种频率(兴许每隔10个左右的epoch)保留模型的权重,因而它十分有用。

  • 如果训练模型时忽然中断,则不须要齐全从新训练模型。
  • 如果,比如说,在第30个epoch,模型开始显示出过拟合的迹象或其余问题,比方梯度爆炸,咱们能够用最近保留的权重从新加载模型(比方在第25个epoch),并调整参数以防止该问题,而无需从新进行大部分训练。
  • 可能提取某个epoch的权重并将其从新加载到另一个模型中有利于迁徙学习。

在上面的场景中,ModelCheckpoint用于存储具备最佳性能的模型的权重。在每个epoch,如果模型比其余记录的epoch体现更好,则其权重存储在一个文件中(笼罩前一个的权重)。在训练完结时,咱们应用model.load_weights进行加载.

from keras.callbacks import ModelCheckpointcallback = ModelCheckpoint( #创立回调    filepath='/filepath/checkpoint', #通知回调要存储权重的filepath在哪    save_weights_only=True, #只保留权重(更无效),而不是整个模型    monitor='val_acc', #度量    mode='max', #找出使度量最大化的模型权重    save_best_only=True #只保留最佳模型的权重(更无效),而不是所有的权重)model.fit(X_train, y_train, epochs=15, callbacks=[callback])model.load_weights(checkpoint_filepath) #将最佳权重装入模型中。

或者,如果须要基于频率的保留(每5个epoch保留一次),请将save_freq设置为5

编写自定义回调是Keras蕴含的最好的个性之一,它容许执行高度特定的操作。然而,请留神,结构它比应用默认回调要简单得多。

咱们的自定义回调将采纳类的模式。相似于在PyTorch中构建神经网络,咱们能够继承keras.callbacks.Callback回调,它是一个基类。

咱们的类能够有许多函数,这些函数必须具备上面列出的给定名称以及这些函数将在何时运行。例如,将在每个epoch开始时运行on_epoch_begin函数。上面是Keras将从自定义回调中读取的所有函数,然而能够增加其余“helper”函数。

class CustomCallback(keras.callbacks.Callback): #继承keras的基类    def on_train_begin(self, logs=None):        #日志是某些度量的字典,例如键能够是 ['loss', 'mean_absolute_error']    def on_train_end(self, logs=None): ...    def on_epoch_begin(self, epoch, logs=None): ...    def on_epoch_end(self, epoch, logs=None): ...    def on_test_begin(self, logs=None): ...    def on_test_end(self, logs=None): ...    def on_predict_begin(self, logs=None): ...    def on_predict_end(self, logs=None): ...    def on_train_batch_begin(self, batch, logs=None): ...    def on_train_batch_end(self, batch, logs=None): ...    def on_test_batch_begin(self, batch, logs=None): ...    def on_test_batch_end(self, batch, logs=None): ...    def on_predict_batch_begin(self, batch, logs=None): ...    def on_predict_batch_end(self, batch, logs=None): ...

依据函数的不同,你能够拜访不同的变量。例如,在函数on_epoch_begin中,该函数既能够拜访epoch编号,也能够拜访以后度量、日志的字典。如果须要其余信息,比方学习率,能够应用keras.backend.get_value.

而后,能够像看待其余回调函数一样看待你自定义的回调函数。

model.fit(X_train, y_train, epochs=15, callbacks=[CustomCallback()])

自定义回调的一些常见想法:

  • 在JSON或CSV文件中记录训练后果。
  • 每10个epoch就通过电子邮件发送训练后果。
  • 在决定何时保留模型权重或者增加更简单的性能。
  • 训练一个简略的机器学习模型(例如应用sklearn),通过将其设置为类变量并以(x: action, y: change)的模式获取数据,来学习何时进步或升高学习率。

当在神经网络中应用回调函数时,你的控制力加强,神经网络变得更容易拟合。

原文链接:https://towardsdatascience.co...

欢送关注磐创AI博客站:
http://panchuang.net/

sklearn机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/