Если вы попали прямо на эту страницу, предлагаю начать читать первую часть этой статьи. В нем описывается, как создать модель RNN для создания текста, слово за словом.

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

Это могло бы быть улучшением, потому что при этом контекст абзаца (это описание сельской местности? Диалог между персонажами? Какие люди участвуют? Каковы предыдущие действия? И т. Д.) Может появиться и может быть использован для мудро выберите следующее предложение текста.

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

Для этого мы будем использовать Doc2Vec.

Примечание: записная книжка этой статьи доступна на github.

1. Doc2Vec

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

Короче говоря, мы преобразуем каждое предложение нашего текста в вектор определенного пространства. Самое замечательное в этом подходе - это то, что мы сможем их сравнить; например, чтобы получить наиболее похожее предложение из данного.

И последнее, но не менее важное: размерность векторов будет одинаковой, независимо от количества слов в их связанном предложении.

Это именно то, что мы ищем: я смогу обучить новый LSTM, пытаясь поймать шаблон из последовательностей векторов одинаковых размеров.

Скажу честно: я не уверен, что мы сможем выполнить такую ​​задачу с достаточной точностью, но давайте проведем несколько тестов. Это эксперимент, в худшем - хорошее упражнение.

Итак, как только все предложения будут преобразованы в векторы, мы попробуем обучить новый двунаправленный LSTM. Его цель будет заключаться в том, чтобы предсказать лучший вектор рядом с последовательностью векторов.

Тогда как мы будем генерировать текст?

Довольно просто: благодаря нашей предыдущей модели LSTM мы будем генерировать предложения в качестве кандидатов на роль следующей фразы. Мы определим их векторы, используя обученную модель doc2Vec, а затем выберем наиболее близкий к предсказанию нашей новой модели LSTM.

1.1 Создание модели Doc2Vec

Первая задача - создать нашу модель doc2vec, посвященную нашему тексту и встроенным предложениям.

Doc2Vec предполагает, что ввод - это список слов с меткой для каждого предложения:

Example: ['tobus', 'ouvre', 'la', 'porte', '.'] LABEL1

Таким образом, мы должны извлекать из текста каждое предложение и разделять их слова.

по соглашению я предполагаю, что предложение заканчивается на «.», «?», «!», «:» или «…». Сценарий читает каждый текст и создает новое предложение каждый раз, когда достигает одного из этих символов.

Сначала мы загружаем библиотеку Doc2Vec, загружаем наши данные и устанавливаем какой-то параметр:

  • все тексты хранятся в каталоге data_dir,
  • список file_list содержит имена всех текстовых файлов в каталоге data_dir,
  • save_dir будет использоваться для сохранения моделей.

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

1.2 Обучить модель doc2vec

Как объяснялось выше, doc2vec требовал правильной формы входных данных. Для этого мы определяем конкретный класс:

Я также создаю специальную функцию для обучения модели doc2vec. Его цель - легко обновить параметры обучения:

несколько замечаний относительно параметров функции: параметры по умолчанию были выбраны опытным путем.

Пришло время обучить модель doc2vec. Просто запустите команду:

Вот некоторые сведения об используемых параметрах:

  • размеры: 300 размеров подходят для классических сюжетов. В моем случае после нескольких тестов я предпочитаю выбрать 500 размеров,
  • эпохи: менее 10 эпох результаты недостаточно хороши (сходство плохо работает), а большее количество эпох создает слишком векторы с меньшими различиями. Поэтому я выбираю для обучения 20 эпох.
  • min_count: Я хочу включить в обучение все слова, даже те, которые встречаются очень редко. В самом деле, я полагаю, что для моего теста могут быть важны конкретные слова. Я установил значение 0, но от 3 до 5 должно быть нормально.
  • sample: 0.0. Я не хочу понижать частоту случайных слов с более высокой частотой, поэтому отключил эту функцию.
  • hs и dm: каждый раз, когда я хочу вывести новый вектор из обученной модели для данного предложения, я хочу иметь тот же выходной вектор . Для этого (как ни странно, это не так интуитивно) мне нужно использовать распределенный пакет слов в качестве алгоритма обучения (dm = 0) и иерархический softmax (hs = 1). Действительно, для моей цели распределительная память и отрицательная выборка дают менее хорошие результаты.

2. Создайте набор входных данных.

Используя свой обученный doc2Vec, я сделаю выводы для всех предложений моих текстов. Модель doc2vec предоставит напрямую вектор каждого предложения, нам просто нужно перебрать весь список предложений:

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

Теперь, чтобы создать набор входных данных Keras (X_train, y_train), мы должны следовать этим рекомендациям:

  • 15 секвенированных векторов из doc2vec в качестве входных,
  • следующий вектор (16-й) в качестве вывода.

Итак, размер X_train должен быть (количество последовательностей, 15, 500), а размер y_train: (количество последовательности, 500)

3. Создайте модель Keras.

Отлично, давайте сейчас создадим модель ...

Сначала мы загружаем библиотеку и создаем функцию для определения простой модели keras:

  • двунаправленный LSTM,
  • размером 512 и с использованием RELU в качестве активации,
  • затем дропаут слой 0,5.

Сеть предоставит мне не вероятность, а непосредственно следующий вектор для данной последовательности. Итак, я заканчиваю:

  • простой плотный слой размером с векторную размерность.

Я использую ADAM в качестве оптимизатора, и расчет потерь выполняется с помощью logcosh.

Затем создаем модель:

И тренируем его:

Большой ! Через несколько минут у нас есть модель для предсказания следующего лучшего вектора предложения для данной последовательности предложений.

Несколько замечаний по поводу результатов:

  • падение потерь до 0,1073, точность около 12,5%,
  • val_loss составляет около 0,1116 с точностью около 9%.

4. Вывод

Как вы, наверное, заметили, необработанный результат нейронных сетей, обученных во время урока, не впечатляет ... Мы, вероятно, сможем добиться большего, изменив архитектуру (добавив плотные слои и т. Д.)

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

Чтобы проверить это, мы должны для данной последовательности предложений:

  • генерировать, используя нашу первую модель LSTM, различные варианты предложений,
  • Сделайте выводы об их векторах, используя нашу модель doc2vec,
  • Сгенерируйте, используя нашу вторую модель LSTM, лучший следующий вектор,
  • затем выберите наиболее похожий вектор.

Это то, что я попытаюсь сделать в следующей части этого эксперимента ... следующая и последняя часть доступна здесь.

Спасибо за прочтение !