【问题标题】:Loss & accuracy - Are these reasonable learning curves?损失和准确性——这些是合理的学习曲线吗?
【发布时间】:2018-05-28 18:47:50
【问题描述】:

我正在学习神经网络,我在 Keras 中构建了一个简单的神经网络,用于来自 UCI 机器学习存储库的虹膜数据集分类。我使用了一个带有 8 个隐藏节点的隐藏层网络。 Adam 优化器使用 0.0005 的学习率并运行 200 个 Epoch。 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()

【问题讨论】:

    标签: machine-learning neural-network keras classification loss


    【解决方案1】:

    lossaccuracy 的实际含义(和机制)有一点了解会大有帮助(也请参阅我的 this answer,尽管我会重复使用一些部分)...

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

    • 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.5output[i] = 0。李>

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

    • 这个样本对损失的贡献是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,但是这种改进仍然没有体现在准确度上,它只关心 正确的分类:从准确性的角度来看,只要这些估计值保持在 0.5 的阈值以下,我们得到更好的 p[k] 估计值并不重要。

    当我们的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 的阈值)。引用我自己的linked answer

    损失和准确性是不同的东西;粗略地说,准确度是我们从商业角度真正感兴趣的,而损失是学习算法(优化器)试图从数学角度最小化的目标函数em> 观点。更粗略地说,您可以将损失视为业务目标(准确性)到数学领域的“转换”,这是分类问题中所必需的转换(在回归问题中,通常损失和业务目标是相同,或者至少原则上可以相同,例如 RMSE)...

    【讨论】:

      猜你喜欢
      • 2021-11-03
      • 2021-05-30
      • 1970-01-01
      • 2021-05-05
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2019-05-04
      相关资源
      最近更新 更多