pytorch conv中的padding

总结:没有padding="same"等固定模型,需要自己计算padding是多少,
当padding=(1,1)在外围上下左右各加了一层,详情见如下转载的博客:
原文链接:https://blog.csdn.net/g11d111/article/details/82665265

一. Caffe、Tensorflow的padding策略

在之前的转载过的一篇文章——《tensorflow ckpt文件转caffemodel时遇到的坑》提到过,caffe的padding方式和tensorflow的padding方式有很大的区别,输出无法对齐。这是为什么呢?

下面简单回顾一下

卷积操作输出的形状计算公式是这样的:

output_shape = (image_shape-filter_shape+2*padding)/stride + 1

因为padding前面的系数是2,所以在padding时,一般是对称地补,左/右各padding一列 或者 上下各padding一行。

那么问题来了,如果stride是2,而括号里算出来的值刚好是奇数怎么办?那就再偷偷摸摸补一列padding或者补一行padding。

于是,caffe和tensorflow的区别就出来了。

caffe偷偷摸摸地把一行0补在上面 或者 把一列0补在左边,tensorflow正好镜像对称,把一行0补在下面或者把一列0补在右边。这就是导致输出对齐不了的原因,前面几层输出的feature map的中间还能勉强对上,随着网络结构的加深,到fc之前已经完全对不上了。

也就是说

  • caffe的padding策略是把0补在左上
  • tensorflow的padding策略是把0补在右下

那么,PyTorch的padding策略是怎样的呢?在介绍padding策略之前,先简单的介绍一下PyTorch中的nn.Conv2d算子。

二. nn.Conv2d简单说明

nn.Conv2d的介绍主要译自官网

nn.Conv2d的功能是:对由多个输入平面组成的输入信号进行二维卷积,以最简单的例子进行说明:

输入信号的形式为 ( N , C i n , H , W ) ( N , C i n , H , W ) ( N , C i n , H , W ) (N,Cin,H,W)(N,Cin,H,W) (N,C_{in},H,W) (N,Cin,H,W)(N,Cin,H,W)(N,Cin,H,W)Wout是根据我们在nn.Conv2d中设置的padding,dilation,kernel_size,stride等参数得到的输出特征图的高度和宽度。
这里写图片描述

三. nn.Conv2d中的padding操作

nn.Conv2d简单介绍完了,现在来讲讲padding在nn.Conv2d中怎么实现的,也就是怎么补的0,或者说补0的策略。

Q1: padding是卷积之后还是卷积之前还是卷积之后实现的?

padding是在卷积之前补0,如果愿意的话,可以通过使用torch.nn.Functional.pad来补非0的内容。

Q2:padding补0的默认策略是什么?

四周都补!如果pad输入是一个tuple的话,则第一个参数表示高度上面的padding,第2个参数表示宽度上面的
下面将展示一个padding = 1的例子:

这里写图片描述
显然,padding=1的效果是:原来的输入层基础上,上下左右各补了一行!除此之外我们看到,上下左右都是0.9862,那么,这个东西是啥呢?为什么不是0呢?

为了这个问题,我甚至还去PyTorch论坛上献丑了,估计大家可能也知道是咋回事了…
是的!是Bias!我问的问题是这样的:
Calculation detail in nn.Conv2d

Hello, I just can’t figure out the way nn.Conv2d calculate the output . 

The result calculated from torch is not the same as some machine learning course had taught.

For example, likes the code below:

>> m = torch.nn.Conv2d(1, 1, 3, padding=0)
>> m(input)
tensor([[[[ 0.5142, 0.3803, 0.2687],
[-0.4321, 1.1637, 1.0675],
[ 0.1742, 0.0869, -0.4451]]]], grad_fn=<ThnnConv2DBackward>)
>> input
tensor([[[[ 0.7504, 0.1157, 1.4940, -0.2619, -0.4732],
[ 0.1497, 0.0805, 2.0829, -0.0925, -1.3367],
[ 1.7471, 0.5205, -0.8532, -0.7358, -1.3931],
[ 0.1159, -0.2376, 1.2683, -0.0959, -1.3171],
[-0.1620, -1.8539, 0.0893, -0.0568, -0.0758]]]])
>> m.weight
Parameter containing:
tensor([[[[ 0.2405, 0.3018, 0.0011],
[-0.1691, -0.0701, -0.0334],
[-0.0429, 0.2668, -0.2152]]]], requires_grad=True)

for the left top element 0.5142, it’s not the output equals to

>> import numpy as np
>> w = np.array([[0.2405, 0.3018, 0.0011],
>> [-0.1691, -0.0701, -0.0334],
>> [-0.0429, 0.2668, -0.2152]])

top-left 3x3 matrix of 5x5

>> x = np.array([[ 0.7504, 0.1157, 1.4940],
>> [ 0.1497, 0.0805, 2.0829],
>> [1.7471, 0.5205, -0.8532]])
>> print(np.sum(w*x))

0.364034 != 0.5142

0.36403412999999996

My Question here is: Why Could the output not equal to 0.5142?

Further more, when i add paramter padding into nn.Conv2d,
The outcome seems obscure to me as below, thanks a lot for explain that to me.Thank you!

>> input
tensor([[[[ 0.7504, 0.1157, 1.4940, -0.2619, -0.4732],
[ 0.1497, 0.0805, 2.0829, -0.0925, -1.3367],
[ 1.7471, 0.5205, -0.8532, -0.7358, -1.3931],
[ 0.1159, -0.2376, 1.2683, -0.0959, -1.3171],
[-0.1620, -1.8539, 0.0893, -0.0568, -0.0758]]]])

set padding from 0 to 1 equals to (1, 1)

>> m1 = torch.nn.Conv2d(1, 1, 1, padding=1)
>> m1(input)
tensor([[[[0.9862, 0.9862, 0.9862, 0.9862, 0.9862, 0.9862, 0.9862],
[0.9862, 1.0771, 1.0002, 1.1672, 0.9544, 0.9288, 0.9862],
[0.9862, 1.0043, 0.9959, 1.2385, 0.9749, 0.8242, 0.9862],
[0.9862, 1.1978, 1.0492, 0.8828, 0.8970, 0.8174, 0.9862],
[0.9862, 1.0002, 0.9574, 1.1398, 0.9745, 0.8266, 0.9862],
[0.9862, 0.9665, 0.7615, 0.9970, 0.9793, 0.9770, 0.9862],
[0.9862, 0.9862, 0.9862, 0.9862, 0.9862, 0.9862, 0.9862]]]],
grad_fn=<ThnnConv2DBackward>)

The confused point is that how 0.9862 be calculated?
And what is the default padding strategy in nn.Conv2d?

Thank you for reading and answer!

答案也很简单——我没考虑bias!
这里写图片描述

根据下图,Q2中神秘的0.9862的来历我们就很清楚了,是bias的值。
这里写图片描述

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值