在 Pytorch 中如何使用 LSTM 将一系列向量分为两类

How can I use an LSTM to classify a series of vectors into two categories in Pytorch

我有一系列向量表示随时间变化的信号。我想 class 将部分信号分为两类:1 或 0。使用 LSTM 的原因是我相信网络需要了解整个信号才能 classify。

我的问题是开发 PyTorch 模型。下面是我想出的class。

class LSTMClassifier(nn.Module):

   def __init__(self, input_dim, hidden_dim, label_size, batch_size):
       self.lstm = nn.LSTM(input_dim, hidden_dim)
       self.hidden2label = nn.Linear(hidden_dim, label_size)
       self.hidden = self.init_hidden()

   def init_hidden(self):
       return (torch.zeros(1, self.batch_size, self.hidden_dim), 
               torch.zeros(1, self.batch_size, self.hidden_dim))

   def forward(self, x):
       lstm_out, self.hidden = self.lstm(x, self.hidden)
       y  = self.hidden2label(lstm_out[-1])
       log_probs = F.log_softmax(y)
       return log_probs

但是这个模型给出了一堆形状错误,我无法理解发生的一切。我先看了this SO问题。

您应该遵循 PyTorch documentation,尤其是 inputsoutputs 部分,始终

分类器应该是这样的:

import torch
import torch.nn as nn


class LSTMClassifier(nn.Module):
    def __init__(self, input_dim, hidden_dim, label_size):
        super().__init__()
        self.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True)
        self.hidden2label = nn.Linear(hidden_dim, label_size)

    def forward(self, x):
        _, (h_n, _) = self.lstm(x)
        return self.hidden2label(h_n.reshape(x.shape[0], -1))


clf = LSTMClassifier(100, 200, 1)
inputs = torch.randn(64, 10, 100)
clf(inputs)

要考虑的要点:

  • 始终使用 super().__init__(),因为它会在您的神经网络中注册模块,允许挂钩等
  • 使用 batch_first=True 这样您就可以传递形状为 (batch, timesteps, n_features)
  • 的输入
  • 无需init_hiddenzeros,未初始化即为默认值
  • 不需要每次都传self.hidden给LSTM。此外,你不应该那样做。这意味着每批数据中的元素在某种程度上是下一步,而批处理元素应该是不相交的,您可能不需要那样。
  • _, (h_n, _) returns 上一时间步的最后一个隐藏单元格,形状完全相同:(num_layers * num_directions, batch, hidden_size)。在我们的例子中 num_layersnum_directions1 所以我们得到 (1, batch, hidden_size) 张量作为输出
  • 整形为(batch, hidden_size)使其可以通过线性层
  • Return 未激活即登录。只有一个,如果它是二元情况。使用 torch.nn.BCEWithLogitsLoss as loss for binary case and torch.nn.CrossEntropyLoss 用于多类案例。 sigmoid 也适用于二进制情况,而 softmaxlog_softmax 适用于多类别。
  • 对于二进制只需要一个输出。任何低于 0 的值(如果在这种情况下返回非标准化概率)都被认为是负数,任何高于正数的值都被认为是负数。