尽管损失值很高,但准确度很好

机器算法验证 神经网络 准确性
2022-02-15 02:05:06

在一个简单的神经网络二元分类器的训练过程中,我使用交叉熵得到了一个很高的损失值。尽管如此,准确性在验证集上的价值还是相当不错的。它有什么意义吗?损失和准确率之间没有严格的相关性吗?

我在训练和验证这些值:0.4011 - acc: 0.8224 - val_loss: 0.4577 - val_acc: 0.7826这是我第一次尝试实现神经网络,而且我刚刚接触机器学习,所以我无法正确评估这些结果。

4个回答

我遇到过类似的问题。

我已经用交叉熵损失训练了我的神经网络二元分类器。这里是作为时代函数的交叉熵的结果。红色是训练集,蓝色是测试集。

作为时代函数的交叉熵。

通过展示准确度,我惊讶地发现,与 epoch 50 相比,epoch 1000 的准确度更高,即使对于测试集也是如此!

精度作为时代的函数

为了理解交叉熵和准确性之间的关系,我研究了一个更简单的模型,即逻辑回归(一个输入和一个输出)。下面我只用3个特殊情况来说明这种关系。

一般来说,交叉熵最小的参数并不是精度最大的参数。然而,我们可能期望交叉熵和准确性之间存在某种关系。

[在下文中,我假设您知道什么是交叉熵,为什么我们使用它而不是准确率来训练模型等。如果不知道,请先阅读:如何解释交叉熵分数?]

图1这是为了说明交叉熵最小的参数不是准确率最大的参数,并理解为什么。

这是我的示例数据。我有 5 个点,例如输入 -1 导致输出 0。 5分样本

交叉熵。 在最小化交叉熵后,我获得了 0.6 的准确度。0 和 1 之间的切割在 x=0.52 处完成。对于这 5 个值,我分别获得了交叉熵:0.14、0.30、1.07、0.97、0.43。

准确性。 在最大化网格上的精度后,我获得了许多导致 0.8 的不同参数。这可以通过选择切割 x=-0.1 直接显示。好吧,您也可以选择 x=0.95 来切割集合。

在第一种情况下,交叉熵很大。确实,第四点离切割很远,所以交叉熵很大。即我分别得到一个交叉熵:0.01、0.31、0.47、5.01、0.004。

在第二种情况下,交叉熵也很大。在这种情况下,第三点离切割很远,所以交叉熵很大。我分别获得了交叉熵:5e-5、2e-3、4.81、0.6、0.6。

最小化交叉熵对于这个,我们可以展示当变化时交叉熵和准确度的演变(在同一张图上)。 aab小数据示例

图 2这里我取我将数据作为 logit 模型下的样本,斜率和截距我选择了一个种子有很大的影响,但是很多种子会导致一个相关的行为。n=100a=0.3b=0.5

在这里,我只绘制了最有趣的图表。最小化交叉熵对于这个,我们可以显示当变化时(在同一张图上)交叉熵和准确度的演变。 bba中号套装

这是一件有趣的事情:情节看起来像我最初的问题。交叉熵在上升,选择变得如此之大,但准确度继续上升(然后停止上升)。a

我们无法选择精度更高的模型(首先因为我们知道底层模型是!)。a=0.3

图 3这里我取,其中现在,我们可以观察到准确性和交叉熵之间的密切关系。n=10000a=1b=0

相当大的数据

我认为如果模型有足够的容量(足以包含真实模型),并且如果数据很大(即样本量趋于无穷大),那么当准确度最大时,交叉熵可能最小,至少对于逻辑模型. 我没有证据,如果有人有参考,请分享。

参考书目:将交叉熵和准确度联系起来的主题很有趣也很复杂,但是我找不到涉及这个的文章……研究准确度很有趣,因为尽管是一个不正确的评分规则,但每个人都可以理解它的含义。

