卷积过程详细讲解

1:单通道卷积

以单通道卷积为例,输入为(1,5,5),分别表示1个通道,宽为5,高为5。假设卷积核大小为3x3,padding=0,stride=1。

卷积过程如下:

相应的卷积核不断的在图像上进行遍历,最后得到3x3的卷积结果,结果如下:

2:多通道卷积1

以彩色图像为例,包含三个通道,分别表示RGB三原色的像素值,输入为(3,5,5),分别表示3个通道,每个通道的宽为5,高为5。假设卷积核只有1个,卷积核通道为3,每个通道的卷积核大小仍为3x3,padding=0,stride=1。

卷积过程如下,每一个通道的像素值与对应的卷积核通道的数值进行卷积,因此每一个通道会对应一个输出卷积结果,三个卷积结果对应位置累加求和,得到最终的卷积结果(这里卷积输出结果通道只有1个,因为卷积核只有1个。卷积多输出通道下面会继续讲到)。

可以这么理解:最终得到的卷积结果是原始图像各个通道上的综合信息结果。

上述过程中,每一个卷积核的通道数量,必须要求与输入通道数量一致,因为要对每一个通道的像素值要进行卷积运算,所以每一个卷积核的通道数量必须要与输入通道数量保持一致

我们把上述图像通道如果放在一块,计算原理过程还是与上面一样,堆叠后的表示如下:

3:多通道卷积2

在上面的多通道卷积1中,输出的卷积结果只有1个通道,把整个卷积的整个过程抽象表示,过程如下:

即:由于只有一个卷积核,因此卷积后只输出单通道的卷积结果(黄色的块状部分表示一个卷积核,黄色块状是由三个通道堆叠在一起表示的,每一个黄色通道与输入卷积通道分别进行卷积,也就是channel数量要保持一致,图片组这里只是堆叠放在一起表示而已)。

那么,如果要卷积后也输出多通道,增加卷积核(filers)的数量即可,示意图如下:

备注:上面的feature map的颜色,只是为了表示不同的卷积核对应的输出通道结果,不是表示对应的输出颜色

4、填充

填充(padding)是指在输入高和宽的两侧填充元素(通常是0元素)。下图里我们在原输入高和宽的两侧分别添加了值为0的元素,使得输入高和宽从3变成了5,并导致输出高和宽由2增加到4。图中的阴影部分为第一个输出元素及其计算所使用的输入和核数组元素:0×0+0×1+0×2+0×3=00×0+0×1+0×2+0×3=0。

一般来说,如果在高的两侧一共填充 p h p_h ph​ 行,在宽的两侧一共填充 p w p_w pw​ 列,那么输出形状将会是


( n h − k h + p h + 1 ) × ( n w − k w + p w + 1 ) (n_h - k_h + p_h + 1)\times(n_w - k_w + p_w + 1) (nh​−kh​+ph​+1)×(nw​−kw​+pw​+1)

也就是说,输出的高和宽会分别增加 p h p_h ph​和 p w p_w pw​ 。

卷积神经网络经常使用奇数高宽的卷积核,如1、3、5和7,所以两端上的填充个数相等。对任意的二维数组X,设它的第i行第j列的元素为X[i,j]。当两端上的填充个数相等,并使输入和输出具有相同的高和宽时,我们就知道输出Y[i,j]是由输入以X[i,j]为中心的窗口同卷积核进行互相关计算得到的。

下面的例子里我们创建一个高和宽为3的二维卷积层,然后设输入高和宽两侧的填充数分别为1。给定一个高和宽为8的输入,我们发现输出的高和宽也是8。

import torch
from torch import nn

# 定义一个函数来计算卷积层。它对输入和输出做相应的升维和降维
def comp_conv2d(conv2d, X):
    # (1, 1)代表批量大小和通道数(“多输入通道和多输出通道”一节将介绍)均为1
    X = X.view((1, 1) + X.shape)
    Y = conv2d(X)
    return Y.view(Y.shape[2:])  # 排除不关心的前两维:批量和通道

