SimCLR/ResNet18微调CrossEntropyLoss维度不匹配错误求助
问题排查与解决方案
一、修复标签(target)形状错误
- 问题根源:你的target被错误传入了图像张量而非标签张量,导致形状变成
[batch_size,3,224,224],而CrossEntropyLoss要求target是0D(单样本)或1D(批量,形状[batch_size])的类别索引。 - 排查与修复:
- 检查数据加载器(DataLoader)的返回逻辑,确保每个batch返回的是
(images, labels),而非误将对比学习任务中的配对图像当成标签。 - 微调代码中明确提取标签,示例:
for images, labels in val_dataloader: # 确认labels形状为[70],而非图像维度 outputs = model(images) loss = criterion(outputs, labels)
- 检查数据加载器(DataLoader)的返回逻辑,确保每个batch返回的是
二、修正模型输出维度适配二分类任务
- 问题根源:当前模型最后一层输出维度为10,但你是二分类任务,需要输出维度为2。这是因为预训练阶段的SimCLR/ResNet18最后一层是适配 pretext任务的投影头或分类头,未替换为二分类层。
- 排查与修复:
- 加载预训练checkpoint后,替换模型的最后全连接层为二分类输出:
import torch import torchvision.models as models # 加载预训练的ResNet18 model = models.resnet18() model.load_state_dict(torch.load("pretext_checkpoint.pth")) # ResNet18默认fc层输入特征数为512,替换为输出2类 model.fc = torch.nn.Linear(512, 2) - 如果是SimCLR封装的模型,需去掉投影头,替换为分类头:
# 假设SimCLR模型结构为backbone + projection_head model = SimCLRModel(backbone=models.resnet18(), projection_dim=128) model.load_state_dict(torch.load("simclr_pretext.pth")) # 保留backbone,添加二分类头 model = torch.nn.Sequential( model.backbone, torch.nn.Linear(512, 2) )
- 加载预训练checkpoint后,替换模型的最后全连接层为二分类输出:
验证步骤
修复后,运行单batch前向传播,确认:
outputs.shape为[batch_size, 2](如torch.Size([70,2]))labels.shape为[batch_size](如torch.Size([70]))- 损失计算不再触发RuntimeError
内容的提问来源于stack exchange,提问作者Willy Lutz
相关产品推荐
相关产品推荐

