Pytorch 上多变量 LSTM 的张量形状

Tensor shape for multivariable LSTM on Pytorch

我有一个包含 8 个特征和 4 个时间步长的数据集。我正在尝试实现 LSTM,但需要帮助理解我是否正确设置了我的张量。目的是从 LSTM 中获取输出的特征并将它们传递给 NN。

我的张量形状目前是#samples x #timesteps x #features 即 4500x4x8。这适用于下面的代码。我想确保模型确实将每个时间步长矩阵作为一个新序列(矩阵 4500x[0]x8 是第一个时间步长矩阵,4500x[3]x8 是最后一个时间步长)。然后我采用最终时间步长输出(输出 [:,-1,:] 通过 NN。

代码是否按照我认为的那样进行?我问,因为性能略低于仅使用最终时间步长数据的简单 RF。这将是出乎意料的,因为数据具有很强的时间序列相关性(它跟踪患者在进行通气前生命体征下降)。

我有以下代码:

class LSTM1(nn.Module):
    def __init__(self, num_classes, input_size, hidden_size, num_layers):
        super(LSTM1, self).__init__()
        self.num_classes = num_classes #number of classes
        self.num_layers = num_layers #number of layers
        self.input_size = input_size #input size
        self.hidden_size = hidden_size #hidden state

        self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size,
                          num_layers=num_layers, batch_first=True) #lstm
        self.fc_1 =  nn.Linear(hidden_size, 32) #fully connected 1
        self.fc_2 =  nn.Linear(32, 12) #fully connected 1
        self.fc_3 = nn.Linear(12, 1)
        self.fc = nn.Sigmoid() #fully connected last layer

        self.relu = nn.ReLU()
    def forward(self,x):
            h_0 = Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size)) #hidden state
            c_0 = Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size)) #internal state
            # Propagate input through LSTM
            output, (hn, cn) = self.lstm(x, (h_0, c_0)) #lstm with input, hidden, and internal state
            out = output[:,-1,:] #reshaping the data for Dense layer next
            out = self.relu(out)
            out = self.fc_1(out) #first Dense
            out = self.relu(out) #relu
            out = self.fc_2(out) #2nd dense
            out = self.relu(out) #relu
            out = self.fc_3(out) #3rd dense
            out = self.relu(out) #relu
            out = self.fc(out) #Final Output
            return out

错误

你的错误源于最后三行。

Do not use ReLU activation at the end of your network

使用 nn.Linear -> nn.Sigmoid 与 BCELoss 或 nn.Linear 和 nn.BCEWithLogitsLoss(请参阅 here 了解什么是 logits)。

怎么回事

  • 使用 ReLu,您输出的值在 [0, +inf)
  • 范围内
  • 在其上应用 sigmoid 将值“压缩”为 (0, 1),阈值为 0(例如 0 变为 0.5 概率,因此 1 在阈值保持在 0.5 后!
  • 实际上,你总是用这段代码预测 1,这可能不是你想要的