Я использую рекуррентную сеть, использующую 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, поэтому я заранее извиняюсь за любую путаницу (и отсутствиезнания в этой области)!