0. Pytorch 卷积层的padding计算

简介

最近在使用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) # 80*80*4帧图像
input = input.transpose(2,0,1) # numpy转制为4*80*80便于输入
stateinput = input[None,:] # numpy数组升维
x = torch.from_numpy(stateinput).to(torch.float32) # torch tensor和numpy的转换

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=SWF+2P+1
其中:
N代表输出大小
W代表输入图片大小
F代表kernel大小
S代表步长
P就是padding也就是我们需要计算的值

举例

我们现在其余变量均已知,想要计算P值。
希望得到的输出是2020的图像,N=20;
输入是80
80的图像,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=SWF+2P+1
20 = 80 − 8 + 2 ∗ P 4 + 1 20=\frac{80-8+2*P}{4}+1 20=4808+2P+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) # 80*80*4帧图像
input = input.transpose(2,0,1) # numpy转制为4*80*80便于输入
stateinput = input[None,:] # numpy数组升维
x = torch.from_numpy(stateinput).to(torch.float32) # torch tensor和numpy的转换

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
如有错误,欢迎各位在评论区指出,我也是初学者,希望和大家一起进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值