在 Pytorch 中使用膨胀> 1 实现卷积操作的"same"填充



我使用的是Pytorch 1.8.1,尽管我知道新版本有填充";相同的";选项,由于某些原因,我不想升级它。为了用步幅1和膨胀为CNN实现相同的填充>1,我把填充如下:

padding=(dilation*(cnn_kernel_size[0]-1)//2, dilation*(cnn_kernel_size[1]-1)//2))

根据Pytorch文档,我原以为输入和输出大小会相同,但事实并非如此!

Pytorch文件中写道:

Hout​=⌊( Hin​ + 2×padding[0] − dilation[0]×(kernel_size[0]−1) −1) /stride[0] ​+ 1⌋
Wout​=⌊( Win​ + 2×padding[1] − dilation[1]×(kernel_size[1]−1) −1) /stride[1] + 1⌋

torch.nn.Conv2d的输入形状为(1,1625513(基于Conv2d pytorch文档,表示批次大小=1,Cin=1,Hin=625,Win=513

使用后:

  • 64个过滤器
  • 粒径(15,15(
  • 步幅=(1,1(
  • 膨胀=5
  • 填充=(35,35(

将这些值放在上面的公式中可以得到:

Hout​=⌊(625 ​+ 2×35 −5×(15−1) −1) /1 ​+1⌋=⌊(625 ​+ 70 −5×14 -1) + 1⌋=625
Wout​=⌊(513 ​+ 2×35 −5×(15−1) −1) /1 ​+1⌋=⌊(513 ​+ 70 −5×14 -1) + 1⌋=513

然而,pytorch给出的输出形状为(1,64681569(

我可以理解1的值,并且C out=64。但我不知道为什么H out和W out与H in和W in不一样?有人能解释一下吗?

我想通了!我最终得到错误维度的原因是我没有为填充添加数值。我给了它膨胀的数值,并在此基础上计算出作为的填充值

padding=(膨胀*(cnn_kernel_size[0]-1(//2,膨胀*(cnn_kernel_size[1]-1(//2(

我认为Pytorch需要得到padding的数值,因为当我更改代码并给网络提供padding的值并基于padding计算膨胀(膨胀=(2*padding(/(内核大小-1(时,我得到了正确的输出形状。

我认为你的计算是正确的。填充应该是35像素
由于某些原因,我无法重现您报告的输出形状。

测试这一点,产生所需的输出大小:

import torch
conv = torch.nn.Conv2d(1, 64, kernel_size=15, dilation=5, padding=35, stride=1)
conv(torch.rand(1, 1, 625, 513)).shape

产生

torch.Size([1, 64, 625, 513])

如预期。

最新更新