【问题标题】:What is different between The MaxPool1D API in tensorflow 2.X and MaxPool1d in pytorchtensorflow 2.X 中的 MaxPool1D API 和 pytorch 中的 MaxPool1d 有什么不同
【发布时间】:2021-09-21 20:25:54
【问题描述】:

我正在尝试将 tensorflow 中生成的代码重新实现到 pytroch 中,但是我遇到了 maxpooling,查看了这两个框架的文档,发现它们的行为并不相同。有人可以向我解释为什么它们不同,哪个更有效(我问这个是因为它们给出了不同的结果)?

import tensorflow
from tensorflow.keras.layers import  GlobalMaxPool1D
tf_tensor = tensorflow.random.normal([8, 6, 5])
tf_maxpool = GlobalMaxPool1D()
print("output shape : ", tf_maxpool(tf_tensor).shape)

输出形状:(8, 5)

import torch
import torch.nn as nn



torch_tensor = torch.tensor(tf_tensor.numpy())
maxpool = nn.MaxPool1d(kernel_size=2)
print("output shape : ", maxpool(torch_tensor).shape)

输出形状:torch.Size([8, 6, 2])

【问题讨论】:

    标签: tensorflow pytorch


    【解决方案1】:

    全局最大池化没有窗口大小,因为它是全局的,它会考虑整个序列。等效的运算符只是 torch.max 按通道应用, axis=1:

    >>> maxpool = torch_tensor.max(1).values
    
    >>> maxpool.shape
    torch.Size([8, 5])
    

    【讨论】:

      【解决方案2】:

      MaxPool 与 GlobalMaxPool

      torch.nn.MaxPool1d 通过执行 max 操作将每个 N 相邻值池化。

      对于这些值:

      [1, 2, 3, 4, 5, 6, 7, 8]
      

      使用您指定的kernel_size=2,您将获得以下值:

      [2, 4, 6, 8]
      

      这意味着大小为 2 的滑动窗口获得最大值并移动到下一对。

      Global Pooling 是一个类似的操作,但从整个列表中获取最大值,正如Ivan's answer 中所指出的那样。在我们的例子中,我们只需要一个 8 值。

      此操作在 PyTorch 中称为 torch.nn.AdaptiveAvgPool1d(可选地后跟 torch.nn.Flatten):

      import torch
      
      tensor = torch.randn(8, 6, 5)
      
      global_max_pooling = torch.nn.Sequential(
          torch.nn.AdaptiveMaxPool1d(1), # (8, 6, 1) shape
          torch.nn.Flatten(), # (8, 6) after removing unnecessary 1 dimension
      )
      
      global_max_pooling(tensor) # (8, 6)
      

      上面的解释被简化为这个操作是跨特定维度进行的

      Tensorflow 与 PyTorch 形状差异

      正如人们所注意到的,在 Tensorflow 的情况下,输出的形状是 (8, 5),而在 PyTorch 的情况下,它是 (8, 6)

      这种差异源于不同的通道尺寸(请参阅here 了解 PyTorch 中的最后一个通道),即:

      • PyTorch 假定数据布局为 (batch, channels, sequence)
      • Tensorflow 假定数据布局为 (batch, sequence, channels)(也称为通道最后)

      在 PyTorch 的情况下,必须permute 数据才能获得完全相同的结果:

      tensor = tensor.permute(0, 2, 1) # (8, 5, 6)
      global_max_pooling(tensor) # (8, 5)
      

      效率

      当您想要执行 具有指定输出大小(不同于 1)的池时使用 torch.nn.AdaptiveAvgPool1d,因为它会跳过 torch.nn.MaxPool1d 执行的一些不必要的操作(多次遍历相同的元素,这超出了这个问题的范围)。

      一般情况下,当我们执行全局池化时,两者大致相等并且执行相同数量的操作

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 1970-01-01
        • 2020-10-01
        • 2020-09-09
        • 2021-03-13
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 2021-11-07
        相关资源
        最近更新 更多