【李沐 | 动手学深度学习】10-3 卷积层-多通道输入与输出

前面我们知道了卷积层与全连接的区别,并学习到其重要的两个超参数-填充与步幅,下面来学习另一个很重要的超参数-✨多个输入和输出的通道✨,它也是通常会很小心设置的一个超参数。

前言

我们知道彩色图像有RGB三个通道,而在前面的学习中涉及到的数据集FashionMnist中都是灰度图,只有黑白灰颜色-只有一个通道,因此相较于对于彩色图像,灰度图的处理更为简单一些。

假如处理的数据有多个通道,那卷积网络中如何处理呢?

1 多个输入通道

处理:每个通道都有一个卷积核,结果是所有通道卷积结果的和。

//实例:

如图,input为2通道,故有2个卷积核分别对应处理相应通道,将计算的结果相加得到output。

下面进行一般化,通过公式做个总结:

假设输入是一个三维的张量,对应的核也是三维,由于每个通道对应位置的结果相加,故输出是一个二维矩阵。

那从上面结果来看,无论有多少输入通道,最后输出的只是单通道-一个二维矩阵

2 多个输出通道

🙈单通道只能提取一类特征(比如边缘),而多输出通道可以让模型同时提取多种不同的特征(比如边缘、纹理、颜色梯度等),因此我们考虑是否输出也可以多个通道。

(卷积核的数量控制通道数——学习不同类型的数量)

处理方式:

张量维度表达含义
输入Xc_i \times n_h \times n_w输入有 c_{i} 个通道,每个通道是一张 n_{h}\times n_{w}​ 的特征图
卷积核Wc_o \times c_i \times k_h \times k_w一共有 c_{o}​ 个卷积核,每个核的维度是c_{i}\times k_{h}\times k_{w}(和输入通道数完全匹配)
输出Yc_o \times m_h \times m_w输出有 c_{o}​ 个通道,每个通道是一张 m_{h}\times m_{w}​ 的特征图

对于第 i 个输出通道,它是输入张量与第 i 个卷积核做完整的三位卷积得到的;

每个输出通道都由一个独立的卷积核生成,不同的核学习不同的特征模式。

\boldsymbol{Y}_{i,\dots} = \boldsymbol{X} \ast \boldsymbol{W}_{i,\dots,\dots} \quad \text{for } i=1,\dots,c_o

👀 为什么需要多通道输出?

(1) 每个输出通道识别一种特定模式

//实例:图里的小色块和条纹,就是输出通道学到的“特定模式”。

彩色小方块:负责识别图像中的颜斑点或局部颜色梯度;

斜线条纹:负责识别图像中的边缘纹理或方向线条。

灰色块:负责识别图像中的平滑区域或低频信息。

!!!每个输出通道都像一个“专项检测器”,只关注一种特定的视觉特征。

(2) 输入通道核识别并组合输入中的模式

  • 这里的“输入通道核”指的是卷积核的输入通道维度c_{i}
  • 当处理输入图像时,每个卷积核会遍历输入的所有通道,把不同通道里的模式(比如上图识别的6个通道的信息)组合起来,再生成一个输出通道。

最后来介绍一个特殊的卷积层。

3 1×1卷积层

  • 它也称为 point wise convolution,是卷积神经网络中非常重要的且常用的一种特殊卷积层。
  • 概念:卷积核尺寸为1×1,这意味着它只对每个像素点本身做运算,考虑其周围的空间邻域维度变化
  • 假设输入为c_i \times h \times w,使用c_o \times c_i \times 1 \times 1卷积核,则输出尺寸为c_o \times h \times w,空间尺寸完全不变,仅仅改变通道数!

🙉 下面是1×1卷积核的主要作用:

a) 通道数变换:可以通过改变卷积核的数量,任意调整输出通道数,从而减少或增加网络的通道维度(常用来降低计算量)

b) 跨通道的特征整合与交互:由于它会与所有输入通道在同一位置做加权求和,相当于把不同通道的特征在该位置进行融合,学习通道间的关联模式。

c) 引入非线性:在卷积后通常会接一个非线性激活函数,从而增加网络的表达能力,即使不改变通道数,也能让网络学习更复杂的特征。

d) 减少计算量:在Inception模块或ResNet等网络的残差块中,先用1×1卷积降维,再用3×3卷积提取空间特征,最后用1×1卷积升维。这种结构能大幅减少3×3卷积的计算量,让网络更高效。

//计算量对比示例:

  • 假设输入 H×W×256H×W×256,直接接 256 个 3×3 卷积核,输出 H×W×256H×W×256,
    参数量:3×3×256×256=5898243×3×256×256=589824(约 59 万)。

  • 如果先通过 64 个 1×1 卷积降维到 64 通道,再做 3×3 卷积升回 256 通道:

    • 1×1 卷积参数量:1×1×256×64=163841×1×256×64=16384

    • 3×3 卷积参数量:3×3×64×256=1474563×3×64×256=147456

    • 总参数量:约 16.4 万,大幅减少。

e) 代替全连接层进行通道加权:一些注意力模型(eg.SE-Net中的Squeeze-and-Excitation)用1×1卷积实现通道间的全连接,学习各通道的重要性权重。

1×1 卷积虽然不融合空间信息,但能高效实现通道间的信息整合与维度变换,是设计轻量、高效网络结构的关键组件,尤其在多分支网络和现代轻量级架构中不可或缺。

下面来看二维卷积层在通用情况下的模样。

4 二维卷积层

卷积的浮点运算数(FLOP)复杂度为:O\left(c_i c_o k_h k_w m_h m_w\right),其中:

