当损失为均方误差 (MSE) 时,什么函数定义了 Keras 中的准确性?

What function defines accuracy in Keras when the loss is mean squared error (MSE)?

损失函数为均方误差时Accuracy如何定义?是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

The MSE is a measure of the quality of an estimator—it is always non-negative, and values closer to zero are better.

这是否意味着 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

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

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

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

第一个现在应该从史努比博士的评论和另一个答案中清楚了:在像你这样的回归问题中,准确性是毫无意义;另请参阅 patyork 在 this Keras thread 中的评论。不管是好是坏,事实是 Keras 不会“保护”你或任何其他用户在你的代码中放置无意义的请求,即你不会得到任何错误,甚至警告,你正在尝试做一些事情没有意义,例如要求回归设置中的准确性。

澄清了这一点,另一个问题是:

既然 Keras 确实 return 一个“准确性”,即使在回归设置中,它到底是什么以及如何计算的?

为了在这里阐明一些情况,让我们恢复到 public 数据集(因为您没有提供有关数据的任何详细信息),即 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中Keras binary_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] 编辑的值相同 return...

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


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

  • 当在多 class 设置中,一个人恰好用 metrics=['accuracy'] 请求 loss='binary_crossentropy'(而不是 categorical_crossentropy)时给出无意义的结果- 在 and

    中查看我的答案
  • 完全禁用 Dropout,在极端情况下要求 dropout 率为 1.0 - 请参阅我在

    中的回答

@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)

你的labels应该是整数,因为keras不会舍入y_true,而且你的准确率很高......