【问题标题】:Why the loss function (mse) calculated by keras not the same as mine为什么keras计算的损失函数(mse)和我的不一样
【发布时间】:2021-04-30 17:10:09
【问题描述】:

我想自己在keras中测试损失函数mse。但是,计算出来的答案是不同的。 mse的定义如下: https://en.wikipedia.org/wiki/Mean_squared_error

测试代码如下:

from keras.datasets import boston_housing
import numpy as np
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()


x_train = train_data.astype(np.float32)

from keras import models 
from keras import layers

model = models.Sequential() 
model.add(layers.Dense(64, activation='relu', input_shape=(13,))) 
model.add(layers.Dense(64, activation='relu')) 
model.add(layers.Dense(1))
model.compile(optimizer='rmsprop',loss='mse', metrics=['mae'])

y_train = train_targets.astype(np.float32)
# y_test = test_targets.astype(np.float32)

model.fit(x_train,y_train,epochs=1,batch_size=404)

print(np.mean((y_train - model.predict(x_train).ravel()) ** 2))

显示在keras中损失函数在816左右。但是从mse的定义来看,结果是704左右,为什么这里的结果不一样呢?

【问题讨论】:

  • 假设你改变了你的epochs=1,batch_size=404,即一次性训练整个批次,所以你没有给模型太多训练,而模型训练给了你mse。现在使用该训练模型,您可以预测相同的训练数据。该模型不会给您相同的 mse,因为当它看到您的 404 个数据点时,它已经调整了权重。因此,该模型不太可能在训练数据上表现出相同的性能,否则它将是一个过拟合的模型。
  • @simpleApp 我改变了epochs和batch_size,损失函数结果还是不一样。对于 keras,是 8412。对于我的计算,大约是 1469。谢谢
  • 它们相距甚远,因此没有意义。需要挖掘更多。

标签: python keras loss-function


【解决方案1】:

你做了平方差的平均值,你需要先在矩阵上做平均值,然后在样本列表上做平均值,你没有在 numpy 数组中做平均值,你需要做差异一个样本,不在样本列表中。

下面是mse的实现:

def my_mse(y_true, y_pred):
    return np.mean(np.square(y_pred - y_true))

每次对每个样本都执行此操作,然后取平均值

【讨论】:

  • 感谢您的回复。在 keras 中设置自定义的 mse 损失函数是一个好主意。但是,我仍然不完全了解 keras 中的过程。你是什​​么意思我需要先在矩阵上做平均值,然后在样本列表上做平均值?您能否显示修改后的代码,以便结果可以相同?谢谢。
  • 对不起,我没有发现model.predict(x_train)的输出的张量是2,我已经修改了代码,把张量减少到了1。希望你进一步的建议。
【解决方案2】:

你使用的代码实际上是在做矩阵减法,试试这个代码计算mse误差:

sub_sqr=0
for a,b in zip(y_train,model.predict(x_train)):
    sub_sqr+= (a-b)**2

print(f"rme : {sub_sqr/len(y_train)}")

如果您增加 epoch 并优化模型,您的 mse 将几乎相同,否则会出现一些差异。

用这个 model.fit(x_train,y_train,epochs=4000,batch_size=404)

1/1 [==============================] - 0s 2ms/step - loss: 7.3889 - mse: 7.3889

rme : [7.54777]

【讨论】:

  • 谢谢。我已经修改了代码。 model.predict(x_train) 是一个矩阵,因此上面的这个差异被错误地计算为一个矩阵。 model.predict(x_train) 已转换为数组。我能问一下为什么只有当epoch很大时结果才匹配?如果 batch_size 为 404,则每个 epoch 意味着参数(权重和偏差)更新一次。我使用 model.predict(x_train) 来获得预测的 y 值。然后使用公式:np.mean((y_train - model.predict(x_train).ravel()) ** 2) 得到mse函数。应该和keras计算的结果一样。
  • large epoch - 想要训练模型进行大量重复,使其过拟合训练数据。通常在生产中,您的目标永远不会是这样,因为您的方法是减少模型从未观察/看到的数据(又名测试数据)的 mse。此外,训练模型与函数式编码不同,您希望调整模型以获得较高的预测成功率,这就是您将 reLU 放在那里的原因。有意义吗?
  • 对于上面的模型,如果epoch为1,那么参数会更新1次。参数更新后,我们应该使用代码得到当前参数下的mse:print(np.mean((y_train - model.predict(x_train).ravel()) ** 2))。它应该等于从keras计算的损失。为什么与时代有关? Epoch 应该只影响参数更新的时间吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多