PyTorch卷积网络报矩阵形状不匹配(128x4与128x64无法相乘)问题
问题排查结果
报错的核心原因是两处代码写法错误,导致卷积输出形状完全偏离设计预期:
- 输入张量缺少batch维度,维度顺序不符合PyTorch Conv2d层的输入要求
- Flatten层后的全连接层输入尺寸写死为128,和实际卷积输出展平长度不匹配
错误推导过程
你打印的初始state1形状为torch.Size([2, 12, 12]),是3维的(通道数, 高度, 宽度)格式,但PyTorch的Conv2d层要求输入必须是4维的(batch_size, 通道数, 高度, 宽度)格式。传入3维张量时,模型不会自动补batch维度,会直接将第0维的通道数2误判为batch维度,后续所有卷积、池化层的输出尺寸都会连锁出错:
三层卷积+池化处理完3维输入后,输出为3维张量(128, 2, 2),经过默认参数的Flatten()(从第1维开始展平,保留第0维)后,输出形状变成128x4,刚好和报错里的mat1形状一致。此时你接的第一个全连接层Linear(128,64)的权重形状为128x64,矩阵乘法要求前一个矩阵的列数等于后一个矩阵的行数,两边维度不匹配直接抛出错误。
正确尺寸计算
如果输入是符合要求的单样本4维张量,形状为(1, 2, 12, 12)(batch=1,2通道,12x12尺寸),经过各层的输出尺寸如下:
- Conv2d(2,32,3,padding=1) + ReLU + MaxPool2d(2,2):输出形状
(1, 32, 6, 6) - Conv2d(32,64,3,padding=1) + ReLU + MaxPool2d(2,2):输出形状
(1, 64, 3, 3) - Conv2d(64,128,3,padding=1) + ReLU + MaxPool2d(2,2,padding=1):输出形状
(1, 128, 2, 2) - Flatten():展平后形状为
(1, 128*2*2) = (1, 512)
修复方法
- 修正所有输入的reshape逻辑,统一转成4维
(batch, 通道, 高, 宽)格式,不要把空间、通道维度展平成1维:- 初始state1生成代码改为:
state_ = game.board.render_np().reshape(1,2,size,size) + np.random.rand(1,2,size,size)/10.0- 后续state2生成、传入模型前的reshape也统一改成
reshape(1,2,size,size),删掉原来用l1展平的写法。
- 修正全连接层输入尺寸,把模型里的
torch.nn.Linear(128, 64)改成torch.nn.Linear(512, 64)。
修正后模型定义参考:
model = torch.nn.Sequential( torch.nn.Conv2d(2,32,kernel_size=3,padding=1), torch.nn.ReLU(), torch.nn.MaxPool2d(2,2), torch.nn.Conv2d(32,64,kernel_size=3,padding=1), torch.nn.ReLU(), torch.nn.MaxPool2d(2,2), torch.nn.Conv2d(64,128,kernel_size=3,padding=1), torch.nn.ReLU(), torch.nn.MaxPool2d(2,2,padding=1), torch.nn.Flatten(), torch.nn.Linear(512, 64), torch.nn.ReLU(), torch.nn.Linear(64,4) )
提示:如果后续调整输入图片尺寸,不要硬写全连接层输入长度,可以先传一个随机生成的符合形状的张量跑一遍卷积块,打印Flatten后的输出尺寸,再填对应全连接层的参数,避免算错。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

