如何在pytorch中实现分数步长卷积层?

问题描述

在此之前,我搜索了 google 和 StackOverflow,但没有找到任何类似的问题,所以在这里我提出一个新问题。

我对 this paper 感兴趣,并希望为我的项目实施此 SGAN。论文提到它的生成器网络是由“一堆分数步长卷积层”组成的,我在pytorch中找到了两种不同的实现方式,一种是:

torch.nn.Sequential(
    # other layers...
    torch.nn.ConvTranspose2d(),# other layers...
)

另一种方式是:

torch.nn.Sequential(
    # other layers...
    torch.nn.Upsample(scale_factor=2),torch.nn.Conv2d(),# other layers...
)

那么,我的问题是,哪个是分数步长卷积层的更好实现,还是我理解的完全错误

提前致谢。

P.S,我在第 87 - 88 行找到了第二个实现 here

解决方法

tldr;有一些形状约束,但都执行相同的操作。


nn.ConvTranspose2d的输出形状由y = (x − 1)s - 2p + d(k-1) + p_out + 1给出,其中xy分别是输入和输出形状,k是内核大小,s 步幅,d 膨胀,pp_out 填充和填充。在这里,我们使用 s=1p=0p_out=0d=1 使事情变得简单。

因此,转置卷积的输出形状为:

y =  x - 1 + k

如果我们看一个带卷积的上采样 (x2)。使用与之前相同的符号,nn.Conv2d 的输出为:y = floor((x + 2p - d(k - 1) - 1) / s + 1)upsamplingx 的大小为 2x。我们将膨胀保持在 d=1

y = floor((2x + 2p - k) / s + 1)

如果我们想匹配转置卷积的输出形状,我们需要有x - 1 + k = floor((2x + 2p - k) / s + 1)。这种关系将定义为我们的卷积选择 sp 的值。

举一个简单的例子来演示:k=2。现在x + 1需要等于floor((2x + 2p - k) / s + 1),这可以通过设置s=2p=1来解决。


这里是同一个视觉形式的例子。

enter image description here

  • 转置卷积

enter image description here

  • 上采样 + 卷积

enter image description here