我添加了一个回调来降低学习率:
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)
我想确保学习率调度器在训练期间启动,所以我想将学习率输出到张量板上。但是我找不到可以设置它的地方。
我也检查了优化器 api,但没有运气。
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
如何将学习率输出到张量?
根据 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")])
请注意,使用当前每晚版本的 tf(2.5 - 可能更早(,使用 LearningRateSchedule 的学习率会自动添加到 tensorboard 的日志中。以下解决方案仅在您以其他方式调整学习率时才是必需的 - 例如通过 ReduceLROnPlateau 或 LearningRateScheduler(不同于 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
)
你给了优化器的代码两次,而不是TensorBoard Callback。无论如何,我没有找到在TensorBoard上显示学习率的方法。我在训练完成后绘制它,从历史对象中获取数据:
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 图
抱歉,这不是您要问的,但可能会有所帮助。
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曲线
对于 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")])
只需确保回调列表中的ReduceLROnPlateau
回调位于TensorBoard
回调之前即可。然后,您将看到每个纪元都记录到 TensorBoard 的lr
指标。