首页 > 解决方案 > 手动和自动验证损失不同

问题描述

我使用 TensorFlow 1.14.0 和 Keras 2.2.4。我正在使用带有自定义验证丢失的以下代码:

seedn=40
import numpy as np
np.random.seed(seedn)
import random
random.seed(seedn)
import tensorflow as tf
tf.set_random_seed(seedn)

from tensorflow.keras import optimizers
from tensorflow.keras import backend as K
from tensorflow.keras.layers import Input, Dense, Activation
from tensorflow.keras.models import Model, Sequential

def EVM_cal(data,prediction):
    return np.sqrt(np.mean((prediction - data) ** 2) / np.mean(data ** 2))*100

def EVMper(data, prediction):
    return K.sqrt(K.mean((prediction-data) ** 2) / K.mean(data** 2)) * 100


x_train_s=np.reshape(np.arange(1,1201),(100,12))/18000;
x_test_s=np.reshape(np.arange(1201,1801),(50,12))/18000;

model = Sequential()
model.add(Dense(8, input_shape=(x_train_s.shape[1],)))
model.add(Activation('linear'))
model.add(Dense(x_train_s.shape[1],))
model.add(Activation('linear'))

model.compile(optimizer='adam', loss=EVMper)
fittingadam = model.fit(x_train_s, x_train_s, epochs=4,
                        validation_data=(x_test_s, x_test_s),verbose=2)

Val_Loss = np.array(fittingadam.history['val_loss'])
print('Last Val Loss (Automatic)= ', Val_Loss[-1])

myEVM = EVM_cal(x_test_s,  model.predict(x_test_s))
print('Last Val Loss (Manual) =', myEVM)

输出是:

Last Val Loss (Automatic)=  89.88273468017579
Last Val Loss (Manual) = 89.90268535029907

正如我们所见,手动和自动验证损失减少了大约 0.02。在这里,我以生成测试和训练集为例。但是,对于我的真实数据集,手动和自动验证损失大约为 2。为什么它们不同?我怎样才能解决这个问题?

标签: python-3.xvalidationtensorflowkerasneural-network

解决方案


不确定,但这可能是评估期间的批量大小问题。与通常的损失不同,您的损失将来自许多样本的值混合在一起。(两批次的平均值不等于整个数据的结果)

你可以尝试batch_size=50(整个测试数据的大小)来测试。

您也可以尝试在像这样的小模型中自己调用 Keras 指标(也可能受批量大小的影响):

dataInput = Input((x_train_s.shape[1],))
predInput = Input((x_train_s.shape[1],))
output = Lambda(lambda x: EVMper(x[0], x[1]))([dataInput, predInput])

evaluator = Model([dataInput, predInput], output)
print(evaluator.predict([x_test_s, x_test_s]))

如果问题恰好是批量大小,一种解决方案,仅针对样本损失(不要像您的混合样本那样混合样本),可能是将批量维度留给 Keras 处理(必须测试)。不要取批量维度的平均值,只取其他维度。损失的最终形状应该是(batch_size,)


推荐阅读