当损失是均方误差 (MSE) 时,啥函数定义 Keras 中的准确性?

Posted

技术标签:

【中文标题】当损失是均方误差 (MSE) 时,啥函数定义 Keras 中的准确性?【英文标题】:What function defines accuracy in Keras when the loss is mean squared error (MSE)?当损失是均方误差 (MSE) 时,什么函数定义 Keras 中的准确性? 【发布时间】:2018-07-24 07:47:43 【问题描述】:

当损失函数为均方误差时,准确度如何定义?是mean absolute percentage error吗?

我使用的模型具有输出激活线性,并使用loss= mean_squared_error编译

model.add(Dense(1))
model.add(Activation('linear'))  # number

model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])

输出如下所示:

Epoch 99/100
1000/1000 [==============================] - 687s 687ms/step - loss: 0.0463 - acc: 0.9689 - val_loss: 3.7303 - val_acc: 0.3250
Epoch 100/100
1000/1000 [==============================] - 688s 688ms/step - loss: 0.0424 - acc: 0.9740 - val_loss: 3.4221 - val_acc: 0.3701

那么,例如val_acc: 0.3250 是什么意思? Mean_squared_error 应该是一个标量而不是一个百分比 - 不应该吗?那么 val_acc - 均方误差,或平均百分比误差或其他函数?

来自***上 MSE 的定义:https://en.wikipedia.org/wiki/Mean_squared_error

MSE 是衡量估算器质量的指标——它始终是 非负数,接近零的值更好。

这是否意味着val_acc: 0.0 的值优于val_acc: 0.325

编辑:我训练时准确度指标输出的更多示例 - 当我训练更多时,准确度会增加。而损失函数 - mse 应该减少。是否为 mse 定义了准确度 - 在 Keras 中是如何定义的?

lAllocator: After 14014 get requests, put_count=14032 evicted_count=1000 eviction_rate=0.0712657 and unsatisfied allocation rate=0.071714
1000/1000 [==============================] - 453s 453ms/step - loss: 17.4875 - acc: 0.1443 - val_loss: 98.0973 - val_acc: 0.0333
Epoch 2/100
1000/1000 [==============================] - 443s 443ms/step - loss: 6.6793 - acc: 0.1973 - val_loss: 11.9101 - val_acc: 0.1500
Epoch 3/100
1000/1000 [==============================] - 444s 444ms/step - loss: 6.3867 - acc: 0.1980 - val_loss: 6.8647 - val_acc: 0.1667
Epoch 4/100
1000/1000 [==============================] - 445s 445ms/step - loss: 5.4062 - acc: 0.2255 - val_loss: 5.6029 - val_acc: 0.1600
Epoch 5/100
783/1000 [======================>.......] - ETA: 1:36 - loss: 5.0148 - acc: 0.2306

【问题讨论】:

我认为你很困惑。回归问题没有定义精度,你看到的均方误差不是百分比,而是你得到的实际值,它可能小于 1。 是的,Matias,我很困惑。因为我的回归问题的准确性 - 表现得像一个百分比。它从训练的第一个时期开始为 acc: 0.0 - 并增加到 acc: 0.99。如果 acc 实际上是 mse - 那么在开始第一个 epoch 时我会得到最好的结果,对吧? 0.0 的 Mse 比 0.99 好 - 这就是为什么我不认为 acc 是 mse 而是百分比。但是这个百分比是如何定义的呢?是平均绝对百分比误差吗? 准确率只是正确分类示例的分数,它始终是标签 == 预测为真的分数。对于回归来说,这是没有意义的,因为预测值与标签完全相同的可能性非常小,但您的模型似乎可以非常准确地做到这一点。 Keras 中的准确性绝不意味着绝对错误,但正如我之前提到的那样。 同样,答案是一样的,Keras 的准确率不会改变,如果它的回归或分类,它总是标签 == 预测的分数。它的行为是正确的,你对它的解释是错误的。 不,不是,这就是为什么准确性对回归没有意义。 【参考方案1】:

损失函数(在本例中为均方误差)用于指示您的预测与目标值的偏差程度。在训练阶段,权重会根据这个数量进行更新。如果您正在处理分类问题,通常会定义一个称为准确性的附加指标。它监控在多少情况下预测了正确的类别。这表示为百分比值。因此,值 0.0 表示没有正确的决定,而 1.0 表示只有正确的决定。 当您的网络在训练时,损失会减少,通常准确度会提高。

请注意,与损失相比,准确性通常不用于更新网络参数。它有助于监控学习进度和网络的当前性能。

【讨论】:

