PyTorch下BERT调用model(**inputs)出现Target size不匹配错误如何解决
问题原因
这个报错是因为BERT分类模型输出维度和传入的标签维度不匹配:
- 模型输出维度是
[32, 3],对应32个样本、每个样本输出3个类别的预测结果 - 传入的
labels维度是[32],和模型内部损失函数要求的输入维度不一致。Hugging Face的Transformers模型传入labels参数时会自动计算损失,所以报错出现在outputs = model(**inputs)这一步,而非你手动写损失计算的环节。
解决方案
任选以下两种方案中的一种即可,注意不要同时混用:
方案1:使用交叉熵损失(推荐,适合普通多分类任务)
交叉熵损失不需要传入独热编码的标签,仅需传入类别的整数索引,操作步骤:
- 删掉独热编码相关代码,把标签恢复为一维整数格式(例如
[0,2,2,1,0,2...],每个值对应3个类别中的一个) - 初始化BERT分类模型时,确保
num_labels参数设置为3,示例:
from transformers import BertForSequenceClassification model = BertForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=3)
- 直接传入一维标签即可,模型内部默认使用交叉熵损失,会自动适配
[32]维度的标签和[32,3]维度的预测输出。
方案2:使用二分类交叉熵损失(需独热标签)
如果你坚持使用独热编码的标签,需要修改损失函数配置,操作步骤:
- 保留现有的独热编码代码,注意将独热编码后的标签正确赋值到
batch[2]的位置,此前修改后仍报错大概率是没有把独热后的结果同步到加载的batch数据中。 - 初始化模型时除了设置
num_labels=3,还要指定问题类型为多标签分类,让模型内部调用BCELoss:
model = BertForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=3, problem_type="multi_label_classification")
- 传入的独热标签要转为float类型,和损失函数要求的输入格式匹配。
额外排查点
如果修改后仍然报错,检查你的DataLoader返回的batch[2]是否和你处理后的标签格式一致,避免出现已经处理了训练集标签,但加载数据时还是调用了原始标签的问题。
内容的提问来源于stack exchange,提问作者Jeff Jefferson
相关产品推荐
相关产品推荐

