PyTorch 的 Conv2d 真的没有 padding=same 选项吗?

Sea*_*ala 16 pytorch

我目前正在构建一个可以处理时间序列数据的卷积神经网络 (CNN)。

更具体地说,该数据是形状为 的财务数据(100, 40)100含义为 100 个时间戳,40含义为 40 个特征。

CNN的,我使用使用非对称内核的大小(即1 x 24 x 1)以及不对称的进步(即1 x 21 x 2层和1 x 14 x 1层)。

为了保持高度尺寸100,我需要对数据应用一些填充。我正在研究如何做到这一点,并注意到使用 TensorFlow 或 Keras 的人只是这样做padding='same',但根据我发现的许多资源,包括Github 上的此线程,此选项在 PyTorch 中显然不可用。

我发现,根据这个问题中的一些答案以及PyTorch 讨论论坛上的这个答案,我可以手动计算我需要如何填充我的数据并可以torch.nn.ZeroPad2d用来解决我的问题,因为看起来正常torch.nn.Conv2d层不'不支持非对称填充(我相信我需要的总填充高度为 3,宽度为 0)。

我为测试这一点而编写的实验代码是这样的:

import torch
import torch.nn as nn

conv = nn.Conv2d(1, 1, kernel_size=(4, 1))
pad = nn.ZeroPad2d((0, 0, 2, 1)) # Add 2 to top and 1 to bottom.

x = torch.randint(low=0, high=9, size=(100, 40))
x = x.unsqueeze(0).unsqueeze(0)

y = pad(x)

x.shape # (1, 1, 100, 40)
y.shape # (1, 1, 103, 40)

print(conv(x.float()).shape)
print(conv(y.float()).shape)

# Output
# x -> (1, 1, 97, 40)
# y -> (1, 1, 100, 40)
Run Code Online (Sandbox Code Playgroud)

如您所见,它确实在维度大小保持不变的意义上起作用。但是,我一直想知道那里真的没有padding='same'选择吗?另外,我们如何知道是将 padding 2 应用到顶部还是底部?

谢谢你。


编辑

这有点晚了,但如果有人好奇我是如何解决这个问题的,我基本上手动添加了填充以模拟该padding=same选项。

luc*_*rot 8

1.9.1根据文档,现在 pytorch 中似乎已经有了。

padding='valid'与没有填充相同。padding='same'填充输入,使输出具有与输入相同的形状。但是,此模式不支持除 1 之外的任何步幅值。


mil*_*bar 6

前段时间我遇到了同样的问题,所以我ZeroPad2d像你一样使用一个层自己实现了它。这是正确的公式:

from functools import reduce
from operator import __add__

kernel_sizes = (4, 1)

# Internal parameters used to reproduce Tensorflow "Same" padding.
# For some reasons, padding dimensions are reversed wrt kernel sizes,
# first comes width then height in the 2D case.
conv_padding = reduce(__add__, 
    [(k // 2 + (k - 2 * (k // 2)) - 1, k // 2) for k in kernel_sizes[::-1]])

pad = nn.ZeroPad2d(conv_padding)
conv = nn.Conv2d(1, 1, kernel_size=kernel_sizes)

print(x.shape) # (1, 1, 103, 40)
print(conv(y.float()).shape) # (1, 1, 103, 40)
Run Code Online (Sandbox Code Playgroud)

另外,正如@akshayk07 和@Separius 所提到的,我可以确认是pytorch 的动态特性使它变得困难。是 Pytorch 开发人员关于这一点的帖子。