优先用nn.Upsample——插值模式可控、无棋盘伪影且不增参数;ConvTranspose2d易因配置不当产生网格效应,需严格设kernel_size=4、stride=2、padding=1、output_padding=0。

PyTorch里用torch.nn.Upsample还是nn.ConvTranspose2d做上采样?
超分辨率模型的核心是上采样,但选错层会直接导致伪影或训练不收敛。默认用nn.Upsample(双线性/双三次插值)更安全——它不引入可学习参数,能稳定初始化,适合ESRGAN、EDSR这类先插值再精修的结构。而nn.ConvTranspose2d虽可学习,但容易产生棋盘效应(checkerboard artifacts),尤其在步长=2时;若要用,必须搭配output_padding=0和stride=2严格对齐输出尺寸,且建议后续接nn.PixelShuffle替代。
如何让nn.PixelShuffle不报RuntimeError: Invalid channel size?
这是最常踩的坑:nn.PixelShuffle(upscale_factor)要求输入通道数必须能被upscale_factor**2整除。比如想4倍超分(upscale_factor=4),输入通道就必须是16的倍数(如64、128)。常见错误是主干网络输出通道没对齐,例如ResNet块后直接接PixelShuffle却忘了调整最后一层Conv2d的out_channels。解决方法:
- 检查上采样前的
Conv2d输出通道:设为upscale_factor ** 2 * n_channels(n_channels通常为3) - 确认输入张量形状:
[B, C, H, W]中C % (upscale_factor**2) == 0 - 调试时打印
x.shape,别只信网络定义
训练时torch.cuda.amp自动混合精度为什么会让PSNR崩掉?
混合精度训练(torch.cuda.amp)在超分任务中容易出问题,因为PSNR计算依赖浮点精度,而autocast可能把torch.float32的标签图(ground truth)转成float16参与loss计算,导致梯度噪声放大。现象是验证PSNR震荡剧烈、收敛变慢甚至下降。关键对策:
- loss计算前强制用
.float():如loss = criterion(pred.float(), target.float()) - PSNR评估阶段禁用
autocast,用with torch.no_grad():包裹并显式转float32 - 避免在
autocast上下文中做图像归一化/反归一化操作
加载预训练权重时load_state_dict报Missing key(s) in state_dict怎么办?
开源模型(如EDSR官方权重)常带model.前缀,而你定义的网络没有。直接model.load_state_dict(...)必然失败。别删键名重写dict——用state_dict = {k.replace("model.", ""): v for k, v in state_dict.items()}即可。更稳妥的做法是用strict=False并检查缺失项:
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
立即学习“Python免费学习笔记(深入)”;
model.load_state_dict(state_dict, strict=False) # 然后print缺失的key,确认只是"model."前缀而非结构不匹配
另外注意:如果模型用了nn.DataParallel保存,key会带module.前缀,需同样清洗;单卡加载多卡权重时漏这步,连第一个卷积层都加载不上。
超分辨率模型的细节陷阱基本都在数据流路径上:上采样方式决定伪影有无,通道数对齐决定能否跑通,精度控制影响指标可信度,权重加载方式决定能不能复现结果。这些地方一松懈,模型可能全程在拟合噪声。

















