PyTorch';是否真的没有padding=相同的选项;那是什么?

PyTorch';是否真的没有padding=相同的选项;那是什么?,pytorch,Pytorch,我目前正致力于建立一个卷积神经网络(CNN),它将处理时间序列数据 更具体地说,数据是形状(100,40)的财务数据,其中100表示100个时间戳,40表示40个特征 我使用的CNN使用了非对称的内核大小(即1x2和4x1)和非对称的步幅(即1x2用于1x2层,1x1用于4x1层) 为了保持高度标注保持在100,我需要对数据应用一些填充。我正在研究如何做到这一点,并注意到使用TensorFlow或Keras的人只需做padding='same',但根据我发现的许多资源,PyTorch中显然没有这

我目前正致力于建立一个卷积神经网络(CNN),它将处理时间序列数据

更具体地说,数据是形状
(100,40)
的财务数据,其中
100
表示100个时间戳,
40
表示40个特征

我使用的CNN使用了非对称的内核大小(即
1x2
4x1
)和非对称的步幅(即
1x2
用于
1x2
层,
1x1
用于
4x1
层)

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

我发现,根据和,我可以手动计算我需要填充数据的方式,并可以用来解决我的问题,因为普通层似乎不支持不对称填充(我认为我需要的总填充高度为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)
正如您所看到的,它确实在维度大小保持不变的意义上起作用。然而,我一直在想,是否真的没有
padding='same'
选项?另外,我们如何知道是将衬垫2应用于顶部还是底部

多谢各位


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

我不久前也遇到过同样的问题,所以我自己用
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)

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

看一看,它会给你一个线索。实际上,由于Tensorflow的静态计算图,这一特性在Tensorflow中是可能的。在PyTorch中,有一个动态计算图,因此可能很难实现(否则他们可能已经实现了)。正如你所说,在
nn.Conv2D
中,只有对称填充,但不同的填充可以沿不同的维度进行。我认为@akshayk07是正确的,pytorch的动态特性让它很难实现;下面是pytorch中“相同”填充的一个很好的实现(用于2d conv):