动手学深度学习09:多输入多输出通道
当我们添加通道时,我们的输入和隐藏的表示都变成了三维张量。例如,每个RGB输入图像具有3×h×w3\times h\times w3×h×w的形状。我们将这个大小为333的轴称为通道(channel)维度。
多输入通道
当输入包含多个通道时,需要构造一个与输入数据具有相同输入通道数的卷积核,以便与输入数据进行互相关运算。
当ci>1c_i>1ci>1时,我们卷积核的每个输入通道将包含形状为kh×kwk_h\times k_wkh×kw的张量。将这些张量cic_ici连结在一起可以得到形状为ci×kh×kwc_i\times k_h\times k_wci×kh×kw的卷积核。由于输入和卷积核都有cic_ici个通道,我们可以对每个通道输入的二维张量和卷积核的二维张量进行互相关运算,再对通道求和(将cic_ici的结果相加)得到二维张量。这是多通道输入和多输入通道卷积核之间进行二维互相关运算的结果。
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))
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]]])
print(corr2d_multi_in(X, K))
多输出通道
直观地说,我们可以将每个通道看作对不同特征的响应。
用cic_ici和coc_oco分别表示输入和输出通道的数目,并让khk_hkh和kwk_wkw为卷积核的高度和宽度。为了获得多个通道的输出,我们可以为每个输出通道创建一个形状为ci×kh×kwc_i\times k_h\times k_wci×kh×kw的卷积核张量,这样卷积核的形状是co×ci×kh×kwc_o\times c_i\times k_h\times k_wco×ci×kh×kw。在互相关运算中,每个输出通道先获取所有输入通道,再以对应该输出通道的卷积核计算出结果。
import torch
from d2l import torch as d2l
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]]])
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 # 3*2*2*2
print(corr2d_multi_in_out(X, K))
1×1 卷积层
我们可以将1×11\times 11×1卷积层看作在每个像素位置应用的全连接层,以cic_ici个输入值转换为coc_oco个输出值。
import torch
from d2l import torch as d2l
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))
小结
- 多输入多输出通道可以用来扩展卷积层的模型。
- 当以每像素为基础应用时,1×11\times 11×1卷积层相当于全连接层。
- 1×11\times 11×1卷积层通常用于调整网络层的通道数量和控制模型复杂