torch same padding

醉酒当歌 提交于 2020-11-27 09:04:38

 

CNN中,增加Padding过后,为我们带来的那些负面影响。

 

如上图所示:

第一行为普通3x3卷积,步长1,padding 0,

第二行为普通3x3卷积,步长1,padding 1,

第三行为膨胀3x3卷积,dilation rate=3,步长1,padding 3.

上图箭头右向所指,为cnn底层在caffe 和darknet的底层实现,用c或c++,至于pytorch和tensorflow 是否也是这样实现cnn我不清楚,但是目前来讲,有效实现卷积的也就3种方式,

im2col(上图) ,winograd, FFT,但是还是im2col比较常见,winograd好像是商汤最近几年提出来的,通过特殊数学计算方式,减少计算量,目前该方法被应用在腾讯移动端深度学习框架NCNN中,至于FFT,还没见到用在深度学习种。

至于为什么使用im2col,这还是贾清扬大神在写caffe时提出来的,因为图像中,一个块内的像素点在内存中是地址不连续的,所以对于同一个块内的像素想要缓存到cache上,可能出现多次内存访问,效率极低,所以设计出im2co方式,提前将需要计算的像素点放在连续地址上。

 

因此,对于同一图像,除了原始图像在内存中占空间,使用im2col又会消耗另一份空间。

如上图所示,对于8x8的图像:

不加padding,计算量为9x36=324, 内存消耗为8x8=64,有效内存为64/64=1

加padding=1,计算量为9x64=572,内存消耗为10x10=100,有效内存为64/100=0.64

加dilation_rate=3,padding=1,计算量为9x64=572,内存消耗为14x14=196,有效内存为64/196=0.32

在上图中可见,添加padding=1就可对内存造成1-0.64=0.36的内存损失,当使用dilation_rate=3时,内存损失为1-0.32=0.68

假如,我们为存储图像分配1个G大小空间,为使用im2col后的图像在分配1个G大小的空间,当我们使用dilation_rate=3之后,有效内存,也就是真正的像素所占的内存仅仅为2x0.32=0.64G。

以上例子为当图像或是特征大小为8x8的情况,假设我们的图像或是特征大小为100x100

那么使用dilation_rate=3,有效内存占比为(100x100)/(106x106)=0.88,有效内存还是挺客观的。

对于8x8的如此小的特征,在我们的网络中一般都出现在网络的深层,而对于100x100的特征,在我们的网络中一般都出现在网络的浅层。因此在网络不同的层中,合理使用dilation,

可以更高效的使用我们的内存。

 

Implement "same" padding for convolution operations

mimics TensorFlow SAME padding (I'm writing it down into the functional interface, so that nn.Conv2d can just call into F.conv2d_same_padding):

 1 def conv2d_same_padding(input, weight, bias=None, stride=1, dilation=1, groups=1):
 2   input_rows = input.size(2)
 3   filter_rows = weight.size(2)
 4   effective_filter_size_rows = (filter_rows - 1) * dilation[0] + 1
 5   out_rows = (input_rows + stride[0] - 1) // stride[0]
 6   padding_needed =
 7           max(0, (out_rows - 1) * stride[0] + effective_filter_size_rows -
 8                   input_rows)
 9   padding_rows = max(0, (out_rows - 1) * stride[0] +
10                         (filter_rows - 1) * dilation[0] + 1 - input_rows)
11   rows_odd = (padding_rows % 2 != 0)
12   # same for padding_cols
13 
14   if rows_odd or cols_odd:
15     input = F.pad(input, [0, int(cols_odd), 0, int(rows_odd)])
16 
17   return F.conv2d(input, weight, bias, stride,
18                   padding=(padding_rows // 2, padding_cols // 2),
19                   dilation=dilation, groups=groups)
20  

It was mostly copy-pasted from TensorFlow code in here and here.

“As you can see, there is a lot of hidden things going on there, and that's why it might not be worth it adding a padding='same'. And I think not replicating the SAME behavior in TensorFlow is not ideal either.

 

本文来自于:

Francisco Massa : Implement "same" padding for convolution operations?

谢谢!!!                                                                                                                  

 

转载于:https://www.cnblogs.com/wang2825/articles/8947634.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!