Простой текстовый генератор Pytorch не работает и потери продолжают расходиться - PullRequest
0 голосов
/ 24 мая 2018

Я новичок в области pytorch и глубокого обучения в целом, и пытаюсь создать простой генератор текста.По причинам, которые я не понимаю, потери продолжают расходиться, а модель - нет.Вот код.

class RNN(nn.Module):
    def __init__(self, embed_size, hidden_size):
        super(RNN, self).__init__()
        self.embeds = nn.Embedding(num_chars, embed_size)
        self.l1 = nn.Linear(embed_size, hidden_size)
        self.l2 = nn.Linear(hidden_size, hidden_size)
        self.l3 = nn.Linear(hidden_size, num_chars)
        self.relu = nn.ReLU()
        self.softmax = nn.Softmax()

    def forward(self, inp):
        out = self.embeds(inp)
        out = self.l3(self.relu(self.l2(self.relu(self.l1(out)))))
        return self.softmax(out)

rnn = RNN(10, 50)
optimizer = torch.optim.Adam(rnn.parameters(), lr = 0.002)
criterion = nn.NLLLoss()

def charTensor(x):
    out = torch.zeros(1, num_chars)
    out[0][all_chars.index(x)] = 1
    return out.long()

for epoch in range(5):
    epoch_loss = 0
    rnn.zero_grad()
    for i in range(len(train_str[:400])-1):

        inp = charTensor(train_str[i])
        output = rnn(inp)
        loss = criterion(output, charTensor(train_str[i+1]))
        epoch_loss += loss

        loss.backward(retain_graph=True)
        optimizer.step()

    print("Epoch Loss:", epoch_loss) //epoch loss is always tensor(-399)

first_char = 'c'
inp_t = charTensor(first_char)
fin = first_char
for i in range(10):
    next_t = rnn(inp_t)
    next_char = all_chars[torch.argmax(next_t).numpy()]   //always ends up as 0, which is the char for space
    fin += next_char   
    inp_t = charTensor(next_char)
print(fin)    //prints new line

1 Ответ

0 голосов
/ 24 мая 2018
  1. Вы пытаетесь внедрить RNN?Потому что я вижу, что вы называете свою модель RNN, но реализация, кажется, не принимает сигналы от предыдущих временных шагов.
  2. Кажется, что вы не реализуете пакеты и тренируетесь на основе ввода 1 символа, а затем обратного распространенияна что.Это, как известно, вызывает нестабильность.Возможно, вы захотите выполнить итерации по нескольким символам и накапливать потери и усреднять их перед обратным распространением.

При создании текста вы хотите обучить модель, подготовив, например, последовательность данных "лиса перепрыгнула через ленивую собаку ".При прогнозировании на уровне слов ваш ввод будет:

["the","fox","jumped", "over","the","lazy"] 

, а цель будет:

["fox","jumped", "over","the","lazy", "dog"]        

Что делает модель, пытаясь предсказать следующее слово, исходя из предыдущих слов.На уровне символов, затем просто измените список на каждый символ в предложении.Таким образом, у вас будет модель, которая изучает распределение вероятностей.

Для конкретной реализации PyTorch проверьте здесь: https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutorial.html

Кроме того, вам не нужен retain_graph=True, поскольку он будет накапливатьсяобъем памяти.Вместо этого просто наберите:

    loss.backward()
    optimizer.step()
    optimizer.zero_grad()
...