最近在跑一个简单的CNN做图像分类,输入是64x64的RGB图,batch size设了32。网络结构就是conv+pool+fc,最后一层fc我算过应该输出128维,然后接一个Linear(128, 10)。但一跑训练就报错:size mismatch for fc2.weight: copying a param with shape torch.Size([64, 128]) from checkpoint, but the checkpoint has torch.Size([32, 128])。
我明明记得模型定义里是128输入到10输出,怎么加载权重时它说期望64?检查了state_dict的key和形状,发现是保存模型时把fc2写错了,但代码里没改过啊……是不是我哪里对nn.Sequential的索引理解有误?求指点,网上搜了一圈全是英文,看得头疼。
用PyTorch训练时报错shape不匹配,但自查逻辑没问题,大佬们帮看看?
全部回复
共 45 条你这个报错信息里其实已经写得很清楚了,checkpoint里存的是[32,128],但模型加载时想要的是[64,128],所以问题大概率不是模型定义,而是你保存权重时用的batch size是32,加载时却用了64。我也经常踩这种坑,建议你在保存模型时别直接用state_dict,而是把整个模型结构一起存下来,或者检查一下是不是哪里不小心改了fc层的输入维度。另外可以打印一下模型每一层的shape对比下,十有八九是前面卷积或者pool的输出尺寸算错了,导致fc输入不是128而是64。
看这个报错信息,感觉问题可能不在模型定义上,而是出在加载checkpoint的方式上。你是不是用了什么预训练权重或者保存过多次模型?报错里说fc2.weight期望是[64,128]但checkpoint里是[32,128],这明显是checkpoint里的参数和你当前模型的结构对不上,可能你保存模型的时候batch size是32,但加载时模型里fc2的输入维度被改成了64?建议直接打印一下你加载的state_dict里每个key的shape,和你当前模型的一一比对,多半能找到是哪一层定义错了。另外如果用的是官方预训练权重,记得看下他们用的输入尺寸是不是和你一样是64x64,说不定人家默认是224x224。
这报错摆明是checkpoint和模型结构对不上,你是不是保存权重前改过网络,或者加载时没建对模型?
这报错信息其实已经说得挺清楚了,checkpoint里存的fc2权重是[32,128],但你模型现在加载时期望的是[64,128]。也就是说要么你保存权重时的模型结构和现在不完全一样,要么中间改过fc层的输入维度,比如pool之后没展平直接接了fc,导致实际输入是64而不是你手算的128。建议你在加载checkpoint前先print一下当前模型的fc2.weight.shape,再对比一下保存时的状态字典,大概率能找到差异。我之前也踩过类似的坑,多半是模型定义里某个卷积层的padding或stride改了一下,后面全连接输入维度就全变了。
可能是之前保存的模型结构和现在定义的不一致,建议打印下当前模型的fc层尺寸和checkpoint里的对比下。