You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CNN人群计数模型中ConvTranspose2d引发输入与权重张量类型不匹配问题排查

问题原因与解决方案

这个错误的核心原因很明确:你的输入张量(真实数据)已经被放到GPU上了(类型是torch.cuda.FloatTensor),但你在forward方法里临时创建的ConvTranspose2d层的权重还停留在CPU上(类型是torch.FloatTensor),两者设备不匹配导致了类型冲突。

为什么虚拟张量测试没问题?

你测试用的虚拟张量大概率是在CPU上生成的,这时候临时创建的upsample层默认也在CPU,输入和权重的设备一致,所以不会报错。但真实数据处理时,你应该是把整个模型和输入数据都移到了GPU(比如用model.cuda()或model.to('cuda')),但这个临时创建的上采样层并没有同步移过去,就出现了类型不匹配。

修复方案

有两种简单的解决方式,推荐第一种更规范的写法:

方案1:将上采样层移到模型初始化阶段

把ConvTranspose2d的创建放到模型的__init__方法里,这样它会和其他层一起被移到GPU,避免每次forward都重新创建:

修改你的模型初始化代码:

class YourCrowdCountModel(nn.Module):
    def __init__(self, bn=True):
        super().__init__()
        # 原有的所有层定义...
        self.base = nn.Sequential(Conv2d(1, 64 ,3, same_padding=True, bn=bn), ...)
        self.layer1_1 = nn.Sequential(nn.MaxPool2d(2), ...)
        # ...其他层定义...
        
        # 添加这行,把上采样层作为模型的一部分
        self.upsample = nn.ConvTranspose2d(256, 256, 3, stride=2, padding=1)

然后修改forward方法里的对应代码:

def forward(self, im_data):
    # 原有的前向传播逻辑...
    fuse_l3 = self.fuse_layer3(l3_1.add(l3_2).add(l3_3))
    # 使用模型初始化好的上采样层
    fuse_l3 = self.upsample(fuse_l3, output_size = fuse_l2.size())
    # ...后续拼接与返回逻辑...

方案2:临时创建后手动同步设备

如果一定要在forward里动态创建上采样层,那需要在创建后马上把它移到输入张量所在的设备上:

def forward(self, im_data):
    # 原有的前向传播逻辑...
    fuse_l3 = self.fuse_layer3(l3_1.add(l3_2).add(l3_3))
    upsample = nn.ConvTranspose2d(256, 256, 3, stride=2, padding=1)
    # 同步到fuse_l3所在的设备(和im_data设备一致)
    upsample = upsample.to(fuse_l3.device)
    fuse_l3 = upsample(fuse_l3, output_size = fuse_l2.size())
    # ...后续拼接与返回逻辑...

额外提示

尽量不要在forward方法里频繁创建层,这样不仅会导致设备同步问题,还会增加不必要的开销,影响训练/推理效率。把所有固定结构的层都放到__init__里是PyTorch模型的标准写法。

内容的提问来源于stack exchange,提问作者eloreah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:07:30