在 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,尤其是 inputs
和 outputs
部分,始终。
分类器应该是这样的:
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_hidden
与zeros
,未初始化即为默认值
- 不需要每次都传
self.hidden
给LSTM。此外,你不应该那样做。这意味着每批数据中的元素在某种程度上是下一步,而批处理元素应该是不相交的,您可能不需要那样。
_, (h_n, _)
returns 上一时间步的最后一个隐藏单元格,形状完全相同:(num_layers * num_directions, batch, hidden_size)
。在我们的例子中 num_layers
和 num_directions
是 1
所以我们得到 (1, batch, hidden_size)
张量作为输出
- 整形为
(batch, hidden_size)
使其可以通过线性层
- Return 未激活即登录。只有一个,如果它是二元情况。使用
torch.nn.BCEWithLogitsLoss
as loss for binary case and torch.nn.CrossEntropyLoss
用于多类案例。 sigmoid
也适用于二进制情况,而 softmax
或 log_softmax
适用于多类别。
- 对于二进制只需要一个输出。任何低于
0
的值(如果在这种情况下返回非标准化概率)都被认为是负数,任何高于正数的值都被认为是负数。
我有一系列向量表示随时间变化的信号。我想 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,尤其是 inputs
和 outputs
部分,始终。
分类器应该是这样的:
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_hidden
与zeros
,未初始化即为默认值 - 不需要每次都传
self.hidden
给LSTM。此外,你不应该那样做。这意味着每批数据中的元素在某种程度上是下一步,而批处理元素应该是不相交的,您可能不需要那样。 _, (h_n, _)
returns 上一时间步的最后一个隐藏单元格,形状完全相同:(num_layers * num_directions, batch, hidden_size)
。在我们的例子中num_layers
和num_directions
是1
所以我们得到(1, batch, hidden_size)
张量作为输出- 整形为
(batch, hidden_size)
使其可以通过线性层 - Return 未激活即登录。只有一个,如果它是二元情况。使用
torch.nn.BCEWithLogitsLoss
as loss for binary case andtorch.nn.CrossEntropyLoss
用于多类案例。sigmoid
也适用于二进制情况,而softmax
或log_softmax
适用于多类别。 - 对于二进制只需要一个输出。任何低于
0
的值(如果在这种情况下返回非标准化概率)都被认为是负数,任何高于正数的值都被认为是负数。