关于人工智能:神经网络训练中回调函数的实用教程

40次阅读

共计 4356 个字符,预计需要花费 11 分钟才能阅读完成。

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

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

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

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


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

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

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

  • monitor,它用来监督指标
  • factor,它是新的学习率将被升高(乘以)的因子
  • persistence,回调激活之前期待的停滞 epoch 数
  • min_lr,它能够升高到的最小学习率。这能够避免不必要和不无益的缩小。
from keras.callbacks import ReduceLROnPlateau
reduce_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 LearningRateScheduler

def 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 TerminateOnNaN
model.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 ModelCheckpoint

callback = 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/

正文完
 0