损失和准确性——这些是合理的学习曲线吗?

Loss & accuracy - Are these reasonable learning curves?

我正在学习神经网络,我在 Keras 中构建了一个简单的神经网络,用于 UCI 机器学习存储库中的鸢尾花数据集分类。我使用了一个带有 8 个隐藏节点的隐藏层网络。 Adam 优化器以 0.0005 的学习率使用,对于 200 个 Epochs 是 运行。 Softmax 在输出中使用,损失作为分类交叉熵。我得到以下学习曲线。

如您所见,准确性的学习曲线有很多平坦区域,我不明白为什么。错误似乎在不断减少,但准确性似乎并没有以同样的方式增加。精度学习曲线中的平坦区域意味着什么?为什么即使错误似乎在减少,但这些区域的准确度却没有增加?

这在训练中是正常的还是更有可能是我这里做错了什么?

dataframe = pd.read_csv("iris.csv", header=None)
dataset = dataframe.values
X = dataset[:,0:4].astype(float)
y = dataset[:,4]

scalar = StandardScaler()
X = scalar.fit_transform(X)

label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y)

encoder = OneHotEncoder()
y = encoder.fit_transform(y.reshape(-1,1)).toarray()

# create model
model = Sequential()
model.add(Dense(8, input_dim=4, activation='relu'))
model.add(Dense(3, activation='softmax'))

# Compile model
adam = optimizers.Adam(lr=0.0005, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='categorical_crossentropy',
              optimizer=adam, 
              metrics=['accuracy'])

# Fit the model
log = model.fit(X, y, epochs=200, batch_size=5, validation_split=0.2)

fig = plt.figure()
fig.suptitle("Adam, lr=0.0006, one hidden layer")

ax = fig.add_subplot(1,2,1)
ax.set_title('Cost')
ax.plot(log.history['loss'], label='Training')
ax.plot(log.history['val_loss'], label='Validation')
ax.legend()

ax = fig.add_subplot(1,2,2)
ax.set_title('Accuracy')
ax.plot(log.history['acc'], label='Training')
ax.plot(log.history['val_acc'], label='Validation')
ax.legend()

fig.show()

稍微了解一下 lossaccuracy 的实际含义(和机制)将在这里有很大帮助(另请参阅到我的,虽然我会重复使用一些部分)...

为了简单起见,我将讨论限制在二分类的情况下,但是这个想法是普遍适用的;这是(逻辑)损失的方程式:

  • y[i] 是真正的标签(0 或 1)
  • p[i]是预测([0,1]中的实数),通常解释为概率
  • output[i](等式中未显示)是 p[i] 舍入 ,以便将它们也转换为 0 或 1;正是这个数量进入了准确性的计算,隐含地涉及一个阈值(通常在 0.5 用于二进制分类),因此如果 p[i] > 0.5,则 output[i] = 1,否则 p[i] <= 0.5 ], output[i] = 0.

现在,假设我们有一个真实的标签 y[k] = 1,在训练的早期,我们对 p[k] = 0.1 做出了相当糟糕的预测;然后,将数字代入上面的损失方程:

  • 这个样本对loss的贡献是loss[k] = -log(0.1) = 2.3
  • 由于 p[k] < 0.5,我们将得到 output[k] = 0,因此它对 准确度 的贡献将为 0(错误分类)

现在假设,在下一个训练步骤中,我们确实变得更好了,我们得到 p[k] = 0.22;现在我们有:

  • loss[k] = -log(0.22) = 1.51
  • 因为它仍然是 p[k] < 0.5,我们又一次得到了错误的分类 (output[k] = 0),对准确性的贡献为零

希望您开始理解这个想法,但让我们再看一个稍后的快照,例如,p[k] = 0.49;然后:

  • loss[k] = -log(0.49) = 0.71
  • 仍然output[k] = 0,即对准确度贡献为零的错误分类

正如你所看到的,我们的分类器在这个特定的样本中确实变得更好了,即它从损失 2.3 到 1.5 再到 0.71,但是这种改进仍然没有体现在准确性上,它只关心 正确分类:从准确性的角度来看,我们对 p[k] 获得更好的估计并不重要,只要这些估计保持在 0.5 的阈值以下即可。

当我们的 p[k] 超过 0.5 的阈值时,损失继续像目前一样平稳地减少,但是现在我们有一个 跳跃 此样本从 0 到 1/n 的准确度贡献,其中 n 是样本总数。

同样,您可以自己确认,一旦我们的 p[k] 超过 0.5,从而给出正确的分类(现在对准确性有积极贡献),进一步改进它(即接近 1.0) 仍然继续减少损失,但对准确性没有进一步影响。

对于真实标签 y[m] = 0p[m] 的相应估计值开始高于 0.5 阈值的情况,也存在类似的论点;即使 p[m] 初始估计值低于 0.5(因此提供了正确的分类并且已经对准确性做出了积极贡献),它们向 0.0 的收敛将减少损失而不会进一步提高准确性。

将各个部分放在一起,希望您现在可以说服自己平稳减少损失和更“逐步”提高准确性不仅不相容,而且确实非常有意义。


在更一般的层面上:从数学优化的严格角度来看,没有所谓的“准确度”——只有损失;准确性仅从 业务 的角度进入讨论(并且不同的业务逻辑甚至可能需要不同于默认 0.5 的阈值)。引用我自己的 :

Loss and accuracy are different things; roughly speaking, the accuracy is what we are actually interested in from a business perspective, while the loss is the objective function that the learning algorithms (optimizers) are trying to minimize from a mathematical perspective. Even more roughly speaking, you can think of the loss as the "translation" of the business objective (accuracy) to the mathematical domain, a translation which is necessary in classification problems (in regression ones, usually the loss and the business objective are the same, or at least can be the same in principle, e.g. the RMSE)...