【问题标题】:Keras: how to output learning rate onto tensorboardKeras:如何将学习率输出到张量板上
【发布时间】:2018-08-14 02:19:59
【问题描述】:

我添加了一个回调来衰减学习率:

 keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=100, 
                                   verbose=0, mode='auto',epsilon=0.00002, cooldown=20, min_lr=0)

这是我的张量板回调:

keras.callbacks.TensorBoard(log_dir='./graph/rank{}'.format(hvd.rank()), histogram_freq=10, batch_size=FLAGS.batch_size,
                            write_graph=True, write_grads=True, write_images=False)

我想确保学习率调度程序在训练期间启动,所以我想将学习率输出到张量板上。但是我找不到可以设置的地方。

我还检查了优化器 a​​pi,但没有运气。

keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)

如何将学习率输出到 tensorboard?

【问题讨论】:

    标签: keras tensorboard


    【解决方案1】:

    According to the author of Keras正确的方式是继承TensorBoard回调:

    from keras import backend as K
    from keras.callbacks import TensorBoard
    
    class LRTensorBoard(TensorBoard):
        # add other arguments to __init__ if you need
        def __init__(self, log_dir, **kwargs):
            super().__init__(log_dir=log_dir, **kwargs)
    
        def on_epoch_end(self, epoch, logs=None):
            logs = logs or {}
            logs.update({'lr': K.eval(self.model.optimizer.lr)})
            super().on_epoch_end(epoch, logs)
    

    然后将其作为callbacks 参数的一部分传递给model.fit(信用Finncent Price):

    model.fit(x=..., y=..., callbacks=[LRTensorBoard(log_dir="/tmp/tb_log")])
    

    【讨论】:

    • 请注意,@alkamid 的答案是针对 python 3,如果您使用的是 python 2,则需要将 CHILD 类名和当前实例传递给 super。对于此特定示例 super() -> super(LRTensorBoard,self) 有效。可以在这里找到解释这种语法差异的答案:stackoverflow.com/questions/30633889/…
    • 在模型的 fit 方法中如何在 Keras 中使用此回调的说明如下。向回调变量提供回调列表,如下所示:model.fit(x=something,y=something,callbacks=[LRTensorboard(log_dir='path_to_log_dir')])
    • logs = logs or {}; logs.update(lr=K.eval(self.model.optimizer.lr)) 这样更好,因为日志,可能是 None
    • 如果你需要 super().__init__(**kwargs),我会添加 `def init__(self, **kwargs): # 添加其他参数到 __init该函数不阻止张量板的其他参数。
    • @Khan 我不确定logs=None 约定的来源,但 Keras/TensorFlow 教程似乎正在使用它。
    【解决方案2】:

    请注意,在当前夜间版本的 tf(2.5 - 可能更早)中,使用 LearningRateSchedule 的学习率会自动添加到 tensorboard 的日志中。仅当您以其他方式调整学习率时,才需要以下解决方案 - 例如通过ReduceLROnPlateauLearningRateScheduler(不同于LearningRateSchedule)回调。

    虽然扩展 tf.keras.callbacks.TensorBoard 是一个可行的选择,但我更喜欢组合而不是子类化。

    class LearningRateLogger(tf.keras.callbacks.Callback):
        def __init__(self):
            super().__init__()
            self._supports_tf_logs = True
    
        def on_epoch_end(self, epoch, logs=None):
            if logs is None or "learning_rate" in logs:
                return
            logs["learning_rate"] = self.model.optimizer.lr
    

    这允许我们组合多个类似的回调,并在多个其他回调中使用记录的学习率(例如,如果您添加 CSVLogger,它也应该将学习率值写入文件)。

    然后在model.fit

    model.fit(
        callbacks=[
            LearningRateLogger(),
            # other callbacks that update `logs`
            tf.keras.callbacks.TensorBoard(path),
            # other callbacks that use updated logs, e.g. CSVLogger
        ],
        **kwargs
    )
    

    【讨论】:

    • 也适用于 TF 2.6。
    【解决方案3】:

    您提供了两次优化器的代码,而不是 TensorBoard 回调。无论如何,我没有找到在 TensorBoard 上显示学习率的方法。 我在训练完成后绘制它,从 History 对象中获取数据:

    nb_epoch = len(history1.history['loss'])
    learning_rate=history1.history['lr']
    xc=range(nb_epoch)
    plt.figure(3,figsize=(7,5))
    plt.plot(xc,learning_rate)
    plt.xlabel('num of Epochs')
    plt.ylabel('learning rate')
    plt.title('Learning rate')
    plt.grid(True)
    plt.style.use(['seaborn-ticks'])
    

    图表如下所示: LR plot

    抱歉,这不是您要问的问题,但也许会有所帮助。

    【讨论】:

    • 抱歉错误。您的解决方案很好,但如果我想监控需要很长时间的培训过程,请不要为我工作。
    【解决方案4】:
    class XTensorBoard(TensorBoard):
        def on_epoch_begin(self, epoch, logs=None):
            # get values
            lr = float(K.get_value(self.model.optimizer.lr))
            decay = float(K.get_value(self.model.optimizer.decay))
            # computer lr
            lr = lr * (1. / (1 + decay * epoch))
            K.set_value(self.model.optimizer.lr, lr)
    
        def on_epoch_end(self, epoch, logs=None):
            logs = logs or {}
            logs['lr'] = K.get_value(self.model.optimizer.lr)
            super().on_epoch_end(epoch, logs)
    
    callbacks_list = [XTensorBoard('./logs')]
    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=32, verbose=2, callbacks=callbacks_list)
    

    lr curve in tensorboard

    【讨论】:

    • 不鼓励仅使用代码的答案。请解释一下你在做什么!
    【解决方案5】:

    对于 tensorflor 2.5,如果您有一些自定义学习率调度程序:

    class LearningRateLogger(tf.keras.callbacks.Callback):
    def __init__(self, log_dir):
        super().__init__()
        self._supports_tf_logs = True
        self.log_dir = log_dir
        
    def set_model(self, model):                                                                                                                                                                                                                                       
        self.model = model                                                                                                                                                                                                                                            
        self.sess = tf.compat.v1.keras.backend.get_session()
        self.writer = tf.summary.create_file_writer(self.log_dir)
    
    def on_epoch_end(self, epoch, logs=None):
        if logs is None or "learning_rate" in logs:
            return
        logs["learning_rate"] = self.model.optimizer.lr
        logs.update({'learning_rate': self.model.optimizer.lr})
        self._write_logs(logs, epoch)
        
    def _write_logs(self, logs, index):
    
        with self.writer.as_default():                                                                                                                                                                                                                               
            for name, value in logs.items():                                                                                                                                                                                                                              
                if name in ['batch', 'size']:                                                                                                                                                                                                                             
                    continue                                                                                                                                                                                                                    
                if isinstance(value, np.ndarray):
                    tf.summary.scalar(name, value.item(), step=index)                                                                                                                                                                                                             
                else:
                    tf.summary.scalar(name, value, step=index)
        
            self.writer.flush()
    

    然后在你的 model.fit 中调用回调:

    model.fit(x=..., y=..., callbacks=[LearningRateLogger(log_dir="/path/to/folder/where/tensorboard/is/logging")])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-11
      • 2018-10-19
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2018-03-17
      • 2019-05-05
      相关资源
      最近更新 更多