初入torch的时候首先看的就是卷积,‘食嗝多黏’ 来记录一下以备不时之需。以下使用的都是torch.nn.functional.conv2d来计算,因为这个可以传入自己的权重矩阵,观察起来比较方便。
torch.nn.
Conv2d
(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=’zeros’, device=None, dtype=None)
参数释义
stride
stride 表示卷积核滑动的步长。例子如下
x = torch.Tensor([x for x in range(25)]).view(1, 1, 5, 5)
w = torch.Tensor([1, 1, 1, 1]).view(1, 1, 2, 2)
print(x)
print(w)
print(conv2d(x, w))
print(conv2d(x, w, stride=2))
输入矩阵
tensor([[[[ 0., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 9.],
[10., 11., 12., 13., 14.],
[15., 16., 17., 18., 19.],
[20., 21., 22., 23., 24.]]]])
权重矩阵
tensor([[[[1., 1.],
[1., 1.]]]])
下面是步长为1的默认情况
tensor([[[[12., 16., 20., 24.],
[32., 36., 40., 44.],
[52., 56., 60., 64.],
[72., 76., 80., 84.]]]])
这是步长为2的情况
tensor([[[[12., 20.],
[52., 60.]]]])
步长为1的时候就是最简单的卷积。步长为2的时候,首先是左上角(0,1,5,6)构成的卷积结果为12,然后步长为2,下一步就跳过了(1,2,6,7)直奔(2,3,7,8)所以结果为20,此时再往右走两步没有足够的空间了,所以直接开始纵向上的移动。
因为设置的步长为2,所以跳过了(5,6,7,8,9)这一行,直接从(10,11,12,13,14)这一行开始。和第一行一样,这里只计算了(10,11,15,16)的结果52 以及(12,13,17,18)的结果60.
接下来再往下移动的时候下方的空间不足了(步长为2,跳过了(15,16,17,18,19)这一行),卷积结束。
dilation(空洞卷积)
卷积核各个元素之间的间隔。默认的卷积方式dilation=1
下图是dilation=2的情况
语言难以描述,有图自有真相。
groups(深度可分离卷积)
groups参数将 in_channel和out_channel 按照次序分别分成了一 一对应的groups组。
比如 in_channels = 10 out_channels = 15 groups = 5
那么会生成5组数据,第一组卷积核能看到 in_channels[0:2],生成out_channels[0:3],以此类推。
最终将这5个组concatenate起来得到最终的结果。groups使得卷积忽略了一部分通道间的交互信息。当groups=in_channels时,卷积变成了深度可分离卷积,此时生成的结果通道之间没有任何交互,通常需要再进行一次卷积核大小为1*1的卷积来联合通道信息。这样做的目的时能够极大幅度的减少模型参数数量。
今天的文章torch.conv2d stride,dilation,groups分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/29580.html