培训MSE损失是否大于理论最大值?

问题描述

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

output = Dense(units=1,activation='sigmoid')

我正在用一些训练数据训练该模型,其中预期输出始终是0.0到1.0之间的数字。 我正在用均方误差编译模型:

model.compile(optimizer='adam',loss='mse')

由于预期输出和实际输出都是介于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]范围内。 无需等待培训结束,您会看到前几个时期的损失远大于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)

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

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

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

print( mse(np.random.random((100,)),np.random.random((100,))) )  # tf.Tensor(0.14863832582680103,dtype=float64)
print( mse( 10 * np.random.random((100,))) )  # tf.Tensor(30.51209646429651,dtype=float64)

最后,S型确实可以确保输出介于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

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

您可以使用np.mean(y_true)进行验证。

,

让我们回顾一下MSE的含义:

您有一个数据集(粉色点),并且找到了该数据集的平均值(蓝线),因此需要评估您的计算。因此,您需要在价值和均值之间保持距离。但是我们为什么要平方这个呢?因为您可能具有负值(以下几点),并且排除了补偿。最后,我们找到了该DISTANSE的平均值(请注意,它不是数据集的平均值,而是数据集的平均值) MSE explained

公式是:
MSE Formula

让我们假设我们的数据有1点(值)。还有MSE 简单的情况是平均值和当前值之间的距离。而且因为 我们没有什么可以总结和除以一的结果,MSE在 范围是0到1。

但是,由于您要处理的是巨大的数据集,因此整个值都是相加并除以数字,因此MSE在(0,+ inf)中。顺便说一句,我们不需要使用正方形,在简单的情况下可以使用绝对值。

Keras允许您编写自己的损失函数,因此您的问题并不难解决。因此,您应该编写一个函数来计算平方,而不是将其除以数字-将其缩放为range(0,1)(为此,SciKit中的MinMaxScaler会非常好)。然后,您应该执行相同的操作:总结并除以

或者您可以添加标准化层(idk它是如何工作的,但我知道是这样)。

进一步阅读:

  1. https://keras.io/api/layers/preprocessing_layers/core_preprocessing_layers/normalization/#:~:text=Normalization%20class&text=Feature%2Dwise%20normalization%20of%20the,sqrt(var)%20at%20runtime
  2. https://heartbeat.fritz.ai/how-to-create-a-custom-loss-function-in-keras-637bd312e9ab
,

乙状结肠不是平均值。这是一种将所有输出可变性作为可折叠性(范围为MinMaxScaler,但用于神经网络)折叠到range(0,1)的方法。当程序计算MSE时,它会做另一件事。不要混合。让我们用数学将其分开。
0 0 ^ 2 0 (因为这个和可以是。或更严格地说:如果b等于无穷大,则根据阿基米德属性)
设n = / = 0
0

,

我对所问的问题没有答案。我的 MSE 损失为 nans,输入范围为 [0,1],输出为 sigmoid。所以我认为这个问题是相关的。

以下是关于 sigmoid 的一些观察:

                        ]).node().id=

因此,可以从 sigmoid 中获取 nans。以防万一有人(我,在不久的将来)(再次)有这个疑问。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...