Tensorflow 回调快速入门

2021-10-27 16:04:26 浏览数 (1)


磐创AI分享

作者 | ashish0765

编译 | Flin

来源 | analyticsvidhya

什么是 Tensorflow 回调?

Tensorflow 回调是在训练深度学习模型时在特定时刻执行的函数或代码块。

我们都熟悉深度学习模型的训练过程。随着模型变得越来越复杂,训练时间也显着增加。因此,模型通常需要花费数小时来训练。

在训练模型之前的工作中,我们修复了所有选项和参数,例如学习率、优化器、损失等并开始模型训练。一旦训练过程开始,就无法暂停训练,以防我们想要更改一些参数。

此外,在某些情况下,当模型已经训练了几个小时,而我们想在后期调整一些参数时,这是不可能的。而这就是 TensorFlow 回调派上用场的地方。

如何使用回调

  1. 首先定义回调
  2. 在调用 model.fit() 时传递回调
代码语言:javascript复制
# Stop training if NaN is encountered
NanStop = TerminateOnNaN()
# Decrease lr by 10% 
LrValAccuracy = ReduceLROnPlateau(monitor='val_accuracy', patience=1, factor= 0.9, mode='max', verbose=0)
代码语言:javascript复制
model.fit(X_train,y_train,
epochs=10,
validation_data=(X_test,y_test),
callbacks = [NanStop, LrValAccuracy])

让我们来看看一些最有用的回调

提前停止

当我们训练模型时,我们通常会查看指标以监控模型的表现。通常,如果我们看到极高的指标,我们可以得出结论,我们的模型过度拟合,如果我们的指标很低,那么我们就欠拟合了。

如果指标增加到某个范围以上,我们可以停止训练以防止过度拟合。EarlyStopping 回调允许我们做到这一点。

代码语言:javascript复制
early_stop_cb = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', min_delta=0, patience=0, verbose=0,
    mode='auto'
)
  • monitor:你在训练时要监视的指标
  • min_delta:你要考虑作为对前一个时期的改进的指标的最小变化量
  • patience:你等待指标等待的时期数。否则,你将停止训练。
  • verbose:0:不打印任何内容,1:显示进度条,2:仅打印时期号
  • mode :
  • “auto” – 尝试从给定的指标中自动检测行为
  • “min” – 如果指标停止下降,则停止训练
  • “max” – 如果指标停止增加则停止训练

Lambda回调

此回调用于在训练过程中的特定时间调用某些 lambda 函数。

代码语言:javascript复制
tf.keras.callbacks.LambdaCallback(
    on_epoch_begin=None, on_epoch_end=None, on_batch_begin=None, on_batch_end=None,
    on_train_begin=None, on_train_end=None, **kwargs
)

在这里,我们可以传递我们需要在指定时间执行的任何 lambda 函数。

让我们看看参数是什么意思

  • on_epoch_begin:在每个时期开始时调用该函数。
  • on_epoch_begin:在每个时期结束时调用该函数。
  • on_batch_begin:在每批开始时调用该函数。
  • on_batch_end:在每批结束时调用该函数。
  • on_train_begin:模型开始训练时调用该函数
  • on_train_end:模型训练完成时调用
代码语言:javascript复制
print_batch_callback = LambdaCallback(
    on_batch_begin=lambda bat,log: print(bat),
    on_batch_begin=lambda bat,log: print(bat)
)

学习率调度器

训练过程中最常见的任务之一是改变学习率。通常,随着模型接近损失最小值(最佳拟合),我们逐渐开始降低学习率以获得更好的收敛性。

让我们看一个简单的例子,我们希望每 3 个 epoch 将学习率降低 5%。这里我们需要向 schedule 函数传递一个参数,该参数指定学习率变化的逻辑。

代码语言:javascript复制
def schedule(epoch,lr):
  if epoch % 3 == 0:
    lr = lr - (lr*.05)
    return lr
  return lr

# Decrease lr by 5% for every 3rd epoch
LrScheduler = tf.keras.callbacks.LearningRateScheduler(schedule,verbose=1)
模型检查点

