为什么 Tensorflow 和 PyTorch LSTM 之间的行为不同?

问题描述 投票:0回答:1

我有一个非常简单的 Pytorch LSTM,我试图在金融数据集上运行。我以前用过它的形式,直到现在它还没有让我失望。

PyTorch 中的 LSTM 看起来像这样

class LSTMPredictor(nn.Module):
    def __init__(self, n_features, n_hidden, n_layers):
        super().__init__()
        self.lstm = nn.LSTM(
            input_size=n_features,
            hidden_size=n_hidden,
            batch_first=True,
            num_layers=n_layers,
        )
        self.drop = nn.Dropout(0.1)
        self.regressor = nn.Linear(n_hidden, 1)


    def forward(self, x):
        _, (hidden, _) = self.lstm(hidden)
        hidden = self.drop1(out)
        preds = self.regressor(hidden[-1])
        return preds

我已将其精简到我遇到问题的最小形式。

对于我有的参数

n_features = 19
n_hidden = 256
n_layers = 1
SEQ_LEN=120

在 torch 和 tf 模型中,这些都是使用的参数

现在这是我的问题

当我尝试训练这个模型时,它无法学习,损失仍然很高,并且在原始值的 +/-50% 左右波动。

在尝试调试模型时,我最终尝试了 Tensorflow (Keras) 实现(不会有什么坏处)。

超级简单

model = Sequential()
model.add(LSTM(256, input_shape=(SEQ_LEN, 19)))
model.add(Dropout(0.1))
model.add(Dense(1))

奇怪的是这个模型确实会学习!? 损失随着每经过一步而持续减少到一个点。

一些额外信息

  • 在 Windows 上运行
  • 火炬==2.0.1
  • 张量流==2.14.0
  • tf 模型在 CPU 上运行(不支持 Windows),而 torch 则在 GPU 上运行
  • 使用 AdamW 优化器,常数 lr=1e-3(keras.optimizers.AdamW 和 torch.optim.AdamW 分别)
  • 都使用l1_loss

我尝试在CPU上运行torch模型,这不是问题。 我尝试过使用火炬后端

import keras_core as keras
os.environ["KERAS_BACKEND"] = "torch"
运行相同的 Keras 模型,并使用火炬张量处理所有内容。当我这样做时,模型就起作用了。

我现在真的很茫然,这两种实现有什么不同? 非常感谢任何帮助:)

编辑 我想我可能已经将问题隔离为与 torch.float32 和 float64 之间的差异有关。当我使用 float32 在 torch 后端运行 keras 模型时,在它无法学习的地方会发生同样的事情,可能会发生梯度消失的情况吗?

tensorflow keras deep-learning pytorch lstm
1个回答
0
投票

您的前向方法是错误的,您使用

hidden
作为输入而不是
x
!,并且您没有使用 LSTM dropout 的 pytorch 标准方法。这是正确的形式:

class LSTMPredictor(nn.Module):
    def __init__(self, n_features, n_hidden, n_layers, dropout_rate=0.1):
        super().__init__()
        self.lstm = nn.LSTM(
            input_size=n_features,
            hidden_size=n_hidden,
            batch_first=True,
            num_layers=n_layers,
            dropout=dropout_rate # Apply dropout only if there are multiple LSTM layers
        )
        self.regressor = nn.Linear(n_hidden, 1)

    def forward(self, x):
        out, (hidden, _) = self.lstm(x)
        preds = self.regressor(hidden[-1])
        return preds

附注仅当有多个 LSTM 层时才应用 dropout。

© www.soinside.com 2019 - 2024. All rights reserved.