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