TensorFlow与PyTorch卷积混淆



我对如何在PyTorch中复制Keras(TensorFlow(卷积感到困惑。

在喀拉拉邦,我可以做这样的事情。(输入大小为(256, 237, 1, 21),输出大小为(256, 237, 1, 1024)

import tensorflow as tf
x = tf.random.normal((256,237,1,21))
y = tf.keras.layers.Conv1D(filters=1024, kernel_size=5,padding="same")(x)
print(y.shape) 
(256, 237, 1, 1024)

然而,在PyTorch中,当我尝试做同样的事情时,我会得到不同的输出大小:

import torch.nn as nn
x = torch.randn(256,237,1,21)
m = nn.Conv1d(in_channels=237, out_channels=1024, kernel_size=(1,5))
y = m(x)
print(y.shape)
torch.Size([256, 1024, 1, 17])

我希望PyTorch能给我与Keras相同的输出大小:

这个前面的问题似乎暗示Keras过滤器是PyTorch的out_channels,但这就是我所拥有的。我试图在padding=(0,503)的PyTorch中添加填充,但这给了我torch.Size([256, 1024, 1, 1023]),但仍然不正确。这也比keras花费的时间长得多,所以我觉得我错误地分配了一个参数。

如何复制Keras在PyTorch中使用卷积所做的操作?

在张量流中,tf.keras.layers.Conv1D采用形状为(batch_shape + (steps, input_dim))的张量。这意味着通常所说的通道出现在最后一个轴上。例如,在2D卷积中,您会得到(batch, height, width, channels)这与PyTorch不同,PyTorch中通道尺寸正好位于批处理轴之后:torch.nn.Conv1d的形状为(batch, channel, length)。所以你需要改变两个轴。

对于torch.nn.Conv1d:

  • in_channels是输入张量中的通道数
  • out_channels是滤波器的数量,输出将具有的通道数量
  • stride卷积的步长
  • padding两侧加零

PyTorch中没有padding='same'选项,您需要正确选择padding。这里是stride=1,所以padding必须等于kernel_size//2(,即padding=2(,以保持张量的长度。


在您的示例中,由于x的形状为(256, 237, 1, 21),因此在TensorFlow的术语中,它将被视为具有的输入

  • 一批CCD_ 24
  • steps=1,所以1D输入的长度是1
  • 21输入通道

而在PyTorch中,(256, 237, 1, 21)形状的x将是:

  • CCD_ 30的批量形状
  • 1输入通道
  • 长度为CCD_ 32

在下面的两个例子中(TensorFlowPyTorch(都将输入保持为x.shape=(256, 237, 21),假设256是批量大小,237是输入序列的长度,21是通道的数量(输入维度,我认为是每个时间步长上的维度(。

在TensorFlow中:

>>> x = tf.random.normal((256, 237, 21))
>>> m = tf.keras.layers.Conv1D(filters=1024, kernel_size=5, padding="same")
>>> y = m(x)
>>> y.shape
TensorShape([256, 237, 1024])

PyTorch中:

>>> x = torch.randn(256, 237, 21)
>>> m = nn.Conv1d(in_channels=21, out_channels=1024, kernel_size=5, padding=2)
>>> y = m(x.permute(0, 2, 1))
>>> y.permute(0, 2, 1).shape
torch.Size([256, 237, 1024])

因此,在后者中,您只需使用x = torch.randn(256, 21, 237)。。。

PyTorch现在有开箱即用的相同卷积操作,你可以看看这个链接〔相同卷积〕〔1〕

class InceptionNet(nn.Module):
def __init__(self, in_channels, in_1x1, in_3x3reduce, in_3x3, in_5x5reduce, in_5x5, in_1x1pool):
super(InceptionNet, self).__init__()
self.incep_1 = ConvBlock(in_channels, in_1x1, kernel_size=1, padding='same')

请注意,相同的卷积只支持默认步幅值1,其他任何值都不起作用。[1] :https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html

相关内容

  • 没有找到相关文章

最新更新