Самым простым было бы создать другой модуль (скажем, Bidirectional
) и передать ему любую ячейку, которую вы хотите.
Сама реализация довольно проста.Обратите внимание, что я использую операцию concat
для соединения двунаправленного вывода, вы можете указать другие режимы, такие как суммирование и т. Д.
Пожалуйста, прочитайте комментарии в коде ниже, возможно, вам придетсяизмените его соответствующим образом.
import torch
class Bidirectional(torch.nn.Module):
def __init__(self, cell):
super().__init__()
self.cell = cell
def __call__(self, x, init_states=None):
prediction, hidden_seq, (h_t, c_t) = self.cell(x, init_states)
backward_prediction, backward_hidden_seq, (
backward_h_t,
backward_c_t,
# Assuming sequence is first dimension, otherwise change 0 appropriately
# Reverses sequences so the LSTM cell acts on the reversed sequence
) = self.cell(torch.flip(x, (0,)), init_states)
return (
# Assuming you transpose so it has (batch, seq, features) dimensionality
torch.cat((prediction, backward_prediction), 2),
torch.cat((hidden_seq, backward_hidden_seq), 2),
# Assuming it has (batch, features) dimensionality
torch.cat((h_t, backward_ht), 1),
torch.cat((c_t, backward_ct), 1),
)
Когда речь идет о нескольких слоях, вы можете сделать что-то похожее в принципе:
import torch
class Multilayer(torch.nn.Module):
def __init__(self, *cells):
super().__init__()
self.cells = torch.nn.ModuleList(cells)
def __call__(self, x, init_states=None):
inputs = x
for cell in self.cells:
prediction, hidden_seq, (h_t, c_t) = cell(inputs, init_states)
inputs = hidden_seq
return prediction, hidden_seq, (h_t, c_t)
Обратите внимание, что вы должны передавать созданные объекты ячеек в Multilayer
например:
# For three layers of LSTM, each needs features to be set up correctly
multilayer_LSTM = Multilayer(LSTM(), LSTM(), LSTM())
Вы также можете передавать классы вместо экземпляров в конструктор и создавать их внутри Multilayer
(так что hidden_size
соответствует автоматически), но эти идеи должны помочь вам начать.