`return_sequences = False` 等效于 pytorch LSTM
`return_sequences = False` equivalent in pytorch LSTM
在tensorflow/keras中,我们可以简单地为classification/fullyconnected/activation(softmax/sigmoid)层之前的最后一个LSTM层设置return_sequences = False
来去掉时间维度。
在 PyTorch 中,我没有找到任何类似的东西。对于分类任务,我不需要序列到序列模型,而是像这样的多对一架构:
这是我的简单双 LSTM 模型。
import torch
from torch import nn
class BiLSTMClassifier(nn.Module):
def __init__(self):
super(BiLSTMClassifier, self).__init__()
self.embedding = torch.nn.Embedding(num_embeddings = 65000, embedding_dim = 64)
self.bilstm = torch.nn.LSTM(input_size = 64, hidden_size = 8, num_layers = 2,
batch_first = True, dropout = 0.2, bidirectional = True)
# as we have 5 classes
self.linear = nn.Linear(8*2*512, 5) # last dimension
def forward(self, x):
x = self.embedding(x)
print(x.shape)
x, _ = self.bilstm(x)
print(x.shape)
x = self.linear(x.reshape(x.shape[0], -1))
print(x.shape)
# create our model
bilstmclassifier = BiLSTMClassifier()
如果我观察每一层之后的形状,
xx = torch.tensor(X_encoded[0]).reshape(1,512)
print(xx.shape)
# torch.Size([1, 512])
bilstmclassifier(xx)
#torch.Size([1, 512, 64])
#torch.Size([1, 512, 16])
#torch.Size([1, 5])
我该怎么做才能使最后一个 LSTM returns 成为形状为 (1, 16)
而不是 (1, 512, 16)
的张量?
最简单的方法是对张量进行索引:
x = x[:, -1, :]
其中 x
是 RNN 输出。当然,如果 batch_first
是 False
,则必须使用 x[-1, :, :]
(或只是 x[-1]
)来索引时间轴。原来这和 Tensorflow/Keras 做的是一样的。相关代码见K.rnn
here:
last_output = tuple(o[-1] for o in outputs)
注意此时的代码使用time_major
数据格式,所以索引在第一个轴中。此外,outputs
是一个元组,因为它可以是多层、state/cell 对等,但它通常是所有时间步的输出的 序列 。
然后在 RNN
class 中使用如下:
if self.return_sequences:
output = K.maybe_convert_to_ragged(is_ragged_input, outputs, row_lengths)
else:
output = last_output
所以总的来说,我们可以看到 return_sequences=False
只使用了 outputs[-1]
。
在tensorflow/keras中,我们可以简单地为classification/fullyconnected/activation(softmax/sigmoid)层之前的最后一个LSTM层设置return_sequences = False
来去掉时间维度。
在 PyTorch 中,我没有找到任何类似的东西。对于分类任务,我不需要序列到序列模型,而是像这样的多对一架构:
这是我的简单双 LSTM 模型。
import torch
from torch import nn
class BiLSTMClassifier(nn.Module):
def __init__(self):
super(BiLSTMClassifier, self).__init__()
self.embedding = torch.nn.Embedding(num_embeddings = 65000, embedding_dim = 64)
self.bilstm = torch.nn.LSTM(input_size = 64, hidden_size = 8, num_layers = 2,
batch_first = True, dropout = 0.2, bidirectional = True)
# as we have 5 classes
self.linear = nn.Linear(8*2*512, 5) # last dimension
def forward(self, x):
x = self.embedding(x)
print(x.shape)
x, _ = self.bilstm(x)
print(x.shape)
x = self.linear(x.reshape(x.shape[0], -1))
print(x.shape)
# create our model
bilstmclassifier = BiLSTMClassifier()
如果我观察每一层之后的形状,
xx = torch.tensor(X_encoded[0]).reshape(1,512)
print(xx.shape)
# torch.Size([1, 512])
bilstmclassifier(xx)
#torch.Size([1, 512, 64])
#torch.Size([1, 512, 16])
#torch.Size([1, 5])
我该怎么做才能使最后一个 LSTM returns 成为形状为 (1, 16)
而不是 (1, 512, 16)
的张量?
最简单的方法是对张量进行索引:
x = x[:, -1, :]
其中 x
是 RNN 输出。当然,如果 batch_first
是 False
,则必须使用 x[-1, :, :]
(或只是 x[-1]
)来索引时间轴。原来这和 Tensorflow/Keras 做的是一样的。相关代码见K.rnn
here:
last_output = tuple(o[-1] for o in outputs)
注意此时的代码使用time_major
数据格式,所以索引在第一个轴中。此外,outputs
是一个元组,因为它可以是多层、state/cell 对等,但它通常是所有时间步的输出的 序列 。
然后在 RNN
class 中使用如下:
if self.return_sequences:
output = K.maybe_convert_to_ragged(is_ragged_input, outputs, row_lengths)
else:
output = last_output
所以总的来说,我们可以看到 return_sequences=False
只使用了 outputs[-1]
。