(一)多输入多输出
(1)多输入通道
彩色图像一般是由RGB三个通道组成的。彩色图片一般会有更加丰富的信息。
转变为灰度图像会将信息丢失。
如果有多个通道,每一个通道都有一个卷积核,结果是所有通道卷积结果的和。
(2)多输出通道
无论有多少通道的输入,如果我们希望输出是多维的该怎么办呢?做法是设置多个三维的卷积核,每一个卷积核计算出来的结果作为一个通道。输出通道数,即卷积核的个数是卷积层的另一个超参数。
那为什么要这么做呢?我们可以认为每一个通道识别出来的都是一些特殊的模式。
(3)1*1卷积核
(1,1)的卷积核是一个常用的卷积核,它并不能识别空间信息,它的作用是融合通道。
(二)代码实现
import torch
from d2l import torch as d2l
def corr2d_multi_in(X, K):
return sum(d2l.corr2d(x, k) for x,k in zip(X,K))
# 这是多通道输入(2,3,3),单通道输出(2,2),两个核(2,2)
# 一个核对应一个通道
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)
# 计算多个通道的输入输出
def corr2d_multi_in_out(X,K):
# 现在一个核有多个通道,每一个核的形状是(2, 2, 2),共有三个核(3,2,2,2)
# 一个卷积核经过一次操作后会得到单通道的输出(2,2)
# 下面这个操作就是让每一个卷积核得到的一个通道的输出,堆叠起来。(3,2,2)
return torch.stack([corr2d_multi_in(X,k) for k in K])
# 创建三个卷积核
K = torch.stack((K, K + 1, K + 2), 0)
print(type(K))
# print(K.shape)
corr2d_multi_in_out(X,K)
# 1*1的卷积核
def corr2d_multi_in_out_1x1(X, K):
c_i,h,w = X.shape
c_o = K.shape[0]
# 这里就是将一张图片的高和宽展平成一条直线(3, 3, 3) => (3,9)
# 剩下(channel_num,input)
X = X.reshape((c_i,h*w))
# 把卷积核的高和宽展平成一条直线(2, 3, 1, 1) => (2,3)
# 剩下(kernel_num, kernnel)
K = K.reshape((c_o,c_i))
Y = torch.matmul(K,X)
print(X.shape,K.shape,Y.shape)
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
网友评论