CNN卷积层的多输入多输出

2022-09-04  本文已影响0人  小黄不头秃

(一)多输入多输出

(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
    
上一篇下一篇

猜你喜欢

热点阅读