上采样方式——SubPixelConv 亚像素卷积

背景知识

  • 普通的上采样(Upsample)如双线性插值 ,是不可学习的。

  • 反卷积(Deconv/ConvTranspose)是可以学习的,但容易产生棋盘格伪影(Checkerboard Artifacts)。

  • SubPixelConv:出自论文 ESPCN。它的思路是:先在通道维度上把特征变多,然后把多出来的通道"重排"到空间维度上。

亚像素卷积 ( Sub-pixel convolution**)** 就是为了解决上述问题而生的:它既可学习 ,又高效 ,还能减少伪影

参考链接;https://blog.csdn.net/MR_kdcon/article/details/123837994

(强推,很详细)

ESPCN:Efficient Sub-Pixel Convolutional Neural Network(超分辨率)

亚像素卷积的核心思想:用通道换空间

假设我们想把一张特征图的长宽放大 r 倍(r 称为上采样因子,Upscaling Factor)。

1. 输入:一张尺寸为 (H,W),通道数为 C 的特征图。

2. 卷积扩维 (Convolution)

  • 使用一个标准的卷积层(Conv2d),不改变 H 和 W,但是把通道数从 C 变成了

  • 现在我们得到了一张"很厚"的特征图:(H,W,)。

3. 像素重排 (Pixel Shuffle)

  • 这就是核心的"洗牌"操作。

  • 我们将这 个通道里的像素取出来,按照一定的规律排列到空间维度上。

  • 具体来说,对于每个 (h,w) 位置,我们有 个像素值。我们将这 个值填入到一个 r×r 的小方格里。

4. 输出

  • 空间尺寸变大了:H 变成了 H×r,W 变成了 W×r。

  • 通道数变小了: 变成了 C。

  • 最终得到的高分辨率图。

python 复制代码
import torch
import torch.nn as nn
import torch.nn.functional as F

class SimpleSubPixelConv(nn.Module):
    def __init__(self, in_channels, out_channels, scale_factor=2, kernel_size=3):
        """
        Args:
            in_channels (int): 输入特征图的通道数
            out_channels (int): 输出特征图的通道数
            scale_factor (int): 上采样倍率 (例如 2 表示长宽各放大 2 倍)
            kernel_size (int): 卷积核大小,通常为 3
        """
        super().__init__()
        self.scale_factor = scale_factor
        
        # 【核心逻辑】
        # 为了在 Shuffle 后得到 out_channels 个通道,
        # 卷积层必须输出 out_channels * (scale_factor^2) 个通道。
        mid_channels = out_channels * (scale_factor ** 2)
        
        # 保持卷积前后 (H, W) 不变所需的 padding
        padding = (kernel_size - 1) // 2
        
        # 1. 卷积层:扩充通道
        self.conv = nn.Conv2d(
            in_channels=in_channels,
            out_channels=mid_channels,
            kernel_size=kernel_size,
            padding=padding
        )
        
        # 2. PixelShuffle 层:无需参数,只负责重排
        self.pixel_shuffle = nn.PixelShuffle(scale_factor)
        
        # 初始化权重 (ICNR 初始化对 PixelShuffle 效果最好,这里简单用 Kaiming)
        self._init_weights()

    def _init_weights(self):
        nn.init.kaiming_normal_(self.conv.weight, mode='fan_out', nonlinearity='relu')
        if self.conv.bias is not None:
            nn.init.constant_(self.conv.bias, 0)

    def forward(self, x):
        # x shape: (N, C_in, H, W)
        x = self.conv(x)  
        # x shape: (N, C_out * r^2, H, W)
        x = self.pixel_shuffle(x) 
        # x shape: (N, C_out, H*r, W*r)
        return x

# 测试一下
if __name__ == "__main__":
    layer = SimpleSubPixelConv(in_channels=64, out_channels=32, scale_factor=2)
    dummy_input = torch.randn(1, 64, 10, 10)
    output = layer(dummy_input)
    print(f"Input shape: {dummy_input.shape}")   # (1, 64, 10, 10)
    print(f"Output shape: {output.shape}")       # (1, 32, 20, 20) -> 尺寸翻倍,通道达标
相关推荐
Elastic 中国社区官方博客3 小时前
Elastic 线下 Meetup 将于 2026 年 7 月 26 号下午在深圳举行
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
独隅4 小时前
PyTorch自动微分模块:从原理到实战一
人工智能·pytorch·python
code_pgf4 小时前
ViT 与 MAE 在图像特征提取方面的优势详解
人工智能·stable diffusion
feifeigo1234 小时前
基于隐马尔可夫模型(HMM)的孤立词语音识别系统
人工智能·语音识别·xcode
weixin_468466854 小时前
千问大模型在阿里生态中的实战应用指南
大数据·人工智能·深度学习·ai·大模型·智能交互·自动应答
kTR2hD1qb4 小时前
Claude Code Skill的介绍与使用
java·前端·数据库·人工智能
qq_390934744 小时前
Cursor使用教程
人工智能
码农小白AI4 小时前
规范档案复核流程,IACheck+AI 报告审核满足资质监管要求
人工智能
Luhui Dev4 小时前
大角几何 MCP 服务上线:让 AI Agent 直接完成几何作图
人工智能·数学·机器学习·大角几何·luhuidev
纤纡.4 小时前
阿里云 DSW 实战:从零完成 Qwen3-4B 大模型 LoRA 微调全流程
人工智能·阿里云·语言模型·云计算