我们使用这个回调来以不同的频率保存我们的模型。这允许我们在中间步骤保存权重,以便在需要时我们可以稍后加载权重。

代码语言:javascript复制
tf.keras.callbacks.ModelCheckpoint(
    filepath, monitor='val_loss', verbose=0, save_best_only=False,
    save_weights_only=False, mode='auto', save_freq='epoch'
)

filepath:模型所在的位置 monitor:要监视的度量 save_best_only:True:仅保存最好的模型,False:保存所有的模型时,指标改善 mode:min, max或auto save_weights_only:False:仅保存模型权重, True:同时保存模型权重和模型架构

例如,让我们看一个例子,保存具有最佳精度的模型

代码语言:javascript复制
filePath = "models/Model1_weights.{epoch:02d}.hdf5"
model_checkpoint_callback = tf.keras.callbacksModelCheckpoint(
    filepath=filePath,
    save_weights_only=True,
    monitor='val_accuracy',
    mode='max')

这里我们使用一些模板字符串指定文件路径。{epoch:02d} 保存模型时由时期号代替

减少LROnPlateau

当特定指标停止增加并达到平台期时,此回调用于降低训练率。

代码语言:javascript复制
tf.keras.callbacks.ReduceLROnPlateau(
    monitor='val_loss', factor=0.1, patience=10, verbose=0,
    mode='auto', min_delta=0.0001, cooldown=0, min_lr=0, **kwargs
)

factor:LR 减少的系数。新学习率 = old_learning_rate * 因子 min_delta:需要被视为改进的最小变化 cooldown:等待 LR 减少的时期数 min_lr:学习率不能低于该最小值

终止OnNaN

当任何损失变为 NaN 时,此回调将停止训练过程

代码语言:javascript复制
tf.keras.callbacks.TerminateOnNaN()

Tensorboard

Tensorboard 允许我们显示有关训练过程的信息,如指标、训练图、激活函数直方图和其他梯度分布。

要使用Tensorboard,我们首先需要设置一个 log_dir,Tensorboard文件被保存到其中。

代码语言:javascript复制
log_dir="logs"
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1, write_graph=True)
  • log_dir:保存文件的目录
  • histogram_freq:计算直方图和梯度图的时期频率
  • write_graph:我们是否需要在Tensorboard中显示和可视化图形

编写自己的回调

除了内置的回调之外,我们还可以为不同的目的定义和使用我们自己的回调。例如,假设我们要定义自己的度量标准,该度量标准在每个 epoch 结束时计算。

代码语言:javascript复制
# Monitor MicroF1 and AUC Score
class Metrics_Callback(tf.keras.callbacks.Callback):
  def __init__(self,x_val,y_val):
    self.x_val = x_val
    self.y_val = y_val
  def on_train_begin(self, logs={}):
    self.history = {"auc_score":[],"micro_f1":[]}
  def on_epoch_end(self, epoch, logs={}):
    auc_score = roc_auc_score(self.y_val, model.predict_proba(self.x_val))
    y_true = [0 if x[0]==1.0 else 1 for x in self.y_val]
    f1_s = f1_score(y_true,self.model.predict_classes(self.x_val), average='micro')
    self.history["auc_score"].append(auc_score)
    self.history["micro_f1"].append(f1_s)
代码语言:javascript复制
Metrics = Metrics_Callback(X_test,y_test)

这里我们要计算每个 epoch 结束时的 F1 分数和 AUC 分数。在 init 方法中,我们读取计算分数所需的数据。然后在每个 epoch 结束时,我们在 on_epoch_end 函数中计算指标。

我们可以使用以下方法在不同的时间执行代码——

on_epoch_begin:在每个时期开始时调用。

on_epoch_begin:在每个时期结束时调用。

on_batch_begin:在每批开始时调用。

on_batch_end:在每批结束时调用。

on_train_begin:模型开始训练时调用

on_train_end:模型训练完成时调用

结论

这些是一些常用和最流行的回调。TensorFlow 官方文档为我们提供了有关各种其他回调及其相关用例的详细信息。

TensorFlow 官方文档:https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/Callback

0 人点赞