简介
最近在使用Pytorch搭建一个简单的DQN网络,其中涉及到图像需要进行卷积层和池化层的计算。 个人感觉Pytorch是一个数据每走一步都需要编程者清楚明白的Library,从github也可以感受到Pytorch的开发者对于极致性能的追求,这个问题会在后面讨论到…… 好的,那我们先来查看一下Pytorch官网的接口。
Pytorch官网接口
Pytorch.nn Document 打开Doc并定位到convolution layers。
class
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)
in_channels:代表输入的通道数,比如你有4帧图像,那么in_channels=4 out_channels:代表输出的通道数,比如你想输出32个矩阵,那么out_channels=32 kernel_size:是个int也可以是个tuple,int即为正方形的卷积核,tuple即为矩形卷积核(X,Y) stride:步长 padding:controls the amount of padding applied to the input. It can be either a string {‘valid’, ‘same’} or a tuple of ints giving the amount of implicit padding applied on both sides. emm,那既然你官网都这么说了,那我就这么写吧。
import numpy as np
import torch
import torch.nn as nn
input = np.random.rand(80,80,4)
input = input.transpose(2,0,1)
stateinput = input[None,:]
x = torch.from_numpy(stateinput).to(torch.float32)
conv1 = nn.Conv2d(in_channels=4, out_channels=32, kernel_size=(8,8), stride=4, padding='same')
out = conv1(x)
print(out.shape)
好的,在这里我的每一步都是按照官网的Docs来的,但是你这么运行,会发现在构造conv2d时出现了错误。
ValueError: padding='same' is not supported for strided convolutions
【有内鬼啊!】 搜索了一下Pytorch的issue,发现了问题所在: Pytorch issues67551 似乎是为了Pytorch的性能,需要用户自己计算一下padding的值,那么好吧,也是一个学习的过程。
Padding的计算
在实际操作时,我们会碰到 padding的两种方式 “SAME” 和 “VALID”,padding = “SAME”时,会在图像的周围填 “0”,padding = “VALID”则不需要,即 P=0。 一般会选“SAME”,以来减缓图像变小的速度,二来防止边界信息丢失(即有些图像边界的信息发挥作用较少)。 padding= “SAME”时:
N
=
W
?
F
+
2
P
S
+
1
N=\frac{W-F+2P}{S}+1
N=SW?F+2P?+1 其中: N代表输出大小 W代表输入图片大小 F代表kernel大小 S代表步长 P就是padding也就是我们需要计算的值
举例
我们现在其余变量均已知,想要计算P值。 希望得到的输出是2020的图像,N=20; 输入是8080的图像,W=80; kernel大小是8*8,F=8 步长为4,S=4
N
=
W
?
F
+
2
P
S
+
1
N=\frac{W-F+2P}{S}+1
N=SW?F+2P?+1
20
=
80
?
8
+
2
?
P
4
+
1
20=\frac{80-8+2*P}{4}+1
20=480?8+2?P?+1
求
得
P
=
2
求得P=2
求得P=2
验证
import numpy as np
import torch
import torch.nn as nn
input = np.random.rand(80,80,4)
input = input.transpose(2,0,1)
stateinput = input[None,:]
x = torch.from_numpy(stateinput).to(torch.float32)
conv1 = nn.Conv2d(in_channels=4, out_channels=32, kernel_size=(8,8), stride=4, padding=2)
out = conv1(x)
print(out.shape)
得到结果
torch.Size([1, 32, 20, 20])
即32个20*20的数字矩阵,有了这样的算式,剩下的Convolution Layers和Pooling Layers也就照猫画虎的得到了。
Reference
卷积层输出大小尺寸计算及padding为 “SAME” 和 “VALID”的计算 使用pytorch实现CNN 如有错误,欢迎各位在评论区指出,我也是初学者,希望和大家一起进步。
|