BGraf,从我帖子中的代码可以看出——我没有分类问题,而是回归问题。我的损失是 mse - 我要求 Keras 训练的输出是准确的。但是当问题是回归问题而不是分类问题时,准确度意味着什么? 在回归问题的情况下,没有理由计算准确度指标,因为没有“错误”或“正确”的决定需要衡量。如果您要预测连续目标,那么 keras 中的准确度指标没有相关意义。您应该使用均方误差之类的量来评估网络的性能。 是的,确实如此!我正在根据耳石图像预测鱼的年龄,MSE 损失函数很好,因为这对预测施加了全排序。例如。 3 岁的耳石更类似于 2 岁或 3 岁,然后说 7 岁或 8 岁。虽然为了将网络性能与人类专家进行比较,准确性更有用,因为这是专家评估自己的方式。也许这是一个不寻常的用例,但绝对是计算准确性的原因。 @EndreMoen 您正在计算的不是机器学习中所理解的准确性,您正在计算一些并非真正准确的自定义指标,您对此事实感到困惑。【参考方案2】:

您的问题至少有两个不同的问题。

现在从 Snoopy 博士的 cmets 和另一个答案中应该清楚第一个问题:在回归问题(例如您的问题)中,准确性毫无意义;另请参阅 this Keras thread 中 patyork 的评论。不管好坏,事实是 Keras 不会“保护”您或任何其他用户免于在您的代码中放置无意义的请求,即您不会收到任何错误,甚至警告,您正在尝试执行某些操作没有意义,例如在回归设置中要求准确性。

澄清后,另一个问题是:

由于 Keras 确实返回“准确度”,即使在回归设置中,它到底是什么以及如何计算?

为了阐明这一点,让我们回到一个公共数据集(因为您没有提供有关数据的任何详细信息),即Boston house price dataset(本地保存为housing.csv),并运行一个简单的实验,如下所示:

import numpy as np
import pandas
import keras

from keras.models import Sequential
from keras.layers import Dense

# load dataset
dataframe = pandas.read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:13]
Y = dataset[:,13]

model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
# Compile model asking for accuracy, too:
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])

model.fit(X, Y,
     batch_size=5,
     epochs=100,
     verbose=1)

与您的情况一样,模型拟合历史(此处未显示)显示损失减少,准确度大致增加。现在让我们使用适当的 Keras 内置函数来评估同一训练集中的模型性能:

score = model.evaluate(X, Y, verbose=0)
score
# [16.863721372581754, 0.013833992168483997]

score 数组的确切内容取决于我们在模型编译期间的确切要求;在我们这里的例子中,第一个元素是损失(MSE),第二个是“准确度”。

至此,让我们看一下metrics.py file中Kerasbinary_accuracy的定义:

def binary_accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)

因此,在 Keras 生成预测 y_pred 之后,它首先对它们进行四舍五入,然后检查其中有多少等于真实标签 y_true,然后再得到平均值。

让我们在本例中使用纯 Python 和 Numpy 代码复制此操作,其中真正的标签是 Y

y_pred = model.predict(X)
l = len(Y)
acc = sum([np.round(y_pred[i])==Y[i] for i in range(l)])/l
acc
# array([0.01383399])

好吧,宾果游戏!这其实和上面score[1]返回的值是一样的……

长话短说:由于您(错误地)在模型编译中请求 metrics=['accuracy'],Keras 将 do its best to satisfy you,并且确实会返回一些“准确度”,如上所示,尽管这在你的设置。


在很多设置中,Keras 在后台执行相当无意义的操作,而没有向用户提供任何提示或警告;我碰巧遇到的其中两个是:

在多类设置中,当一个人碰巧用metrics=['accuracy'] 请求loss='binary_crossentropy'(而不是categorical_crossentropy)时给出毫无意义的结果 - 请参阅我在Keras binary_crossentropy vs categorical_crossentropy performance? 和Why is binary_crossentropy more accurate than categorical_crossentropy for multiclass classification in Keras? 中的答案

完全禁用 Dropout,在极端情况下,当一个请求的 dropout 率为 1.0 - 请参阅我在 Dropout behavior in Keras with rate=1 (dropping all input units) not as expected 中的回答

【讨论】:

【参考方案3】:

@desertnaut 说的很清楚了

考虑以下两段代码

compile code

binary_accuracy code

def binary_accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)

你的标签应该是整数,因为keras不圆y_true,而且你得到的准确率很高......

【讨论】:

以上是关于当损失是均方误差 (MSE) 时,啥函数定义 Keras 中的准确性?的主要内容,如果未能解决你的问题,请参考以下文章

mse是啥需要看吗spss

交叉熵函数(Cross Entropy)与均方误差损失函数(MSE)对比?为什么选择交叉熵函数?

keras中的加权mse自定义损失函数

损失函数——均方误差和交叉熵

[转] 为什么分类问题的损失函数采用交叉熵而不是均方误差MSE?

PyTorch 中自定义后向函数的损失 - 简单 MSE 示例中的爆炸损失