Tensorflow Keras:对培训数据的自定义数据验证回调始终返回验证数据结果
我正在Keras中开发一个自动编码器,其中包含一些退出层。为了评估偏差和方差,我想比较训练和测试数据的损失。然而,由于辍学是在培训期间使用的,因此损失无法比较。(有关为什么训练数据结果可能比测试数据结果差的解释,请参阅。) 为了获得不受辍学影响的训练数据丢失,我编写了一个回调来验证一些额外的数据集(在本例中,它将再次是训练数据)。 奇怪的是,我总是得到与验证数据相同的结果。下面是一个简单的例子:Tensorflow Keras:对培训数据的自定义数据验证回调始终返回验证数据结果,tensorflow,validation,keras,callback,tf.keras,Tensorflow,Validation,Keras,Callback,Tf.keras,我正在Keras中开发一个自动编码器,其中包含一些退出层。为了评估偏差和方差,我想比较训练和测试数据的损失。然而,由于辍学是在培训期间使用的,因此损失无法比较。(有关为什么训练数据结果可能比测试数据结果差的解释,请参阅。) 为了获得不受辍学影响的训练数据丢失,我编写了一个回调来验证一些额外的数据集(在本例中,它将再次是训练数据)。 奇怪的是,我总是得到与验证数据相同的结果。下面是一个简单的例子: from pprint import pprint import keras import num
from pprint import pprint
import keras
import numpy as np
import pandas as pd
from numpy.random import seed as np_seed
from tensorflow.random import set_seed as tf_seed
np_seed(1)
tf_seed(2)
# Generation of data sets for training and testing. Random data is only used to showcase the problem.
df_train = pd.DataFrame(data=np.random.random((1000, 10))) # This will be used for training
df_test_1 = pd.DataFrame(data=np.random.random((1000, 10))) # This will be used as validation data set directly
df_test_2 = pd.DataFrame(data=np.random.random((1000, 10))) # This will be used within the callback
np_seed(1)
tf_seed(2)
model = keras.models.Sequential(
[
keras.Input(shape=(10, )),
keras.layers.Dropout(rate=0.01),
keras.layers.Dense(5, activation='relu'),
keras.layers.Dropout(rate=0.01),
keras.layers.Dense(10, activation='linear'),
]
)
model.compile(
loss='mean_squared_error',
optimizer=keras.optimizers.Adam(),
)
class CustomDataValidation(keras.callbacks.Callback):
def __init__(self, x=None, y=None):
self.x = x
self.y = y
def on_epoch_end(self, epoch, logs=None):
result = self.model.evaluate(x=self.x, y=self.y, return_dict=True)
for loss_name, loss_value in result.items():
logs["custom_" + loss_name] = loss_value
cdv = CustomDataValidation(df_test_2, df_test_2)
hist = model.fit(df_train, df_train, validation_data=(df_test_1, df_test_1), epochs=2, validation_split=0.1, callbacks=[cdv])
pprint(hist.history)
输出是
Epoch 1/2
4/4 [==============================] - 0s 1ms/step - loss: 0.7625
29/29 [==============================] - 0s 5ms/step - loss: 0.9666 - val_loss: 0.7625
Epoch 2/2
4/4 [==============================] - 0s 1ms/step - loss: 0.5331
29/29 [==============================] - 0s 2ms/step - loss: 0.6638 - val_loss: 0.5331
{'custom_loss': [0.7624925374984741, 0.5331208109855652],
'loss': [0.9665887951850891, 0.6637843251228333],
'val_loss': [0.7624925374984741, 0.5331208109855652]}
“自定义丢失”和“val丢失”是相等的,尽管它们应该基于完全不同的数据集。
因此,问题是:如何评估回调中自定义数据的模型性能
编辑:因为我还没有得到关于stackoverflow的答案,所以我在tensorflow的git repo上创建了一个。另外,现在有一个可用的示例显示了问题。这似乎是tensorflow版本2.3.x(使用2.3.0和2.3.1测试)中的一个错误。在版本2.4.0-rc0和2.2.1中,loss和custom_loss的损耗输出不同,这是预期行为:
{'custom_loss': [0.7694963216781616, 0.541864812374115],
'loss': [0.9665887951850891, 0.6637843251228333],
'val_loss': [0.7624925374984741, 0.5331208109855652]}
这似乎是tensorflow版本2.3.x(使用2.3.0和2.3.1测试)中的一个bug。在版本2.4.0-rc0和2.2.1中,loss和custom_loss的损耗输出不同,这是预期行为:
{'custom_loss': [0.7694963216781616, 0.541864812374115],
'loss': [0.9665887951850891, 0.6637843251228333],
'val_loss': [0.7624925374984741, 0.5331208109855652]}