训练 MSE 损失大于理论最大值?

ooo*_*rrr 6 python loss mse keras sigmoid

我正在训练一个 keras 模型,它的最后一层是一个sigmoid单元:

output = Dense(units=1, activation='sigmoid')
Run Code Online (Sandbox Code Playgroud)

我正在用一些训练数据训练这个模型,其中预期输出总是介于 0.0 和 1.0 之间的数字。我正在用均方误差编译模型:

model.compile(optimizer='adam', loss='mse')
Run Code Online (Sandbox Code Playgroud)

由于预期输出和实际输出都是介于 0 和 1 之间的单个浮点数,因此我也期望损失介于 0 和 1 之间,但是当我开始训练时,我得到了3.3932大于 1的损失。

我错过了什么吗?

编辑: 我正在添加一个示例来显示问题:https : //drive.google.com/file/d/1fBBrgW-HlBYhG-BUARjTXn3SpWqrHHPK/view?usp=sharing (我不能只粘贴代码,因为我需要附加训练数据)

运行后python stackoverflow.py,将显示模型的摘要,以及训练过程。我还在每一步打印 y_true 的最小值和最大值,以验证它们是否在 [0, 1] 范围内。无需等待训练完成,您会看到前几个 epoch 的损失远大于 1。

ika*_*men 1

首先,我们可以揭开mse损失的神秘面纱——它是一个正常的可调用函数tf.keras

import tensorflow as tf
import numpy as np

mse = tf.keras.losses.mse
print(mse([1] * 3, [0] * 3))  # tf.Tensor(1, shape=(), dtype=int32)
Run Code Online (Sandbox Code Playgroud)

接下来,正如名称“均方误差”所暗示的那样,它是一个平均值,意味着只要平均值相同,传递给它的向量的大小就不会改变该值:

print(mse([1] * 10, [0] * 10)) # tf.Tensor(1, shape=(), dtype=int32)

为了使mse超过 1,平均误差必须超过 1:

print( mse(np.random.random((100,)), np.random.random((100,))) )  # tf.Tensor(0.14863832582680103, shape=(), dtype=float64)
print( mse( 10 * np.random.random((100,)), np.random.random((100,))) )  # tf.Tensor(30.51209646429651, shape=(), dtype=float64)
Run Code Online (Sandbox Code Playgroud)

最后,sigmoid 确实保证输出在 0 到 1 之间:

sigmoid = tf.keras.activations.sigmoid
signal = 10 * np.random.random((100,))

output = sigmoid(signal)
print(f"Raw: {np.mean(signal):.2f}; Sigmoid: {np.mean(output):.2f}" )  # Raw: 5.35; Sigmoid: 0.92
Run Code Online (Sandbox Code Playgroud)

这意味着在您的代码中, 的平均值y_true不在 0 和 1 之间。

您可以使用 来验证这一点np.mean(y_true)