Добавление текущего слоя к модели PyTorch LSTM с другим скрытым размером - PullRequest
0 голосов
/ 08 декабря 2018

Я разрабатываю модель BI-LSTM для анализа последовательности с использованием PyTorch.Для чего я использую torch.nn.LSTM.Используя этот модуль, вы можете иметь несколько слоев, просто передав параметр num_layers, равный количеству слоев (например, num_layers=2).Однако все они будут иметь одинаковый hidden_size, что частично хорошо для меня, я просто хочу, чтобы все они были одинаковыми hidden_size , но последний слой с другимразмер.Ниже приведен базовый пример:

rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
inp = torch.randn(5, 3, 10)
h0 = torch.randn(2, 3, 20)
c0 = torch.randn(2, 3, 20)
output, (hn, cn) = rnn(inp, (h0, c0))

Выходная яркость равна (5, 3,20)

Одно решение (но для меня это невыгодно) реализует дополнительную модель, которая выводит нужное мне измерение и получает данные из первой модели, например:

rnn_two = nn.LSTM(input_size=20, hidden_size=2)
output2, _ = rnn_two(output)

Однако я не хочу этого делать, потому что я распараллеливаю модель использует DataParallel, поэтому мне нужно, чтобы все было в одной упаковке.Я надеялся найти что-то похожее на keras, например:

rnn.add(LSTM, hidden_size=2)

Я проверил исходный код LSTM , но не смог найти то, что мне нужно.

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Хотя тот факт, что ответ @Mikhail Berlinkov работает по мере необходимости, он не обобщается на общий случай (который даже не запрашивается в вопросе), для которого я хотел бы предложить второе решение:

import torch
import torch.nn as nn
import torch.nn.functional as F
from functools import reduce

class RNNModel(nn.Module):
    def __init__(self, *models):
        super(RNNModel, self).__init__()
        self.models = models

    def forward(self, inp):
        return reduce(lambda arg, model: model(arg, None)[0], self.models, inp)

И может называться:

rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
rnn_two = nn.LSTM(input_size=20, hidden_size=2)
inp = torch.randn(5, 3, 10)

rnn_model = RNNModel(rnn, rnn_two)

output = rnn_model(inp)

output.shape равно ожидаемому (т. Е. 5,3,2)

0 голосов
/ 08 декабря 2018

Если я не ошибаюсь, это можно сделать так:

import torch.nn as nn
import torch.nn.functional as F

class RnnWith2HiddenSizesModel(nn.Module):
    def __init__(self):
        super(RnnWith2HiddenSizesModel, self).__init__()
        self.rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
        self.rnn_two = nn.LSTM(input_size=20, hidden_size=2)

    def forward(self, inp, hc):
        output, _ = self.rnn(inp, hc)
        output2, _ = self.rnn_two(output)
        return output2


inp = torch.randn(5, 3, 10)
h0 = torch.randn(2, 3, 20)
c0 = torch.randn(2, 3, 20)

rnn = RnnWith2HiddenSizesModel()

output = RnnWith2HiddenSizesModel()(inp, (h0, c0))


tensor([[[-0.0305,  0.0327],
     [-0.1534, -0.1193],
     [-0.1393,  0.0474]],

    [[-0.0370,  0.0519],
     [-0.2081, -0.0693],
     [-0.1809,  0.0826]],

    [[-0.0561,  0.0731],
     [-0.2307, -0.0229],
     [-0.1780,  0.0901]],

    [[-0.0612,  0.0891],
     [-0.2378,  0.0164],
     [-0.1760,  0.0929]],

    [[-0.0660,  0.1023],
     [-0.2176,  0.0508],
     [-0.1611,  0.1053]]], grad_fn=<CatBackward>)
...