超分辨率重建的核心目标是从低分辨率图像恢复出高分辨率细节,而网络结构中如何把特征图从低分辨率空间映射到高分辨率空间,是绕不开的设计决策。转置卷积作为一种可学习的上采样方式,在早期超分网络中扮演了重要角色,但它带来的棋盘伪影问题也让不少研究者转投其他方案。本文将系统梳理转置卷积的原理、实现细节,以及在超分任务中使用它的收益与代价。

转置卷积的原理与计算过程
转置卷积的名字容易引起误解,它并不是卷积的逆运算,而是卷积反向传播时梯度计算过程的正向化。普通卷积在 stride 大于 1 时会把输入尺寸压缩,而转置卷积则相反,通过在输入元素之间插入空洞(stride 充当输入端间隔),再用卷积核进行标准卷积,从而实现尺寸放大。
具体来说,假设输入尺寸为 H_in,卷积核大小为 k,步长为 s,填充为 p,输出边长满足 H_out = (H_in - 1) * s + k - 2 * p。以 stride=2、kernel=3、padding=1 为例,一个 4x4 的输入经过转置卷积后得到 8x8 的输出,正好完成两倍上采样。在 PyTorch 中对应的模块是 nn.ConvTranspose2d,在 TensorFlow 中则是 Conv2DTranspose。
import torch
import torch.nn as nn
# 定义一个两倍上采样的转置卷积
up = nn.ConvTranspose2d(
in_channels=64,
out_channels=64,
kernel_size=3,
stride=2,
padding=1,
# output_padding 用于补齐尺寸,保证输出刚好是输入的两倍
output_padding=1
)
x = torch.randn(1, 64, 24, 24) # 低分辨率特征图
y = up(x)
print(y.shape) # torch.Size([1, 64, 48, 48])值得注意的是 output_padding 这个参数,它只在输出的一侧补零,用来消除尺寸计算中的歧义。当 (H_in - 1) * s + k - 2p 的结果比期望输出小 1 时,就需要设置它。很多初学者在复现超分网络时发现输出尺寸总是差一个像素,多半是漏掉了这个参数。
转置卷积在超分中的优势
相比双线性或双三次插值这类固定的上采样方式,转置卷积最大的优势是可学习。插值算子没有任何参数,只能按照固定的权重组合对像素进行加权,而转置卷积的卷积核参数会随训练过程不断更新,理论上能够学到更适合当前数据分布的上采样模式。对于细节丰富的自然图像,这种自适应能力有助于恢复高频纹理。
第二个优势是位置灵活。在 SRCNN 这类早期方法中,上采样直接用插值完成,网络只在插值后的高分辨率空间做卷积,计算量随放大倍数平方增长。FSRCNN 则把转置卷积放在网络末端,先在低分辨率空间完成所有特征提取,最后一步才放大,整体计算量大幅下降。这种后置上采样的设计思路后来被广泛继承,亚像素卷积版本的 ESPCN 本质上也是这一框架的变体。
第三个优势是实现简单、部署兼容性好。转置卷积在各个推理框架中支持成熟,不依赖复杂的通道重排操作,量化导出时也很少出问题。在一些对部署环境有严格限制的嵌入式场景,这一点相当实用。
棋盘效应:转置卷积最大的坑
转置卷积最广为人知的问题就是棋盘伪影,输出图像上会出现明暗交替的网格状纹理。根源在于:当卷积核大小不能被步长整除时,不同输出位置被卷积核覆盖的次数不均匀。某些像素点会被多个核窗口的重叠区域覆盖多次,而相邻像素可能只被覆盖一次,重叠区域的不均匀加权在反传学习中被放大,最终形成周期性的伪影图案。
以 kernel=3、stride=2 为例,输出尺寸中每两个像素就有一处重叠覆盖,棋盘周期恰好为 2。实验上有一个经验规律:当 kernel 是 stride 的整数倍时(如 kernel=4 配 stride=2,或 kernel=2 配 stride=2),各输出位置的覆盖次数相同,棋盘效应会显著减弱甚至消失。代价是核大小受限,网络设计的自由度降低。
import torch.nn as nn
# 方案一:核大小整除步长,缓解棋盘效应
conv_a = nn.ConvTranspose2d(64, 3, kernel_size=4, stride=2, padding=1)
# 方案二:Resize-Conv,先插值再普通卷积,彻底规避棋盘
class ResizeConv(nn.Module):
def __init__(self, channels):
super().__init__()
self.up = nn.Upsample(scale_factor=2, mode='nearest')
self.conv = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
def forward(self, x):
return self.conv(self.up(x))Odena 等人在相关研究中系统验证了 Resize-Conv 方案的有效性:先用最近邻插值放大,再用标准卷积做特征变换,既避免了不均匀覆盖,又保留了卷积部分的可学习性。在超分任务中,这一组合的实际效果往往比直接用转置卷积更干净,尤其在高倍放大(x4、x8)时差距明显。
与亚像素卷积的对比及选型建议
超分领域目前更主流的上采样方案是 ESPCN 提出的亚像素卷积,也就是 PixelShuffle。它在低分辨率特征图上做普通卷积,把通道数扩展到放大倍数的平方倍,再通过通道重排折叠到空间维度。相比转置卷积,它没有空洞插入带来的稀疏计算,GPU 上的访存效率更高,也不天然携带棋盘问题。
两者各有取舍。亚像素卷积的重排操作在某些推理框架中支持不佳,量化部署时可能出现算子缺失;转置卷积的算子支持则普遍更完善。在训练数据充足的情况下,亚像素卷积的表征上限略高,而在小数据集或需要快速收敛的场景,两者差距并不显著。
实际的选型建议可以归纳为三点:第一,如果坚持使用转置卷积,优先选 kernel 能被 stride 整除的组合,并配合输出后的平滑卷积层抑制伪影;第二,如果部署环境对算子兼容性要求高,转置卷积仍是稳妥选择;第三,追求重建质量的学术场景,优先考虑 PixelShuffle 或 Resize-Conv,必要时在损失函数中加入感知损失和对抗损失,进一步压制网格状纹理。总之,转置卷积不是不能用,而是要在了解其缺陷成因的前提下,针对性地规避风险。