TensorFlow中fit()如何隐式关联整数标签与概率分布?相关疑问解析
问题
我正在学习TensorFlow,跟随MIT2023深度学习入门课程,在第二个实验中遇到了困惑:实验基于MNIST数据集构建CNN识别手写数字,训练标签是0-9的一维整数张量,但模型输出各数字的概率张量。
模型定义如下:
def build_cnn_model(): cnn_model = tf.keras.Sequential([ #Use parameters as shown in the diagram #First two params of Conv2D are filter shape tf.keras.layers.Conv2D(3,3, input_shape=(28, 28, 1), activation='relu'), tf.keras.layers.MaxPool2D(pool_size=(2,2), strides=(1,1)), tf.keras.layers.Conv2D(3,3, input_shape=(26, 26, 24)), tf.keras.layers.MaxPool2D(pool_size=(2,2), strides=(1,1)), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(10, activation='softmax') ]) return cnn_model cnn = build_cnn_model()
编译代码如下:
cnn.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=1e-1), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
随后调用:
cnn.fit(train_images, train_labels, batch_size=BATCH_SIZE, epochs=EPOCHS)
我知道使用sparse_categorical_crossentropy损失函数是因为无需独热编码,但对文档中概率范围的假设理解不深,且认为该解释不够完整:若模型输出层设为20个神经元,或训练标签唯一值超过10个会怎样?整数标签与概率分布的转换究竟发生在何处?
解答
输出层神经元数量与标签不匹配的情况
- 如果输出层设为20个神经元,而训练标签是0-9的整数,虽然不会直接报错,但模型会被迫学习一个包含20类的概率分布,其中10-19类的概率会被训练过程压得极低——这完全是浪费算力,没有任何实际意义。TensorFlow会默认输出层神经元数量对应总类别数,标签索引需要落在0到(神经元数-1)的范围内,超出范围才会触发报错。
- 如果训练标签的唯一值超过10个(比如有0-11共12类),但输出层只有10个神经元,训练时会直接报错。因为
sparse_categorical_crossentropy会把整数标签当作类别索引,10、11这些索引已经超出了输出层神经元的索引范围(0-9),损失函数找不到对应位置的概率来计算交叉熵。
整数标签与概率分布的转换位置
这个转换是在sparse_categorical_crossentropy损失函数内部自动完成的:它会把每个整数标签转换成对应的one-hot编码张量(比如标签5会变成[0,0,0,0,0,1,0,0,0,0]),然后再和模型输出的softmax概率分布计算交叉熵。整个过程对用户完全透明,不需要手动处理。
内容的提问来源于stack exchange,提问作者Jaded-Coded
相关产品推荐
相关产品推荐