注意:首先,我想在这个网站上找到一个答案,关于准确性和交叉熵之间关系的帖子很多但答案很少,请参阅:Comparable train and test cross-entropies result in very different accuracy验证损失下降,但验证准确性恶化对分类交叉熵损失函数的怀疑将日志损失解释为百分比......

还需要注意的一件重要事情是交叉熵不是有损失。这意味着一个非常错误的预测可能会使您的损失“爆炸”。从这个意义上说,可能有一个或几个异常值被分类得非常糟糕并且导致损失爆炸,但与此同时,您的模型仍在对数据集的其余部分进行学习。

在以下示例中,我使用了一个非常简单的数据集,其中测试数据中存在异常值。有 2 类“零”和“一”。

以下是数据集的样子:

在此处输入图像描述

如您所见,这 2 个类非常容易分离:0.5 以上是“零”类。仅在测试集中,在“零”类的中间还有一个“一”类的异常值。这个异常值很重要,因为它会干扰损失函数。

我在这个数据集上训练了一个隐藏的神经网络,你可以看到结果:

在此处输入图像描述

损失开始增加,但准确度仍在继续增加。

绘制每个样本的损失函数直方图清楚地显示了问题:对于大多数样本(0 处的大条),损失实际上非常低,并且有一个异常值具有巨大的损失(17 处的小条)。由于总损失是平均值,即使它在除一个之外的所有点上都表现得非常好,你也会在该组中获得很高的损失。

在此处输入图像描述

奖励:数据和模型的代码

import tensorflow.keras as keras
import numpy as np

np.random.seed(0)
x_train_2 = np.hstack([1/2+1/2*np.random.uniform(size=10), 1/2-1.5*np.random.uniform(size=10)])
y_train_2 = np.array([0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1])
x_test_2 = np.hstack([1/2+1/2*np.random.uniform(size=10), 1/2-1.5*np.random.uniform(size=10)])
y_test_2 = np.array([0,0,0,1,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1])

keras.backend.clear_session()
m = keras.models.Sequential([
    keras.layers.Input((1,)),
    keras.layers.Dense(3, activation="relu"),
    keras.layers.Dense(1, activation="sigmoid")
])
m.compile(
    optimizer=keras.optimizers.Adam(lr=0.05), loss="binary_crossentropy", metrics=["accuracy"])
history = m.fit(x_train_2, y_train_2, validation_data=(x_test_2, y_test_2), batch_size=20, epochs=300, verbose=0)

TL;博士

您的损失可能会被一些异常值劫持,请检查您的损失函数在验证集的各个样本上的分布。如果平均值周围有一组值,那么你就过拟合了。如果只有少数几个值高于低多数群体,那么您的损失会受到异常值的影响:)

ahstat 提供了非常好的插图。

受这些插图的启发,我总结出两个可能的原因。1. 模型过于简单,无法提取预测所需的特征。在您的插图 1 中,这是一个多方面的问题,需要多一层才能获得 100% 的准确度。2. 数据有太多嘈杂的标签。(比较图 1 和图 3)

至于图 2,它解释了为什么我们不能在模型上添加过多的 L1/L2 正则化。

在分类交叉熵案例中,准确度衡量的是真阳性,即准确度是离散值,而 softmax 损失的对数损失可以说是衡量模型对抗假阴性的性能的连续变量。错误的预测会稍微影响准确性,但会不成比例地惩罚损失。假设您有一个平衡的数据集。

那么是什么导致了损失与准确性的差异呢?

  • 当模型预测更大胆时,损失会下降并且准确性保持不变。暗示模型在其类中表现良好

  • 一个有信心的错误预测会略微降低准确度,但损失会增加,即过拟合模型可能有很好的准确度但损失很差

对于分类交叉熵损失,只是猜测的哑模型应该有 y=-ln(1/n) 的损失,其中 n 是平衡的数字或类别。进一步应用您的类之间不平衡的概率,以首先计算预期的机会 logloss 作为基线。一旦您知道了,您就可以评估模型的训练效果,并使用损失作为准确性的代理来推断模型性能。