为什么model.fit()使用categorical_crossentropy损失函数通过tf.train.AdamOptimizer引发ValueError?

时间:2018-11-13 06:29:03

标签: python tensorflow machine-learning keras neural-network

我正在使用TensorFlow basic classification example中的“入门”文档中提供的Keras API。我按原样完成了本教程,但是如果将损失函数从sparse_categorical_crossentropy更改为categorical_crossentropy,则下面的代码:

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])

model.compile(optimizer=tf.train.AdamOptimizer(), 
          loss='categorical_crossentropy',
          metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=5)

在训练/拟合步骤中失败,并出现以下错误:

ValueError: Error when checking target: expected dense_1 to have shape (10,) but got array with shape (1,)

关于损失函数的文档没有深入研究预期的输入和输出。显然这里存在维数问题,但是如果有任何专家可以给出详细的解释,那么该损失函数或引发该ValueError的任何其他损失函数又是什么呢?

1 个答案:

答案 0 :(得分:4)

sparse_categorical_crossentropy丢失期望提供的标签为整数,如0、1、2等,其中每个整数表示特定的类别。例如,类别0可能是狗,类别1可能是猫,而类别2可能是狮子。另一方面,categorical_crossentropy丢失采用一种热编码的标签,例如[1,0,0][0,1,0][0,0,1],它们被解释为索引为1表示样本的类别。例如[0,0,1]表示此样本属于2类(即狮子)。此外,在分类模型的上下文中,由于输出通常是softmax层的输出产生的概率分布,因此这种形式的标签也对应于概率分布,并与模型的输出匹配。同样,[0,0,1]意味着我们以概率1知道该样本属于第二类。

sparse_categorical_crossentropy几乎是使用categorical_crossentropy作为损失函数的一种便捷方法,在该函数中Keras(或其后端)将在内部处理整数标签,而您无需手动将标签转换为-热编码形式。但是,如果您提供的标签是一次性编码的,则必须使用categorical_crossentropy作为损失函数。

另外,您可能也有兴趣研究this answer,在这里我简要介绍了激活和丢失功能以及在各种分类任务中使用的标签格式。