作者: Rick Chao, Francois Chollet
创建日期: 2019/03/20
最后修改: 2023/06/25
描述: 编写新Keras回调函数的完整指南。
回调(callback)是一个强大的工具,可以在 Keras 模型训练、评估或推理期间自定义模型的行为。例如,keras.callbacks.TensorBoard
用于通过 TensorBoard 可视化训练进度和结果,或 keras.callbacks.ModelCheckpoint
用于在训练期间定期保存模型。
在本指南中,您将了解什么是 Keras 回调,它可以做什么,以及如何构建自己的回调。我们提供了一些简单的回调应用演示,以帮助您入门。
import numpy as np
import keras
所有回调都继承自 keras.callbacks.Callback
类,并重写一组在训练、测试和预测的不同阶段调用的方法。回调在训练期间获取模型的内部状态和统计数据非常有用。
您可以将回调列表(作为关键字参数 callbacks
)传递给以下模型方法:
keras.Model.fit()
keras.Model.evaluate()
keras.Model.predict()
on_(train|test|predict)_begin(self, logs=None)
在 fit
/evaluate
/predict
开始时调用。
on_(train|test|predict)_end(self, logs=None)
在 fit
/evaluate
/predict
结束时调用。
on_(train|test|predict)_batch_begin(self, batch, logs=None)
在训练/测试/预测期间处理批次之前调用。
on_(train|test|predict)_batch_end(self, batch, logs=None)
在训练/测试/预测批次结束时调用。在这个方法中,logs
是一个包含指标结果的字典。
on_epoch_begin(self, epoch, logs=None)
在训练期间一个周期开始时调用。
on_epoch_end(self, epoch, logs=None)
在训练期间一个周期结束时调用。
让我们看一个具体的例子。首先,让我们导入 tensorflow 并定义一个简单的 Sequential Keras 模型:
# 定义一个Keras模型以添加回调函数
def get_model():
model = keras.Sequential()
model.add(keras.layers.Dense(1))
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=0.1),
loss="mean_squared_error",
metrics=["mean_absolute_error"],
)
return model
然后,从Keras数据集API加载用于训练和测试的MNIST数据:
# 加载示例MNIST数据并进行预处理
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(-1, 784).astype("float32") / 255.0
x_test = x_test.reshape(-1, 784).astype("float32") / 255.0
# 将数据限制为1000个样本
x_train = x_train[:1000]
y_train = y_train[:1000]
x_test = x_test[:1000]
y_test = y_test[:1000]
现在,定义一个简单的自定义回调,记录以下内容:
fit
/evaluate
/predict
开始和结束时class CustomCallback(keras.callbacks.Callback):
def on_train_begin(self, logs=None):
keys = list(logs.keys())
print("Starting training; got log keys: {}".format(keys))
def on_train_end(self, logs=None):
keys = list(logs.keys())
print("Stop training; got log keys: {}".format(keys))
def on_epoch_begin(self, epoch, logs=None):
keys = list(logs.keys())
print("Start epoch {} of training; got log keys: {}".format(epoch, keys))
def on_epoch_end(self, epoch, logs=None):
keys = list(logs.keys())
print("End epoch {} of training; got log keys: {}".format(epoch, keys))
def on_test_begin(self, logs=None):
keys = list(logs.keys())
print("Start testing; got log keys: {}".format(keys))
def on_test_end(self, logs=None):
keys = list(logs.keys())
print("Stop testing; got log keys: {}".format(keys))
def on_predict_begin(self, logs=None):
keys = list(logs.keys())
print("Start predicting; got log keys: {}".format(keys))
def on_predict_end(self, logs=None):
keys = list(logs.keys())
print("Stop predicting; got log keys: {}".format(keys))
def on_train_batch_begin(self, batch, logs=None):
keys = list(logs.keys())
print("...Training: start of batch {}; got log keys: {}".format(batch, keys))
def on_train_batch_end(self, batch, logs=None):
keys = list(logs.keys())
print("...Training: end of batch {}; got log keys: {}".format(batch, keys))
def on_test_batch_begin(self, batch, logs=None):
keys = list(logs.keys())
print("...Evaluating: start of batch {}; got log keys: {}".format(batch, keys))
def on_test_batch_end(self, batch, logs=None):
keys = list(logs.keys())
print("...Evaluating: end of batch {}; got log keys: {}".format(batch, keys))
def on_predict_batch_begin(self, batch, logs=None):
keys = list(logs.keys())
print("...Predicting: start of batch {}; got log keys: {}".format(batch, keys))
def on_predict_batch_end(self, batch, logs=None):
keys = list(logs.keys())
print("...Predicting: end of batch {}; got log keys: {}".format(batch, keys))
让我们试试看:
model = get_model()
model.fit(
x_train,
y_train,
batch_size=128,
epochs=1,
verbose=0,
validation_split=0.5,
callbacks=[CustomCallback()],
)
res = model.evaluate(
x_test, y_test, batch_size=128, verbose=0, callbacks=[CustomCallback()]
)
res = model.predict(x_test, batch_size=128, callbacks=[CustomCallback()])
开始训练;获取日志键:[]
开始第0个训练周期;获取日志键:[]
...训练:第0批开始;获取日志键:[]
...训练:第0批结束;获取日志键:['损失', '平均绝对误差']
...训练:第1批开始;获取日志键:[]
...训练:第1批结束;获取日志键:['损失', '平均绝对误差']
...训练:第2批开始;获取日志键:[]
...训练:第2批结束;获取日志键:['损失', '平均绝对误差']
...训练:第3批开始;获取日志键:[]
...训练:第3批结束;获取日志键:['损失', '平均绝对误差']
开始测试;获取日志键:[]
...评估:第0批开始;获取日志键:[]
...评估:第0批结束;获取日志键:['损失', '平均绝对误差']
...评估:第1批开始;获取日志键:[]
...评估:第1批结束;获取日志键:['损失', '平均绝对误差']
...评估:第2批开始;获取日志键:[]
...评估:第2批结束;获取日志键:['损失', '平均绝对误差']
...评估:第3批开始;获取日志键:[]
...评估:第3批结束;获取日志键:['损失', '平均绝对误差']
停止测试;获取日志键:['损失', '平均绝对误差']
结束第0个训练周期;获取日志键:['损失', '平均绝对误差', '验证损失', '验证平均绝对误差']
停止训练;获取日志键:['损失', '平均绝对误差', '验证损失', '验证平均绝对误差']
开始测试;获取日志键:[]
...评估:第0批开始;获取日志键:[]
...评估:第0批结束;获取日志键:['损失', '平均绝对误差']
...评估:第1批开始;获取日志键:[]
...评估:第1批结束;获取日志键:['损失', '平均绝对误差']
...评估:第2批开始;获取日志键:[]
...评估:第2批结束;获取日志键:['损失', '平均绝对误差']
...评估:第3批开始;获取日志键:[]
...评估:第3批结束;获取日志键:['损失', '平均绝对误差']
...评估:第4批开始;获取日志键:[]
...评估:第4批结束;获取日志键:['损失', '平均绝对误差']
...评估:第5批开始;获取日志键:[]
...评估:第5批结束;获取日志键:['损失', '平均绝对误差']
...评估:第6批开始;获取日志键:[]
...评估:第6批结束;获取日志键:['损失', '平均绝对误差']
...评估:第7批开始;获取日志键:[]
...评估:第7批结束;获取日志键:['损失', '平均绝对误差']
停止测试;获取日志键:['损失', '平均绝对误差']
开始预测;获取日志键:[]
...预测:第0批开始;获取日志键:[]
...预测:第0批结束;获取日志键:['输出']
1/8 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/步...预测:第1批开始;获取日志键:[]
...预测:第1批结束;获取日志键:['输出']
...预测:第2批开始;获取日志键:[]
...预测:第2批结束;获取日志键:['输出']
...预测:第3批开始;获取日志键:[]
...预测:第3批结束;获取日志键:['输出']
...预测:第4批开始;获取日志键:[]
...预测:第4批结束;获取日志键:['输出']
...预测:第5批开始;获取日志键:[]
...预测:第5批结束;获取日志键:['输出']
...预测:第6批开始;获取日志键:[]
...预测:第6批结束;获取日志键:['输出']
...预测:第7批开始;获取日志键:[]
...预测:第7批结束;获取日志键:['输出']
停止预测;获取日志键:[]
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/步
logs
dict 的使用logs
dict 包含损失值以及在批次或 epoch 结束时的所有指标。示例包括损失和平均绝对误差。
class LossAndErrorPrintingCallback(keras.callbacks.Callback):
def on_train_batch_end(self, batch, logs=None):
print(
"到批次 {},平均损失为 {:7.2f}。".format(batch, logs["loss"])
)
def on_test_batch_end(self, batch, logs=None):
print(
"到批次 {},平均损失为 {:7.2f}。".format(batch, logs["loss"])
)
def on_epoch_end(self, epoch, logs=None):
print(
"第 {} 个 epoch 的平均损失为 {:7.2f} "
"并且平均绝对误差为 {:7.2f}。".format(
epoch, logs["loss"], logs["mean_absolute_error"]
)
)
model = get_model()
model.fit(
x_train,
y_train,
batch_size=128,
epochs=2,
verbose=0,
callbacks=[LossAndErrorPrintingCallback()],
)
res = model.evaluate(
x_test,
y_test,
batch_size=128,
verbose=0,
callbacks=[LossAndErrorPrintingCallback()],
)
到批次 0,平均损失为 29.25。
到批次 1,平均损失为 485.36。
到批次 2,平均损失为 330.94。
到批次 3,平均损失为 250.62。
到批次 4,平均损失为 202.20。
到批次 5,平均损失为 169.51。
到批次 6,平均损失为 145.98。
到批次 7,平均损失为 128.48。
第 0 个 epoch 的平均损失为 128.48 并且平均绝对误差为 6.01。
到批次 0,平均损失为 5.10。
到批次 1,平均损失为 4.80。
到批次 2,平均损失为 4.96。
到批次 3,平均损失为 4.96。
到批次 4,平均损失为 4.82。
到批次 5,平均损失为 4.69。
到批次 6,平均损失为 4.51。
到批次 7,平均损失为 4.53。
第 1 个 epoch 的平均损失为 4.53 并且平均绝对误差为 1.72。
到批次 0,平均损失为 5.08。
到批次 1,平均损失为 4.66。
到批次 2,平均损失为 4.64。
到批次 3,平均损失为 4.72。
到批次 4,平均损失为 4.82。
到批次 5,平均损失为 4.83。
到批次 6,平均损失为 4.77。
到批次 7,平均损失为 4.72。
self.model
属性的使用除了在调用其方法时接收日志信息外,回调还可以访问与当前训练/评估/推理轮次相关的模型:self.model
。
以下是您可以在回调中使用 self.model
做的一些事情:
self.model.stop_training = True
以立即中断训练。self.model.optimizer
),例如 self.model.optimizer.learning_rate
。model.predict()
在一些测试样本上的输出,以在训练期间作为合理性检查。让我们通过几个例子来看看这是如何实现的。
这个第一个示例展示了创建一个Callback
,当损失达到最小值时停止训练,通过设置属性self.model.stop_training
(布尔值)。可选地,你可以提供一个参数patience
,以指定在达到局部最小值后应等待多少个epoch再停止。
keras.callbacks.EarlyStopping
提供了一个更完整和通用的实现。
class EarlyStoppingAtMinLoss(keras.callbacks.Callback):
"""当损失达到最小值时停止训练,即损失不再减少。
参数:
patience: 在达到最小值后等待的epoch数。在此之后没有改进,训练停止。
"""
def __init__(self, patience=0):
super().__init__()
self.patience = patience
# best_weights用于存储在最小损失时的权重。
self.best_weights = None
def on_train_begin(self, logs=None):
# 当损失不再是最小值时等待的epoch数。
self.wait = 0
# 训练停止时的epoch。
self.stopped_epoch = 0
# 初始化最佳值为无穷大。
self.best = np.inf
def on_epoch_end(self, epoch, logs=None):
current = logs.get("loss")
if np.less(current, self.best):
self.best = current
self.wait = 0
# 如果当前结果更好(更小),记录最佳权重。
self.best_weights = self.model.get_weights()
else:
self.wait += 1
if self.wait >= self.patience:
self.stopped_epoch = epoch
self.model.stop_training = True
print("从最佳epoch结束时恢复模型权重。")
self.model.set_weights(self.best_weights)
def on_train_end(self, logs=None):
if self.stopped_epoch > 0:
print(f"Epoch {self.stopped_epoch + 1}: 提前停止")
model = get_model()
model.fit(
x_train,
y_train,
batch_size=64,
epochs=30,
verbose=0,
callbacks=[LossAndErrorPrintingCallback(), EarlyStoppingAtMinLoss()],
)
Up to batch 0, the average loss is 25.57.
Up to batch 1, the average loss is 471.66.
Up to batch 2, the average loss is 322.55.
Up to batch 3, the average loss is 243.88.
Up to batch 4, the average loss is 196.53.
Up to batch 5, the average loss is 165.02.
Up to batch 6, the average loss is 142.34.
Up to batch 7, the average loss is 125.17.
Up to batch 8, the average loss is 111.83.
Up to batch 9, the average loss is 101.35.
Up to batch 10, the average loss is 92.60.
Up to batch 11, the average loss is 85.16.
Up to batch 12, the average loss is 79.02.
Up to batch 13, the average loss is 73.71.
Up to batch 14, the average loss is 69.23.
Up to batch 15, the average loss is 65.26.
The average loss for epoch 0 is 65.26 and mean absolute error is 3.89.
Up to batch 0, the average loss is 3.92.
Up to batch 1, the average loss is 4.34.
Up to batch 2, the average loss is 5.39.
Up to batch 3, the average loss is 6.58.
Up to batch 4, the average loss is 10.55.
Up to batch 5, the average loss is 19.29.
Up to batch 6, the average loss is 31.58.
Up to batch 7, the average loss is 38.20.
Up to batch 8, the average loss is 41.96.
Up to batch 9, the average loss is 41.30.
Up to batch 10, the average loss is 39.31.
Up to batch 11, the average loss is 37.09.
Up to batch 12, the average loss is 35.08.
Up to batch 13, the average loss is 33.27.
Up to batch 14, the average loss is 31.54.
Up to batch 15, the average loss is 30.00.
The average loss for epoch 1 is 30.00 and mean absolute error is 4.23.
Up to batch 0, the average loss is 5.70.
Up to batch 1, the average loss is 6.90.
Up to batch 2, the average loss is 7.74.
Up to batch 3, the average loss is 8.85.
Up to batch 4, the average loss is 12.53.
Up to batch 5, the average loss is 21.55.
Up to batch 6, the average loss is 35.70.
Up to batch 7, the average loss is 44.16.
Up to batch 8, the average loss is 44.82.
Up to batch 9, the average loss is 43.07.
Up to batch 10, the average loss is 40.51.
Up to batch 11, the average loss is 38.44.
Up to batch 12, the average loss is 36.69.
Up to batch 13, the average loss is 34.77.
Up to batch 14, the average loss is 32.97.
Up to batch 15, the average loss is 31.32.
The average loss for epoch 2 is 31.32 and mean absolute error is 4.39.
Restoring model weights from the end of the best epoch.
Epoch 3: early stopping
<keras.src.callbacks.history.History at 0x1187b7430>
在这个例子中,我们展示了如何使用自定义回调在训练过程中动态改变优化器的学习率。
请参阅 callbacks.LearningRateScheduler
以获取更通用的实现。
class CustomLearningRateScheduler(keras.callbacks.Callback):
"""学习率调度器,根据调度设置学习率。
参数:
schedule: 一个函数,输入为epoch索引(整数,从0开始)和当前学习率
作为输入,输出为新的学习率(浮点数)。
"""
def __init__(self, schedule):
super().__init__()
self.schedule = schedule
def on_epoch_begin(self, epoch, logs=None):
if not hasattr(self.model.optimizer, "learning_rate"):
raise ValueError('Optimizer must have a "learning_rate" attribute.')
# 从模型的优化器中获取当前学习率。
lr = self.model.optimizer.learning_rate
# 调用schedule函数以获取调度的学习率。
scheduled_lr = self.schedule(epoch, lr)
# 在当前epoch开始前将值设置回优化器
self.model.optimizer.learning_rate = scheduled_lr
print(f"\nEpoch {epoch}: Learning rate is {float(np.array(scheduled_lr))}.")
LR_SCHEDULE = [
# (开始epoch, 学习率) 元组
(3, 0.05),
(6, 0.01),
(9, 0.005),
(12, 0.001),
]
def lr_schedule(epoch, lr):
"""辅助函数,根据epoch获取调度的学习率。"""
if epoch < LR_SCHEDULE[0][0] or epoch > LR_SCHEDULE[-1][0]:
return lr
for i in range(len(LR_SCHEDULE)):
if epoch == LR_SCHEDULE[i][0]:
return LR_SCHEDULE[i][1]
return lr
model = get_model()
model.fit(
x_train,
y_train,
batch_size=64,
epochs=15,
verbose=0,
callbacks=[
LossAndErrorPrintingCallback(),
CustomLearningRateScheduler(lr_schedule),
],
)
Epoch 0: Learning rate is 0.10000000149011612.
Up to batch 0, the average loss is 27.90.
Up to batch 1, the average loss is 439.49.
Up to batch 2, the average loss is 302.08.
Up to batch 3, the average loss is 228.83.
Up to batch 4, the average loss is 184.97.
Up to batch 5, the average loss is 155.25.
Up to batch 6, the average loss is 134.03.
Up to batch 7, the average loss is 118.29.
Up to batch 8, the average loss is 105.65.
Up to batch 9, the average loss is 95.53.
Up to batch 10, the average loss is 87.25.
Up to batch 11, the average loss is 80.33.
Up to batch 12, the average loss is 74.48.
Up to batch 13, the average loss is 69.46.
Up to batch 14, the average loss is 65.05.
Up to batch 15, the average loss is 61.31.
The average loss for epoch 0 is 61.31 and mean absolute error is 3.85.
Epoch 1: 学习率是 0.10000000149011612.
到批次 0 为止,平均损失是 57.96.
到批次 1 为止,平均损失是 55.11.
到批次 2 为止,平均损失是 52.81.
到批次 3 为止,平均损失是 51.06.
到批次 4 为止,平均损失是 50.58.
到批次 5 为止,平均损失是 51.49.
到批次 6 为止,平均损失是 53.24.
到批次 7 为止,平均损失是 54.20.
到批次 8 为止,平均损失是 54.39.
到批次 9 为止,平均损失是 54.31.
到批次 10 为止,平均损失是 53.83.
到批次 11 为止,平均损失是 52.93.
到批次 12 为止,平均损失是 51.73.
到批次 13 为止,平均损失是 50.34.
到批次 14 为止,平均损失是 48.94.
到批次 15 为止,平均损失是 47.65.
第 1 个 epoch 的平均损失是 47.65 并且平均绝对误差是 4.30.
Epoch 2: 学习率是 0.10000000149011612。
到批次 0,平均损失是 46.38。
到批次 1,平均损失是 45.16。
到批次 2,平均损失是 44.03。
到批次 3,平均损失是 43.11。
到批次 4,平均损失是 42.52。
到批次 5,平均损失是 42.32。
到批次 6,平均损失是 43.06。
到批次 7,平均损失是 44.58。
到批次 8,平均损失是 45.33。
到批次 9,平均损失是 45.15。
到批次 10,平均损失是 44.59。
到批次 11,平均损失是 43.88。
到批次 12,平均损失是 43.17。
到批次 13,平均损失是 42.40。
到批次 14,平均损失是 41.74。
到批次 15,平均损失是 41.19。
第 2 轮的平均损失是 41.19,平均绝对误差是 4.27。
Epoch 3: 学习率是 0.05。
到批次 0,平均损失是 40.85。
到批次 1,平均损失是 40.11。
到批次 2,平均损失是 39.38。
到批次 3,平均损失是 38.69。
到批次 4,平均损失是 38.01。
到批次 5,平均损失是 37.38。
到批次 6,平均损失是 36.77。
到批次 7,平均损失是 36.18。
到批次 8,平均损失是 35.61。
到批次 9,平均损失是 35.08。
到批次 10,平均损失是 34.54。
到批次 11,平均损失是 34.04。
到批次 12,平均损失是 33.56。
到批次 13,平均损失是 33.08。
到批次 14,平均损失是 32.64。
到批次 15,平均损失是 32.25。
第 3 轮的平均损失是 32.25,平均绝对误差是 3.64。
Epoch 4: 学习率是 0.05000000074505806。
到批次 0,平均损失是 31.83。
到批次 1,平均损失是 31.42。
到批次 2,平均损失是 31.05。
到批次 3,平均损失是 30.72。
到批次 4,平均损失是 30.49。
到批次 5,平均损失是 30.37。
到批次 6,平均损失是 30.15。
到批次 7,平均损失是 29.94。
到批次 8,平均损失是 29.75。
到批次 9,平均损失是 29.56。
到批次 10,平均损失是 29.27。
到批次 11,平均损失是 28.96。
到批次 12,平均损失是 28.67。
到批次 13,平均损失是 28.39。
到批次 14,平均损失是 28.11。
到批次 15,平均损失是 27.80。
第 4 轮的平均损失是 27.80,平均绝对误差是 3.43。
Epoch 5: 学习率是 0.05000000074505806。
到批次 0,平均损失是 27.51。
到批次 1,平均损失是 27.25。
到批次 2,平均损失是 27.05。
到批次 3,平均损失是 26.88。
到批次 4,平均损失是 26.76。
到批次 5,平均损失是 26.60。
到批次 6,平均损失是 26.44。
到批次 7,平均损失是 26.25。
到批次 8,平均损失是 26.08。
到批次 9,平均损失是 25.89。
到批次 10,平均损失是 25.71。
到批次 11,平均损失是 25.48。
到批次 12,平均损失是 25.26。
到批次 13,平均损失是 25.03。
到批次 14,平均损失是 24.81。
到批次 15,平均损失是 24.58。
第 5 轮的平均损失是 24.58,平均绝对误差是 3.25。
Epoch 6: 学习率是 0.01.
到批次 0,平均损失是 24.36.
到批次 1,平均损失是 24.14.
到批次 2,平均损失是 23.93.
到批次 3,平均损失是 23.71.
到批次 4,平均损失是 23.52.
到批次 5,平均损失是 23.32.
到批次 6,平均损失是 23.12.
到批次 7,平均损失是 22.93.
到批次 8,平均损失是 22.74.
到批次 9,平均损失是 22.55.
到批次 10,平均损失是 22.37.
到批次 11,平均损失是 22.19.
到批次 12,平均损失是 22.01.
到批次 13,平均损失是 21.83.
到批次 14,平均损失是 21.67.
到批次 15,平均损失是 21.50.
第 6 轮的平均损失是 21.50 并且平均绝对误差是 2.98.
Epoch 7: 学习率是 0.009999999776482582.
到批次 0,平均损失是 21.33.
到批次 1,平均损失是 21.17.
到批次 2,平均损失是 21.01.
到批次 3,平均损失是 20.85.
到批次 4,平均损失是 20.71.
到批次 5,平均损失是 20.57.
到批次 6,平均损失是 20.41.
到批次 7,平均损失是 20.27.
到批次 8,平均损失是 20.13.
到批次 9,平均损失是 19.98.
到批次 10,平均损失是 19.83.
到批次 11,平均损失是 19.69.
到批次 12,平均损失是 19.57.
到批次 13,平均损失是 19.44.
到批次 14,平均损失是 19.32.
到批次 15,平均损失是 19.19.
第 7 轮的平均损失是 19.19 并且平均绝对误差是 2.77.
Epoch 8: 学习率是 0.009999999776482582.
到批次 0,平均损失是 19.07.
到批次 1,平均损失是 18.95.
到批次 2,平均损失是 18.83.
到批次 3,平均损失是 18.70.
到批次 4,平均损失是 18.58.
到批次 5,平均损失是 18.46.
到批次 6,平均损失是 18.35.
到批次 7,平均损失是 18.24.
到批次 8,平均损失是 18.12.
到批次 9,平均损失是 18.01.
到批次 10,平均损失是 17.90.
到批次 11,平均损失是 17.79.
到批次 12,平均损失是 17.68.
到批次 13,平均损失是 17.58.
到批次 14,平均损失是 17.48.
到批次 15,平均损失是 17.38.
第 8 轮的平均损失是 17.38 并且平均绝对误差是 2.61.
Epoch 9: 学习率是 0.005。
到批次 0,平均损失是 17.28。
到批次 1,平均损失是 17.18。
到批次 2,平均损失是 17.08。
到批次 3,平均损失是 16.99。
到批次 4,平均损失是 16.90。
到批次 5,平均损失是 16.80。
到批次 6,平均损失是 16.71。
到批次 7,平均损失是 16.62。
到批次 8,平均损失是 16.53。
到批次 9,平均损失是 16.44。
到批次 10,平均损失是 16.35。
到批次 11,平均损失是 16.26。
到批次 12,平均损失是 16.17。
到批次 13,平均损失是 16.09。
到批次 14,平均损失是 16.00。
到批次 15,平均损失是 15.92。
第 9 轮的平均损失是 15.92 并且平均绝对误差是 2.48。
Epoch 10: 学习率是 0.004999999888241291.
到批次 0, 平均损失是 15.84.
到批次 1, 平均损失是 15.76.
到批次 2, 平均损失是 15.68.
到批次 3, 平均损失是 15.61.
到批次 4, 平均损失是 15.53.
到批次 5, 平均损失是 15.45.
到批次 6, 平均损失是 15.37.
到批次 7, 平均损失是 15.29.
到批次 8, 平均损失是 15.23.
到批次 9, 平均损失是 15.15.
到批次 10, 平均损失是 15.08.
到批次 11, 平均损失是 15.00.
到批次 12, 平均损失是 14.93.
到批次 13, 平均损失是 14.86.
到批次 14, 平均损失是 14.79.
到批次 15, 平均损失是 14.72.
第 10 轮的平均损失是 14.72 和平均绝对误差是 2.37.
Epoch 11: 学习率是 0.004999999888241291.
到批次 0, 平均损失是 14.65.
到批次 1, 平均损失是 14.58.
到批次 2, 平均损失是 14.52.
到批次 3, 平均损失是 14.45.
到批次 4, 平均损失是 14.39.
到批次 5, 平均损失是 14.33.
到批次 6, 平均损失是 14.26.
到批次 7, 平均损失是 14.20.
到批次 8, 平均损失是 14.14.
到批次 9, 平均损失是 14.08.
到批次 10, 平均损失是 14.02.
到批次 11, 平均损失是 13.96.
到批次 12, 平均损失是 13.90.
到批次 13, 平均损失是 13.84.
到批次 14, 平均损失是 13.78.
到批次 15, 平均损失是 13.72.
第 11 轮的平均损失是 13.72 和平均绝对误差是 2.27.
Epoch 12: 学习率是 0.001.
到批次 0, 平均损失是 13.67.
到批次 1, 平均损失是 13.60.
到批次 2, 平均损失是 13.55.
到批次 3, 平均损失是 13.49.
到批次 4, 平均损失是 13.44.
到批次 5, 平均损失是 13.38.
到批次 6, 平均损失是 13.33.
到批次 7, 平均损失是 13.28.
到批次 8, 平均损失是 13.22.
到批次 9, 平均损失是 13.17.
到批次 10, 平均损失是 13.12.
到批次 11, 平均损失是 13.07.
到批次 12, 平均损失是 13.02.
到批次 13, 平均损失是 12.97.
到批次 14, 平均损失是 12.92.
到批次 15, 平均损失是 12.87.
第 12 轮的平均损失是 12.87 和平均绝对误差是 2.19.
Epoch 13: 学习率是 0.0010000000474974513.
到批次 0 为止,平均损失是 12.82.
到批次 1 为止,平均损失是 12.77.
到批次 2 为止,平均损失是 12.72.
到批次 3 为止,平均损失是 12.68.
到批次 4 为止,平均损失是 12.63.
到批次 5 为止,平均损失是 12.58.
到批次 6 为止,平均损失是 12.53.
到批次 7 为止,平均损失是 12.49.
到批次 8 为止,平均损失是 12.45.
到批次 9 为止,平均损失是 12.40.
到批次 10 为止,平均损失是 12.35.
到批次 11 为止,平均损失是 12.30.
到批次 12 为止,平均损失是 12.26.
到批次 13 为止,平均损失是 12.22.
到批次 14 为止,平均损失是 12.17.
到批次 15 为止,平均损失是 12.13.
第 13 轮的平均损失是 12.13 并且平均绝对误差是 2.12.
Epoch 14: 学习率是 0.0010000000474974513。
到批次 0,平均损失是 12.09。
到批次 1,平均损失是 12.05。
到批次 2,平均损失是 12.01。
到批次 3,平均损失是 11.97。
到批次 4,平均损失是 11.92。
到批次 5,平均损失是 11.88。
到批次 6,平均损失是 11.84。
到批次 7,平均损失是 11.80。
到批次 8,平均损失是 11.76。
到批次 9,平均损失是 11.72。
到批次 10,平均损失是 11.68。
到批次 11,平均损失是 11.64。
到批次 12,平均损失是 11.60。
到批次 13,平均损失是 11.57。
到批次 14,平均损失是 11.54。
到批次 15,平均损失是 11.50。
第 14 轮的平均损失是 11.50,平均绝对误差是 2.06。
<keras.src.callbacks.history.History at 0x168619c60>
务必查看现有的 Keras 回调, 阅读 API 文档。 应用包括记录到 CSV、保存 模型、在 TensorBoard 中可视化指标等等!