多输入通道

彩色图像可能有 RGB 三个通道,转换为单通道的灰度图像会丢失信息

当输入包含多个通道时,构造一个与输入数据具有相同输入通道数的卷积核,结果是所有通道卷积结果的和

Untitled

(1×1+2×2+4×3+5×4)+(0×0+1×1+3×2+4×3)=56(1 \times 1+2 \times 2+4 \times 3+5 \times 4)+(0 \times 0+1 \times 1+3 \times 2+4 \times 3)=56

输入 X:ci×nh×nw\mathbf{X}: c_{i} \times n_{h} \times n_{w}

W:ci×kh×kw\mathbf{W}: c_{i} \times k_{h} \times k_{w}

输出 Y:mh×mw\mathbf{Y}: m_{h} \times m_{w}

Y=i=0ciXi,:,:Wi,:,:\mathbf{Y}=\sum_{i=0}^{c_{i}} \mathbf{X}_{i,:,:} \star \mathbf{W}_{i,:,:}

多输出通道

目前为止,不论有多少输入通道,还只有一个输出通道

可以有多个三维卷积核,每个核生成一个输出通道

输入 X:ci×nh×nw\mathbf{X}: c_{i} \times n_{h} \times n_{w}

W:co×ci×kh×kw\mathbf{W}: c_{o}\times c_{i} \times k_{h} \times k_{w}

输出 Y:co×mh×mw\mathbf{Y}: c_{o}\times m_{h} \times m_{w}

Yi,:,:=XWi,:,:,: for i=1,,co\mathbf{Y}_{i,:,:}=\mathbf{X} \star \mathbf{W}_{i,:,:,:} \quad \text { for } i=1, \ldots, c_{o}

每个输出通道可以识别特定模式

Untitled

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

1×11\times1 卷积层

kh=kw=1k_h=k_w=1 的卷积层不识别空间模式,只是融合通道

Untitled

相当于输入形状为 nhnw×cin_hn_w\times c_i,权重为 co×cic_o\times c_i 的全连接层

总结

  • 多输入多输出通道可以用来扩展卷积层的模型
  • 输出通道数是卷积层的超参数
  • 每个输入通道有独立的二维卷积核,所有通道结果相加得到一个输出通道的结果
  • 每个输出通道有独立的三维卷积核
  • 当以每像素为基础应用时,1×1 卷积层相当于全连接层
  • 1×1 卷积层通常用于调整网络层的通道数量和控制模型复杂性

代码实现

实现一下多输入通道互相关运算

1
2
3
4
5
6
import torch
from d2l import torch as d2l

def corr2d_multi_in(X, K):
# 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起
return sum(d2l.corr2d(x, k) for x, k in zip(X, K))

验证互相关运算的输出

1
2
3
4
5
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)
1
2
tensor([[ 56.,  72.],
[104., 120.]])

计算多个通道的输出的互相关函数

1
2
3
4
5
6
7
def corr2d_multi_in_out(X, K):
# 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。
# 最后将所有结果都叠加在一起
return torch.stack([corr2d_multi_in(X, k) for k in K], 0)

K = torch.stack((K, K + 1, K + 2), 0)
K.shape
1
torch.Size([3, 2, 2, 2])
1
corr2d_multi_in_out(X, K)
1
2
3
4
5
6
7
8
tensor([[[ 56.,  72.],
[104., 120.]],

[[ 76., 100.],
[148., 172.]],

[[ 96., 128.],
[192., 224.]]])

1x1卷积

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def corr2d_multi_in_out_1x1(X, K):
c_i, h, w = X.shape
c_o = K.shape[0]
X = X.reshape((c_i, h * w))
K = K.reshape((c_o, c_i))
# 全连接层中的矩阵乘法
Y = torch.matmul(K, X)
return Y.reshape((c_o, h, w))

X = torch.normal(0, 1, (3, 3, 3))
K = torch.normal(0, 1, (2, 3, 1, 1))

Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6