# 注意这里是两侧分别填充1行或列,所以在两侧一共填充2行或列
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, padding=1)

X = torch.rand(8, 8)
comp_conv2d(conv2d, X).shape
torch.Size([8, 8])

当卷积核的高和宽不同时,我们也可以通过设置高和宽上不同的填充数使输出和输入具有相同的高和宽。

# 使用高为5、宽为3的卷积核。在高和宽两侧的填充数分别为2和1
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape
torch.Size([8, 8])

5、步幅

我们介绍了卷积运算。卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅(stride)。

目前我们看到的例子里,在高和宽两个方向上步幅均为1。我们也可以使用更大步幅。下图展示了在高上步幅为3、在宽上步幅为2的二维互相关运算。可以看到,输出第一列第二个元素时,卷积窗口向下滑动了3行,而在输出第一行第二个元素时卷积窗口向右滑动了2列。当卷积窗口在输入上再向右滑动2列时,由于输入元素无法填满窗口,无结果输出。图中的阴影部分为输出元素及其计算所使用的输入和核数组元素:0×0+0×1+1×2+2×3=80×0+0×1+1×2+2×3=8、0×0+6×1+0×2+0×3=60×0+6×1+0×2+0×3=6。

一般来说,当高上步幅为 s h s_h sh​,宽上步幅为 s w s_w sw​时,输出形状为
[ ( n h − k h + p h + s h ) s h ] × [ ( n w − k w + p w + s w ) s w ] \left[ \frac{(n_h - k_h + p_h + s_h)}{s_h} \right] \times \left[ \frac{(n_w - k_w + p_w + s_w)}{s_w} \right] [sh​(nh​−kh​+ph​+sh​)​]×[sw​(nw​−kw​+pw​+sw​)​]
下面我们令高和宽上的步幅均为2,从而使输入的高和宽减半。

conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)
comp_conv2d(conv2d, X).shape
torch.Size([4, 4])
conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))
comp_conv2d(conv2d, X).shape
torch.Size([2, 2])

小结

  • 62
    点赞
  • 274
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
卷积(Deconvolution)是卷积的逆运算,也称为转置卷积(Transpose Convolution)或分步卷积(Fractionally Strided Convolution)。在深度学习中,反卷积通常用于图像语义分割、物体定位等任务中。 反卷积的计算过程卷积类似,但是它的输入和输出顺序是相反的。具体来说,反卷积的计算步骤如下: 1. 定义一个反卷积核(Deconvolution Kernel),它通常是一个小的矩阵,例如 $3 \times 3$ 或 $5 \times 5$ 的矩阵。 2. 把反卷积核对准输出图像的一个像素点,然后计算反卷积核和该像素点周围一定范围内像素点的加权平均值。这个范围就是反卷积核的大小。 3. 把步骤2中计算得到的加权平均值赋值给输入图像的对应像素点。重复步骤2和步骤3,直到对整个输出图像都进行了反卷积运算。 与卷积不同的是,反卷积的输入和输出大小关系相反。如果输入图像的大小为 $H \times W$,反卷积核的大小为 $K \times K$,那么输出图像的大小为 $(H+K-1) \times (W+K-1)$。 在实现反卷积运算时,可以使用反卷积运算的矩阵形式,也可以使用反卷积运算的逐元素形式。反卷积运算的矩阵形式可以用矩阵乘法实现,反卷积运算的逐元素形式可以用循环实现。 需要注意的是,反卷积并不是卷积的逆运算,因为卷积是一种有信息丢失的运算。在卷积运算中,多个输入像素可能会被映射到同一个输出像素上,因此反卷积运算并不能完全恢复原始输入。实际上,反卷积只是一种近似逆运算,它可以在一定程度上恢复原始输入,但是不能完全恢复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值