我使用的是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])
如预期。