简体   繁体   English

TensorFlow vs PyTorch 卷积混淆

[英]TensorFlow vs PyTorch convolution confusion

I am confused on how to replicate Keras (TensorFlow) convolutions in PyTorch.我对如何在 PyTorch 中复制 Keras (TensorFlow) 卷积感到困惑。

In Keras, I can do something like this.在 Keras 中,我可以做这样的事情。 (the input size is (256, 237, 1, 21) and the output size is (256, 237, 1, 1024) . (输入大小为(256, 237, 1, 21) ,output 大小为(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)

However, in PyTorch, when I try to do the same thing I get a different output size:然而,在 PyTorch 中,当我尝试做同样的事情时,我得到了不同的 output 大小:

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])

I want PyTorch to give me the same output size that Keras does:我想要 PyTorch 给我 output 的尺寸,和 Keras 一样:

This previous question seems to imply that Keras filters are PyTorch's out_channels but thats what I have. 上一个问题似乎暗示 Keras 过滤器是 PyTorch 的out_channels但这就是我所拥有的。 I tried to add the padding in PyTorch of padding=(0,503) but that gives me torch.Size([256, 1024, 1, 1023]) but that still not correct.我试图在padding=(0,503)的 PyTorch 中添加填充,但这给了我torch.Size([256, 1024, 1, 1023])但这仍然不正确。 This also takes so much longer than keras does so I feel that I have incorrectly assigned a parameter.这也比 keras 花费的时间长得多,所以我觉得我错误地分配了一个参数。

How can I replicate what Keras did with convolution in PyTorch?如何复制 Keras 在 PyTorch 中对卷积所做的操作?

In TensorFlow, tf.keras.layers.Conv1D takes in a tensor of shape (batch_shape + (steps, input_dim)) .在 TensorFlow 中, tf.keras.layers.Conv1D采用形状为(batch_shape + (steps, input_dim))的张量。 Which means that what is commonly known as channels appears on the last axis.这意味着通常所说的通道出现在最后一个轴上。 For instance in 2D convolution you would have (batch, height, width, channels) .例如,在 2D 卷积中,您将拥有(batch, height, width, channels) This is different from PyTorch where the channel dimension is right after the batch axis: torch.nn.Conv1d takes in shapes of (batch, channel, length) .这与 PyTorch 不同,其中通道维度紧跟在批次轴之后: torch.nn.Conv1d的形状为(batch, channel, length) So you will need to permute two axes.所以你需要排列两个轴。

For torch.nn.Conv1d :对于torch.nn.Conv1d

  • in_channels is the number of channels in the input tensor in_channels是输入张量中的通道数
  • out_channels is the number of filters, ie the number of channels the output will have out_channels是过滤器的数量,output 将拥有的通道数量
  • stride the step size of the convolution stride卷积的步长
  • padding the zero-padding added to both sides padding添加到两侧的零填充

In PyTorch there is no option for padding='same' , you will need to choose padding correctly.在 PyTorch 中没有padding='same'选项,您需要正确选择padding Here stride=1 , so padding must equal to kernel_size//2 ( ie padding=2 ) in order to maintain the length of the tensor.这里stride=1 ,所以padding必须等于kernel_size//2padding=2 )才能保持tensor的长度。


In your example, since x has a shape of (256, 237, 1, 21) , in TensorFlow's terminology it will be considered as an input with:在您的示例中,由于x的形状为(256, 237, 1, 21) ,因此在 TensorFlow 的术语中,它将被视为输入:

  • a batch shape of (256, 237) , (256, 237)的批量形状,
  • steps=1 , so the length of your 1D input is 1 , steps=1 ,所以你的一维输入的长度是1
  • 21 input channels. 21个输入通道。

Whereas in PyTorch, x of shape (256, 237, 1, 21) would be:而在 PyTorch 中, x的形状(256, 237, 1, 21)将是:

  • batch shape of (256, 237) , (256, 237)的批量形状,
  • 1 input channel 1输入通道
  • a length of 21 .长度为21

Have kept the input in both examples below (TensorFlow vs. PyTorch) as x.shape=(256, 237, 21) assuming 256 is the batch size, 237 is the length of the input sequence, and 21 is the number of channels ( ie the input dimension, what I see as the dimension on each timestep).将下面两个示例(TensorFlowPyTorch)中的输入保持为x.shape=(256, 237, 21)假设256是批量大小, 237是输入序列的长度,21 是通道数(输入维度,我认为是每个时间步长的维度)。

In TensorFlow:在 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])

In PyTorch:在 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])

So in the latter, you would simply work with x = torch.randn(256, 21, 237) ...所以在后者中,您只需使用x = torch.randn(256, 21, 237) ...

PyTorch now has out of the box same convolution operation you can take a look at this link [Same convolution][1] PyTorch 现在已经开箱即用了相同的卷积运算你可以看看这个链接 [Same convolution][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')

Note a same convolution only supports the default stride value which is 1 anything other won't work.请注意,相同的卷积仅支持默认步幅值,即 1,其他任何值都不起作用。 [1]: https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html [1]: https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM