我使用回调来停止训练后,我的损失低于一定的值。一旦训练结束,我在训练输入上调用predict()
方法,然而,当我手动计算损失函数时,我得到了一个非常糟糕的结果。使用predict()
是错误的吗?还是我做错了什么?
import numpy as np
import random
import tensorflow as tf
from sklearn.metrics import mean_squared_error as my_mse
class stopAtLossValue(tf.keras.callbacks.Callback):
def on_epoch_end(self, batch, logs={}):
eps = 0.00001
if logs.get('loss') <= eps:
self.model.stop_training = True
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(x.shape[1],)),
tf.keras.layers.Dense(8, activation='relu'),
tf.keras.layers.Dense(8, activation='relu'),
tf.keras.layers.Dense(8, activation='relu'),
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(1)
])
model.compile(loss='mse',optimizer = tf.keras.optimizers.Adam(learning_rate=0.001))
model.fit(x, y, epochs=1000, batch_size=1, verbose=1, callbacks=[stopAtLossValue()])
例如,当我运行代码片段时,我在112次循环后达到所需的损失值。
Epoch 111/1000
20/20 [==============================] - 0s 2ms/step - loss: 0.0294
Epoch 112/1000
20/20 [==============================] - 0s 315us/step - loss: 1.0666e-06
<keras.callbacks.History at 0x153a7b70d30>
然后调用predict()
方法,自己计算损失。顺便说一下,我的损失函数只是一个最小平方误差(MSE)我得到的价值相当高。事实上,如果我打印预测,即使我因为MSE低而停止了训练,它们看起来也很糟糕。
my_mse(y,model.predict(x))
0.027716089
差异是因为在训练期间显示的损失是每批损失的平均值,但是对于每个批都有一个梯度更新,所以模型权重在此期间是变化的,所以你不会得到与使用predict评估相同的损失值,因为如果你使用predict,权重是固定的。
所以最终,这些数字是不可比较的,因为它们不是以相同的方式计算的。