之前我们用到的输入和输出都是二维数组,但真实数据的维度经常更高。例如,彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。假设彩色图像的高和宽分别是h和w(像素),那么它可以表示为一个3×h×w的多维数组。我们将大小为3的这一维称为通道(channel)维。本文我们将介绍含多个输入通道或多个输出通道的卷积核。
1 多输入通道–单输出通道
接下来我们实现含多个输入通道的互相关运算。我们只需要对每个通道做互相关运算,然后通过add_n
函数进行累加。
import torch from torch import nn import sys 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): # 计算多个通道 # 沿着X和K的第0维(通道维)分别计算再相加 res = corr2d(X[0, :, :], K[0, :, :]) for i in range(1, X.shape[0]): res += corr2d(X[i, :, :], K[i, :, :]) return res
我们可以构造图1中的输入数组X
、核数组K
来验证互相关运算的输出。
X = torch.tensor([[[0, 1, 2], [3, 4, 5], [6, 7, 8]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]]]) K = torch.tensor([[[0, 1], [2, 3]], [[1, 2], [3, 4]]]) corr2d_multi_in(X, K)
输出:
tensor([[ 56., 72.], [104., 120.]])
2 多输出通道
上面一节中,输入通道有多个时,因为我们对各个通道的结果做了累加,所以不论输入通道数是多少,输出通道数总是为1。设卷积核输入通道数和输出通道数分别为ci和co,高和宽分别为kh和kw。如果希望得到含多个通道的输出,我们可以为每个输出通道分别创建形状为ci×kh×kw的核数组。将它们在输出通道维上连结,卷积核的形状即co×ci×kh×kw。在做互相关运算时,每个输出通道上的结果由卷积核在该输出通道上的核数组与整个输入数组计算而来。
下面我们实现一个互相关运算函数来计算多个通道的输出。
def corr2d_multi_in_out(X, K): # 对K的第0维遍历,每次同输入X做互相关计算。所有结果使用stack函数合并在一起 return torch.stack([corr2d_multi_in(X, k) for k in K])
我们将核数组K
同K+1
(K
中每个元素加一)和K+2
连结在一起来构造一个输出通道数为3的卷积核。
K = torch.stack([K, K + 1, K + 2]) K.shape # torch.Size([3, 2, 2, 2])
下面我们对输入数组X
与核数组K
做互相关运算。此时的输出含有3个通道。其中第一个通道的结果与之前输入数组X
与多输入通道、单输出通道核的计算结果一致。
corr2d_multi_in_out(X, K)
输出:
tensor([[[ 56., 72.], [104., 120.]], [[ 76., 100.], [148., 172.]], [[ 96., 128.], [192., 224.]]])
3 1 × 1 1\times 11×1卷积层
1×1卷积层即卷积窗口形状为1×1(kh=kw=1)的多通道卷积层,将其中的卷积运算称为1×1卷积。因为使用了最小窗口,1×1卷积失去了卷积层可以识别高和宽维度上相邻元素构成的模式的功能。实际上,1×1卷积的主要计算发生在通道维上。图2展示了使用输入通道数为3、输出通道数为2的1×1卷积核的互相关计算。此时,输入和输出具有相同的高和宽。输出中的每个元素来自输入中在高和宽上相同位置的元素在不同通道之间的按权重累加。假设我们将通道维当作特征维,将高和宽维度上的元素当成数据样本,那么1×1卷积层的作用与全连接层等价。
下面我们使用全连接层中的矩阵乘法来实现1×1卷积。这里需要在矩阵乘法运算前后对数据形状做一些调整。
def corr2d_multi_in_out_1x1(X, K): c_i, h, w = X.shape c_o = K.shape[0] X = X.view(c_i, h * w) K = K.view(c_o, c_i) Y = torch.mm(K, X) # 全连接层的矩阵乘法 return Y.view(c_o, h, w)
经验证,做1 × 1 1\times 11×1卷积时,以上函数与之前实现的互相关运算函数corr2d_multi_in_out
等价。
X = torch.rand(3, 3, 3) K = torch.rand(2, 3, 1, 1) Y1 = corr2d_multi_in_out_1x1(X, K) Y2 = corr2d_multi_in_out(X, K) (Y1 - Y2).norm().item() < 1e-6
输出:
True
在之后的模型里我们将会看到1×1卷积层被当作保持高和宽维度形状不变的全连接层使用。于是,我们可以通过调整网络层之间的通道数来控制模型复杂度。
总结
- 使用多通道可以拓展卷积层的模型参数。
- 假设将通道维当作特征维,将高和宽维度上的元素当成数据样本,那么1×1卷积层的作用与全连接层等价。
- 1×1卷积层通常用来调整网络层之间的通道数,并控制模型复杂度。