使用sparse_categorical_crossentropy出现logits与labels维度不匹配错误
报错根因
你遇到的维度不匹配问题核心是模型输出结构和任务类型不匹配:
- 你当前的模型最终输出维度为
(批次大小, 28),仅支持单标签28分类任务 - 你传入的稀疏标签维度为
(批次大小, 2),属于双标签28分类任务,sparse_categorical_crossentropy默认会将标签最后一维以外的维度全部识别为批次维度,因此(批次大小,2)的标签会被自动展平为(2*批次大小, ),和模型输出的第一维批次大小完全无法匹配,也就出现了日志中批次为20时,标签维度为40、logits维度为20的报错。 - 你之前用
(1382,28)的独热标签可以正常训练,是因为该维度刚好匹配单标签28分类的输出要求,说明你之前的训练实际是把双标签合并为了单28分类任务处理。
解决方案
根据你的实际任务需求选对应方案即可:
方案1:保留双标签分类任务
需要调整输出层结构,让模型输出和双标签维度匹配:
- 把原有输出层替换为输出维度56的全连接层,再通过Reshape层把输出转为
(批次大小, 2, 28),对应2个标签各28个分类的概率分布 - 参考修改代码:
# 删掉原来的最后一层 Dense(28, activation='softmax'),替换为以下两层 model.add(Dense(2 * 28, activation='softmax')) model.add(Reshape((2, 28)))
- 损失函数仍使用
sparse_categorical_crossentropy即可,此时输出(bs,2,28)和标签(bs,2)维度完全匹配,可正常训练。
方案2:改为单标签分类任务
如果你的任务实际只需要一个28分类结果,直接对(1382,2)的标签做预处理即可:
- 任选其中一列标签作为训练目标,维度变为
(1382,),和现有模型输出结构匹配,即可直接用sparse_categorical_crossentropy训练 - 若两个标签都需要用到,也可以把两个标签组合为新的分类(总分类数为28*28=784),同步把输出层维度改为784即可。
内容的提问来源于stack exchange,提问作者Sharan Kumar
相关产品推荐
相关产品推荐