c_i c_o k_h k_w:每个空间位置的计算量

m_h m_w:输出特征图的空间位置总数

//示例计算:

//示例:大规模场景下的算力需求

当网络扩展到10层,处理1M(百万)样本时,总计算量为:

0.1 GFLOP/层×10 层×1,000,000 样本=10,000 GFLOP=10 PFLOP,用不同设备来跑:

  • CPU(0.15 TFLOPS):约 18 小时;GPU(12 TFLOPS):约 14 分钟

——> GPU 是训练大模型的必备工具:在大规模场景下,GPU 比 CPU 效率高两个数量级以上。

代码实现

(1) 实现多输入通道互相关运算

corrr2d_multi_in:每个通道对应一个卷积核,其互相关运算结果求和得到输出。

import torch 

# 互相关运算(单通道)
def corr2d(X,K): 
    h, w = K.shape
    Y = torch.zeros(X.shape[0]-h+1,X.shape[1]-w+1)
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
           Y[i,j] = (X[i:i+h,j:j+w]*K).sum()
    return Y

# 多通道输入互相关运算
def corr2d_multi_in(X, K):
    return sum(corr2d(x, k) for x, k in zip(X, K))

验证相关运算的输出:

X:2×3×3;K:2×2×2——>一个输出通道

Y(1,1):(0.0*0.0+1.0*1.0+2.0*3.0+3.0*4.0)+(1.0*1.0+2.0*2.0+3.0*3.0+4.0*4.0)=56

# 验证相关运算的输出
X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],
               [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])
K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], [[1.0, 2.0], [3.0, 4.0]]])

corr2d_multi_in(X, K)

(2) 多通道输出互相关运算

原理:遍历K中每一维卷积核  k  对输入 X 处理得到单输出通道结果,从而得到多输出通道结果。

torch.stack():把多个形状完全相同的张量,在一个新的维度上“堆叠”起来,生成一个更高维度的张量。要注意的是,它不是像cat那样在现有维度上拼接,而是创建一个全新的维度来容纳这些输入张量。

# 多通道输出互相关运算
def corr2d_multi_in_out(X, K):
    return torch.stack([corr2d_multi_in(X, k) for k in K], 0)

此处:(K,K+1,K+2)生成了3组形状完全相同的卷积核,torch.stack(... , 0)在第0维堆叠这三组核,得到形状为 (3,c_i,k_h,k_w)的卷积核组,对应3组输出通道的卷积核集合。

K = torch.stack((K, K + 1, K + 2), 0)
K.shape

此处:3组卷积核对应3个通道输出

corr2d_multi_in_out(X, K)

(3) 验证1×1卷积等价于1个全连接

def corr2d_multi_in_out_1x1(X, K):
    c_i, h, w = X.shape            # 提取输入张量X的维度
    c_o = K.shape[0]               # 提取卷积核K的输出通道数
    X = X.reshape((c_i, h * w))    # 重塑X:把每个通道的h×w矩阵展平成一维向量,形状从 (c_i, h, w) → (c_i, h*w)
    K = K.reshape((c_o, c_i))      # 重塑K:把1×1卷积核展平成二维矩阵,形状从 (c_o, c_i, 1, 1) → (c_o, c_i) 
    # 全连接层中的矩阵乘法
    Y = torch.matmul(K, X)
    return Y.reshape((c_o, h, w))  # 重塑回卷积输出形状:从 (c_o, h*w) → (c_o, h, w)
# 生成输入张量X:形状(3,3,3),均值0、方差1的正态分布随机数
X = torch.normal(0, 1, (3, 3, 3))        
# 生成卷积核K:形状(2,3,1,1),均值0、方差1的正态分布随机数
K = torch.normal(0, 1, (2, 3, 1, 1))

# 验证等价性
Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
# 断言验证:两个结果的差值之和的绝对值小于1e-6(浮点精度误差范围内),说明矩阵乘法和卷积运算的结果几乎完全一致
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6

🌼核心原理:1×1卷积为什么等价于矩阵乘法?

1×1卷积的本质是跨通道的线性组合——它不改变特征图的空间尺寸(h和w),只对每个空间位置的所有输入通道做加权求和,得到输出通道的数值:

  • 对于特征图上的任意一个空间位置 (i,j),输入是 (c_i, 1, 1) 的向量,卷积核是(c_o, c_i, 1, 1) 的矩阵,卷积运算是c_o × c_i  的矩阵乘以c_i\times 1的向量,得到 c_o\times 1的输出;
  • 把所有空间位置的向量拼接成 c_i × (h\times w) 的矩阵,一次性做矩阵乘法,就等价于对所有空间位置逐点做 1×1 卷积,效率更高。

//维度变化示例:

# X:(3, 3, 3) 【原始输入:3通道,3×3特征图】→ reshape → (3, 9) 【每个通道展平成1行,共3行(9=3×3)】

# K:(2, 3, 1, 1) 【原始卷积核:2输出通道,3输入通道,1×1】→ reshape → (2, 3) 【2行(输出通道),3列(输入通道)】

# 矩阵乘法 (2, 3) × (3, 9) = (2, 9) 【2输出通道,9个空间位置】

# 最终重塑 (2, 9) → (2, 3, 3)        【还原为2通道,3×3特征图(和卷积输出一致)】

总结

本文介绍了卷积神经网络中重要的多通道处理机制。对于多输入通道,每个通道使用独立卷积核处理后相加得到单通道输出;多输出通道则通过多个卷积核同时提取不同特征;另外了解了1×1卷积具有特殊作用:既能调整通道数、跨通道特征整合,又能大幅降低计算量(通过先降维再升维)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔江seven

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值