使用TPSSpatialTransformerNetwork训练IAM数据集出现shape不匹配报错
问题根因分析
报错直接来自stn函数第43行的theta.view(-1, 2, 4,28)操作,核心原因是张量形状不匹配,且存在逻辑混淆问题:
- 你前面计算localization输出的
79*4*28维度是对的,输入为(32,128)的图片经过两层卷积+池化后,输出特征的高为4、宽为28,这部分没有问题。 - 你定义的
fc_loc最后一层输出维度是3*2=6,对应普通2D仿射变换的参数数量,因此单样本theta的总元素数是6。假设你当前batch size为128,总元素数就是128*6=768,和报错提示的输入大小一致。 - 你指定的目标形状
[-1,2,4,28]单样本维度乘积为2428=224,768无法被224整除,因此触发形状错误。 - 同时你混淆了普通仿射STN和TPS STN的实现逻辑:当前你用的
F.affine_grid是普通仿射变换的API,要求输入theta的形状为[batch_size, 2, 3],和你写的2428的形状完全不匹配。
修复方案
方案1:先调试普通仿射STN(最小改动修复当前报错)
需要修改两处错误:
- 修正theta的形状转换逻辑,将
stn函数中的theta = theta.view(-1, 2, 4,28)替换为:
theta = theta.view(-1, 2, 3)
- 修正forward函数中展平操作的硬编码维度,你硬写的
320和实际卷积输出维度不符,会触发后续报错,替换为自动推导展平维度的写法:
x = x.view(x.size(0), -1)
方案2:实现TPS版本的STN
如果你的目标是用TPS变换而非普通仿射变换,需要做更多调整:
- 先确定TPS的控制点数量K,比如常用的K=20,将
fc_loc最后一层输出维度改为2*K(每个控制点对应x、y两个坐标参数) - 替换
F.affine_grid为自定义的TPS网格生成逻辑,根据预测的控制点坐标计算采样网格,再调用F.grid_sample完成变换 - 对应调整theta的形状转换逻辑,匹配你定义的控制点参数维度
内容的提问来源于stack exchange,提问作者Quynh Anh Pham
相关产品推荐
相关产品推荐

