Вероятности вывода следующего слова по заданному вводимому слову и целевому слову в RNN с использованием Pytorch - PullRequest
1 голос
/ 08 ноября 2019

Я использую рекуррентную сеть, использующую Pytorch 1.3.0, где вводом являются слова из небольшой вероятностной грамматики (горячее кодирование), а целью является одно слово впереди ввода. Мне удалось запустить модель, но мне интересно, есть ли способ вернуть распределения вероятностей возможных следующих слов по заданному входному слову. Моя конечная цель - измерить, насколько выходные данные сети отклоняются от этого распределения вероятностей.

Я видел другие примеры использования функции softmax для получения тензора вероятностей, но только в контексте генерации слов / символов. Итак, я использовал ту же функцию, но вместо этого вставил ее в функцию forward. А потом я использовал print(), потому что я не мог заставить функцию вернуть ее без ошибки (а также потому, что я понятия не имею, что я делаю).

Для простоты я только запускаюсмоделируйте одно предложение: «кошка бежит»

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

input_seq = np.array([[[0., 0., 1., 0.],
                       [0., 1., 0., 0.],
                       [0., 0., 0., 1.]]], dtype = np.float32) 

target_seq = [[1, 3, 0]]

И затем, используя Pytorch, вот мой код для модели:

device = torch.device("cpu")

input_seq = torch.from_numpy(input_seq)
target_seq = torch.Tensor(target_seq)

class Model(nn.Module):
    def __init__(self, input_size, output_size, hidden_dim, n_layers):
        super(Model, self).__init__()
        self.hidden_dim = hidden_dim
        self.n_layers = n_layers
        self.rnn = nn.RNN(input_size, hidden_dim, n_layers, batch_first=True)   
        self.fc = nn.Linear(hidden_dim, output_size)

    def forward(self, x):

        batch_size = x.size(0)
        hidden = self.init_hidden(batch_size)
        out, hidden = self.rnn(x, hidden)

        out = out.contiguous().view(-1, self.hidden_dim)
        out = self.fc(out)
        prob = nn.functional.softmax(out[-1], dim=0).data  # here is where I included the code
        print(prob)

        return out, hidden

    def init_hidden(self, batch_size):
        hidden = torch.zeros(self.n_layers, batch_size, self.hidden_dim).to(device)
        return hidden

И вот где я создаю экземпляр модели:

model = Model(input_size=dict_size, output_size=dict_size, hidden_dim=12, n_layers=1)
model.to(device)
n_epochs = 5  # epochs set to 5 for simplicity
lr=0.01
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)

И, наконец, обучение:

for epoch in range(1, n_epochs + 1):
    optimizer.zero_grad() 
    input_seq = input_seq.to(device)
    output, hidden = model(input_seq)
    loss = criterion(output, target_seq.view(-1).long())
    loss.backward() 
    optimizer.step()

    print('Epoch: {}/{}.............'.format(epoch, n_epochs), end=' ')
    print("Loss: {:.4f}".format(loss.item()))

Когда я запускаю код, он печатает вероятность для каждого слова в виде тензора, но только в конце каждой эпохи, а не после каждого введенного слова.

Итак, два моих вопроса:

1) Есть ли в любом случае вероятности, которые можно выводить после каждого слова в последовательности? Таким образом, в этом примере, когда модель обрабатывает «кошку», она возвращает вероятности для всех возможных слов. Или это что-то, что нельзя сделать?

2) И затем, если да на вопрос 1, есть ли способ вернуть вероятности не с помощью функции print(),но как переменная я могу получить доступ? (Таким образом, в основном, возвращая переменную без ошибок)

Я впервые задаю вопрос о переполнении стека, а также о своем первом реальном опыте работы с Pytorch, поэтому я заранее извиняюсь за любую путаницу (и отсутствиезнания в этой области)!

...