在 MSE 损失函数中 n 代表什么?

数据挖掘 机器学习 神经网络 损失函数 毫秒
2022-02-26 01:12:01

神经网络损失函数 - 均方误差:关于“n”表示什么的问题

我不明白这个问题的答案是如何回答这个问题的。请帮助我理解以下案例:

让我们看一个有 10 个神经元的输出层。标签/目标也是大小为 10 的向量。假设我们只有 2 个样本/实例。

对于第一个样本,我们得到:

输出层:[0.9, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]

标签/目标:[1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

对于第二个样本:

输出层:[0.2, 0.9, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]

标签/目标:[0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

按照我的理解,我们可以计算每个样本的损失:

Loss = (1/10)*sum((output_layer - label)**2)

这样,n代表神经元的数量(10)。答案说n是样本数(2)。我的错误是什么?

而且,如果我使用全批次而不是小批量,我想在网络遍历所有样本后更新权重,这意味着(我认为)我想要所有样本的单一损失函数。我想到的唯一方法是将 n 定义为输出层中的神经元数量乘以样本​​数量。是这样完成的吗?

Loss_for_all_samples = (1/20)*sun((all_outputs - all_labels)**2)

其中 all_outputs 是每个样本的 output_layer 的总和,all_labels 是每个样本的标签总和。

3个回答

作为 10xAI 笔记的答案,n在损失函数中是指您计算损失的样本数,这意味着您基本上是在计算特定批次数据的平均损失。您的错误是您除以输出神经元的数量,这是不正确的,因为输出神经元的数量/类的数量对损失没有影响(在 MSE 的情况下)。您所指的损失函数均方损失仅适用于回归问题,而您的示例使用类,因此是分类问题。在回归问题中,您尝试预测的通常只有一个连续值(并且只有一个输出神经元),因此无需除以输出神经元的数量。对于您的示例,诸如交叉熵损失之类的东西会更有意义,

如果您正在查看 MSE 是如何在 Python 等中实现的,您会发现,本质上,均值是在两个维度(即特征和样本)中获取的:

def mse(x, y):
    diff = x - y
    err = np.square(diff)
    return np.mean(err)

(当没有给出轴作为参数时np.mean,NumPy 取所有轴的平均值)

例如,参见这里scikit learn implementation将上述函数应用于像上面这样的多维示例,具有 10 个特征和 2 个样本(即输入具有 (2,10) 作为形状)给出:

IN:
y_pred = np.array([
    [0.9, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1],
    [0.2, 0.9, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]])

y_true = np.array([
    [1  ,  0 ,  0 , 0  , 0  , 0  , 0  , 0  , 0  , 0  ],
    [0  ,  1 ,  0 , 0  , 0  , 0  , 0  , 0  , 0  , 0  ]])

mse(y_true, y_pred)

OUT: 0.02350000000000001

一般来说,
当我们讨论这个话题时,都是围绕着Stochastic GD、Mini-batch GD、Batch GD的思想。平均的想法是将梯度移向 Batch 的平均值。
所以,“N”是指batch_size一般的。

在输出层的聚合上,我相信它更像是一种设计实现。
检查此示例以了解 Keras

import tensorflow as tf, numpy as np
from tensorflow.python.keras.layers import Input, Dense
from tensorflow.python.keras.models import Model, Sequential
import keras.backend as K

model = Sequential()
model.add(Dense(3, activation="relu", input_shape=(2,), kernel_initializer=tf.keras.initializers.Ones()))
model.add(Dense(2, activation="relu", kernel_initializer=tf.keras.initializers.Ones()))

x = tf.constant([[2.,2.],[4.,4.],[5.,5.]])
y =tf.constant([[10.,12.], [20.,20.], [25.,25.]])

 # This is Keras standard definition i.e. reduce to mean on last axis
def mse_loss(y_true, y_pred): return K.mean(K.square(y_pred - y_true), axis=-1)
model.compile(loss=mse_loss) 

from keras.callbacks import LambdaCallback

def batchOutput(batch, logs): print("Finished batch: " + str(batch), end=''); print("--->",logs)
batchLogCallback = LambdaCallback(on_batch_end=batchOutput)

model.fit(x,y, batch_size=1, epochs=1,callbacks=[batchLogCallback], verbose=0, shuffle=False)

完成批次:0---> {'loss': 2.0}
完成批次:1---> {'loss': 8.509464263916016}
完成批次:2---> {'loss': 12.874275207519531}

您可以手动计算损失作为输入,并且权重已被视为简单整数。
最终损失 [4, 0] 平均为 2。

def mse_loss(y_true, y_pred): return K.sum(K.square(y_pred - y_true), axis=-1)

如果使用上面的函数输出会是,

完成批次:0---> {'loss': 4.0}
完成批次:1---> {'loss': 17.01892852783203}
完成批次:2---> {'loss': 25.748550415039062}