(pytorch-深度学习系列)CNN的多输入通道和多输出通道

CNN的多输入通道和多输出通道

之前的输入都视为二维数组,但是真实数据往往具有更高的维度,彩色图像有RGB三个颜色通道,那么这个图像(高为h,宽为w)可以表示为 3 ∗ h ∗ w 3*h*w 3hw的多维数组,一般将表示通道数的维(即3这一维)称为通道维

多输入通道

对于多维的输入,与二维的输入卷积操作类似,只是这里我们的卷积核需要构造成与输入数据通道数相同,从而使其能够与多通道数据进行互相关运算。

卷积的结果为将各个通道的互相关运算结果相加

例如,对与双通道数据,其维度为(2 * 3 * 3):
i n p u t = [ [ 0 1 2 3 4 5 6 7 8 ] [ 1 2 3 4 5 6 7 8 9 ] ] input = \begin{bmatrix} \begin{bmatrix} 0&1&2 \\ 3&4&5 \\ 6&7&8\end{bmatrix} \\ \\ \begin{bmatrix} 1&2&3 \\ 4&5&6 \\ 7&8&9\end{bmatrix} \end{bmatrix} input=036147258147258369

使用卷积核,其维度为(2 * 2 * 2):

k e r n e l = [ [ 0 1 2 3 ] [ 1 2 3 4 ] ] kernel = \begin{bmatrix} \begin{bmatrix} 0&1 \\ 2&3 \end{bmatrix} \\ \\ \begin{bmatrix} 1&2 \\ 3&4 \end{bmatrix} \end{bmatrix} kernel=[0213][1324]

那么运算为:
i n p u t ∗ k e r n e l = [ [ 0 1 2 3 4 5 6 7 8 ] [ 1 2 3 4 5 6 7 8 9 ] ] ∗ [ [ 0 1 2 3 ] [ 1 2 3 4 ] ] = [ 0 1 2 3 4 5 6 7 8 ] ∗ [ 0 1 2 3 ] + [ 1 2 3 4 5 6 7 8 9 ] ∗ [ 1 2 3 4 ] = [ 56 72 104 120 ] input * kernel = \begin{bmatrix} \begin{bmatrix} 0&1&2 \\ 3&4&5 \\ 6&7&8\end{bmatrix} \\ \\ \begin{bmatrix} 1&2&3 \\ 4&5&6 \\ 7&8&9\end{bmatrix} \end{bmatrix} * \begin{bmatrix} \begin{bmatrix} 0&1 \\ 2&3 \end{bmatrix} \\ \\ \begin{bmatrix} 1&2 \\ 3&4 \end{bmatrix} \end{bmatrix} = \begin{bmatrix} 0&1&2 \\ 3&4&5 \\ 6&7&8\end{bmatrix} * \begin{bmatrix} 0&1 \\ 2&3 \end{bmatrix} + \begin{bmatrix} 1&2&3 \\ 4&5&6 \\ 7&8&9\end{bmatrix} * \begin{bmatrix} 1&2 \\ 3&4 \end{bmatrix} = \begin{bmatrix} 56&72 \\ 104&120 \end{bmatrix} inputkernel=036147258147258369[0213][1324]=036147258[0213]+147258369[1324]=[5610472120]

实现多通道的互相关运算:

import torch
from torch import nn

def corr2d_multi_in(X, K):
    # 沿着X和K的第0维(通道维)分别计算再相加
    res = d2l.corr2d(X[0, :, :], K[0, :, :])
    for i in range(1, X.shape[0]):
        res += d2l.corr2d(X[i, :, :], K[i, :, :])
    return res

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

输入数据验证上面的矩阵计算:

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.]])

多输出通道

当输入通道有多个时,因为我们对各个通道的结果做了累加,所以不论输入通道数是多少,输出通道数总是为1。
设卷积核输入通道数和输出通道数、高和宽分别为:
c i 、 c o 、 k h 、 k w c_i 、c_o、 k_h、k_w cicokhkw
如果希望得到含多个通道的输出,我们可以为每个输出通道分别创建一个核数组,其形状为:
c i × k h × k w c_i\times k_h\times k_w ci×kh×kw
将它们在输出通道维上连结,卷积核的形状即为
c o × c i × k h × k w c_o\times c_i\times k_h\times k_w 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 = torch.stack([K, K + 1, K + 2])
#(K+1)K中每个元素加一
K.shape # torch.Size([3, 2, 2, 2])

则现在的核数组为:
k e r n e l = [ [ [ 0 1 2 3 ] [ 1 2 3 4 ] ] [ [ 1 2 3 4 ] [ 2 3 4 5 ] ] [ [ 2 3 4 5 ] [ 3 4 5 6 ] ] ] kernel = \begin{bmatrix} \begin{bmatrix} \begin{bmatrix} 0&1 \\ 2&3 \end{bmatrix} \begin{bmatrix} 1&2 \\ 3&4 \end{bmatrix} \end{bmatrix} \\\\ \begin{bmatrix} \begin{bmatrix} 1&2 \\ 3&4 \end{bmatrix} \begin{bmatrix} 2&3 \\ 4&5 \end{bmatrix} \end{bmatrix} \\\\ \begin{bmatrix} \begin{bmatrix} 2&3 \\ 4&5 \end{bmatrix} \begin{bmatrix} 3&4 \\ 5&6 \end{bmatrix} \end{bmatrix} \end{bmatrix} kernel=[[0213][1324]][[1324][2435]][[2435][3546]]

corr2d_multi_in_out(X, K)

输出:

tensor([[[ 56.,  72.],
         [104., 120.]],

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

        [[ 96., 128.],
         [192., 224.]]])
  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值