微调Huggingface预训练RoBERTa做文本摘要出现batch size不匹配报错求解
错误原因与解决方案
1. 直接触发报错的原因:损失函数参数顺序错误
PyTorch中CrossEntropyLoss的调用规则是cross_entropy_loss(模型输出, 标签),你代码里写的是crossent_loss = self.cross_entropy_loss(labels, output),两个参数顺序完全颠倒,才会触发batch size不匹配的报错。
2. 核心逻辑错误:维度处理完全混乱
你当前的张量维度流转完全不符合预期:
- Roberta输出的
last_hidden_state形状为(batch_size, 文本seq_len, hidden_size),你的batch_size=20,文本seq_len=200,roberta-base的hidden_size=768,所以输出是(20, 200, 768) - 你直接调用
torch.unsqueeze(x, 0)把张量变成(1, 20, 200, 768),又把卷积层的in_channels设为20,相当于错误把batch维度当成了通道维度处理 - 后续调用
flatten()直接把整个batch的所有特征压成一维张量,全连接层输出维度为50,最终得到的输出是长度为50的一维张量,而你的标签形状是(20, 50)(20个样本,每个对应50个摘要token),二者形状完全不匹配
3. 方案选型错误:损失函数和任务不匹配
- 摘要生成是序列预测任务,每个位置要预测对应的token id(属于分类任务,类别数等于词表大小),完全不需要把long类型的标签归一化到0~1做回归
- CrossEntropyLoss适用于分类任务,要求模型输出的最后一维是类别数,你当前把全连接层输出设为50,根本无法对应词表大小的分类需求
调整建议
- 把卷积层的
in_channels改为1,拿到roberta输出后在第二维(即特征维度)做升维,对应x = torch.unsqueeze(x, 1),把形状变成(20, 1, 200, 768),符合卷积层(batch_size, channels, height, width)的输入要求 - 去掉
flatten()调用,调整全连接层的输入输出维度,让最终输出形状为(batch_size, 摘要seq_len, 词表大小),对应每个样本每个摘要位置的分类结果 - 损失函数参数顺序调整为
crossent_loss = self.cross_entropy_loss(output.permute(0,2,1), labels),标签保留long类型的token id,不要做归一化处理
内容的提问来源于stack exchange,提问作者rana
相关产品推荐
相关产品推荐

