Keras模型.fit()中的验证损失不符合预期

5

当使用model.compile()中的loss='mean_squared_error'来训练我的网络时,我会使用Keras中的model.fit()。

model.compile(loss='mean_squared_error', optimizer=optimizers.Adam(decay=0.00001), metrics=['accuracy'])
hist=model.fit(X, Y, epochs=200, batch_size=2000,  verbose=2, shuffle="batch", validation_data=(Xval,Yval))

训练结束时,输出结果如下:

Epoch 200/200 23s - loss: 1.2060 - acc: 0.5168 - val_loss: 1.5213 - val_acc: 0.5294

如果我手动检查验证集上的损失值,则为:

pre=model.predict(Xval)
print(np.mean(np.square(pre-Yval)))

我得到的是1.4587而不是1.5213。
为什么会有差异?我为什么没有得到model.fit()计算出的1.5213?我是否漏掉了一些东西?model.fit()难道不是遍历整个验证集吗?

1
你实际上得到了更低的损失值,为什么你不开心呢? - DarkCygnus
没错。但是,model.fit() 报告的 val_loss 不应该与我手动计算的损失相匹配吗? - samjk
也许您选择的损失度量方式与Keras计算方式不同。 - DarkCygnus
1
没错。你还能用什么方法计算均方损失? - samjk
建议您查看“losses”文件的源代码,您可以看到他们如何实现均方误差损失。Keras调用它们的后端中的'k.mean'和'k.square',不确定它们是否与Numpy的相同。无论如何,查看代码可能会给您更好的了解。但是,我怀疑原因是其他的,在一个答案中我已经提及了,希望对您有所帮助。 - DarkCygnus
2个回答

6
分析这种情况后,我认为我知道您可能遇到问题的原因。从您在epoch 200上得到的输出来看,我们可以看出您模型在那一时刻的指标如下: loss:1.2060 - acc:0.5168 - val_loss:1.5213 - val_acc:0.5294
这意味着,在最后一个epoch中,您正在训练的前馈模型获得了1.2060的损失值(验证损失为1.5213)。
然而,训练算法仍然需要反向传播该最终损失以更新您的模型权重。只有在迭代输入、计算指标,最后反向传播权重之后,才会认为一个epoch“结束”。对于任何其他epoch,同样的过程都将继续进行。
这就是为什么当您在最终epoch之后进行评估时,会得到不同的损失值,因为您的模型在最后一次反向传播更新您的模型后发生了一些变化,学习比上一步更多。这也可以解释为什么在第200个epoch之后,您获得了更低的损失值,因为您的模型经历了成功训练的另一个epoch。

0

可能有两个原因:

  1. 你的网络输出是向量,而 mse 假定输出和目标输出都是标量。虽然使用向量仍然可以工作,但值不可靠。
  2. 在训练期间,你使用了 batch_size 为 2000,而在预测期间,batch_size 是 1。尝试 model.predict(Xval, batch_size=256)。这将确保两者的条件相同。

我尝试在 model.predict() 中更改 batch_sizes。但是验证损失仍然相同。 - samjk
你也试过第一个选项了吗? - Shagun Sodhani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接