Текстовый генератор Pytorch LSTM повторяет те же слова - PullRequest
1 голос
/ 26 апреля 2019

ОБНОВЛЕНИЕ: Это была ошибка в логике, генерирующей новые символы.См. Ответ ниже.

ОРИГИНАЛЬНЫЙ ВОПРОС: Я создал LSTM для генерации текста на уровне символов с помощью Pytorch.Модель тренируется хорошо (потери разумно уменьшаются и т. Д.), Но обученная модель в итоге выдает последнюю горстку слов ввода, повторяемых снова и снова (например, ввод: «Она сказала ей вернуться позже, но никогда не делала»);Вывод: «но она никогда не делала, но она никогда не делала, но она никогда не делала» и так далее).

Я немного поигрался с гиперпараметрами, и проблема остается.В настоящее время я использую:

  • Функция потери: BCE

  • Оптимизатор: Адам

  • Обучениескорость: 0,001

  • Длина последовательности: 64

  • Размер партии: 32

  • Размер встраивания:128

  • Скрытое затемнение: 512

  • LSTM слоев: 2

Я тоже пробовал не всегдавыбирая лучший выбор, но это только вводит неправильные слова и не прерывает цикл.Я смотрел на бесчисленные учебники, и я не могу понять, что я делаю по-другому / неправильно.

Ниже приведен код для обучения модели.training_data - это одна длинная строка, и я зацикливаюсь на ней, предсказывая следующий символ для каждой подстроки длины SEQ_LEN.Я не уверен, что моя ошибка здесь или в другом месте, но любой комментарий или направление высоко ценится!

loss_dict = dict()
for e in range(EPOCHS):
    print("------ EPOCH {} OF {} ------".format(e+1, EPOCHS))

    lstm.reset_cell()

    for i in range(0, DATA_LEN, BATCH_SIZE):

        if i % 50000 == 0:
            print(i/float(DATA_LEN))

        optimizer.zero_grad()

        input_vector = torch.tensor([[
            vocab.get(char, len(vocab)) 
            for char in training_data[i+b:i+b+SEQ_LEN]
        ] for b in range(BATCH_SIZE)])

        if USE_CUDA and torch.cuda.is_available():
            input_vector = input_vector.cuda()

        output_vector = lstm(input_vector)        

        target_vector = torch.zeros(output_vector.shape)

        if USE_CUDA and torch.cuda.is_available():
            target_vector = target_vector.cuda()

        for b in range(BATCH_SIZE):
            target_vector[b][vocab.get(training_data[i+b+SEQ_LEN])] = 1

        error = loss(output_vector, target_vector)

        error.backward()
        optimizer.step()

        loss_dict[(e, int(i/BATCH_SIZE))] = error.detach().item()

1 Ответ

1 голос
/ 26 апреля 2019

ОТВЕТ: Я допустил глупую ошибку при создании символов с обученной моделью: я запутался с размером пакета и предположил, что на каждом шаге сеть будет предсказывать целую серию новых символов, хотя на самом деле она только предсказывает одиночный ... Вот почему он просто повторил конец ввода. Хлоп!

В любом случае, если вы столкнетесь с этой проблемой, дважды проверьте, что у вас есть правильная логика для создания нового вывода с обученной моделью (особенно если вы используете пакеты). Если это не так и проблема не устранена, попробуйте выполнить тонкую настройку следующим образом:

  • длина последовательности

  • жадность (например, вероятностный выбор в сравнении с лучшим выбором для следующего символа)

  • размер партии

  • Эпоха

...