«В Квебеке нет мнений, а есть только чувства» - Уилфрид Лорье.

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

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

Классификация текста

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

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

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

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

1D сверточные слои

Сверточные нейронные сети (ConvNets) особенно хорошо справляются с проблемами компьютерного зрения из-за их способности работать сверточно, то есть извлекать функции из локальных входных патчей, обеспечивая модульность представления и эффективность данных. Те же свойства, которые делают ConvNets лучшим выбором для задач, связанных с компьютерным зрением, также делают их очень важными для обработки последовательностей. Сверточные слои 1D также инвариантны к трансляции в том смысле, что, поскольку одно и то же преобразование входных данных выполняется для каждого фрагмента, шаблон, изученный в определенной позиции в предложении, позже может быть распознан в другой позиции. Подобно 2D ConvNets, одномерные патчи могут быть извлечены из входа и вывести максимальное или среднее значение, процесс, технически называемый Max Pooling и Average Pooling соответственно, и, как и в случае 2D ConvNets, это также используется для уменьшения длины вход 1D (технически известный как субдискретизация).

Давайте теперь реализуем базовую 5-уровневую 1D ConvNet и воспользуемся ею, чтобы классифицировать набор данных обзоров фильмов IMDB как положительный или отрицательный.

Для начала загрузите и распакуйте необработанный набор данных IMDB отсюда. Затем мы извлечем отдельные обзоры обучения в список строк, по одной строке на обзор, а также соберем метки обзора в список, в котором положительный отзыв обозначен как 1, а отрицательный - как 0.

После этого мы токенизируем наши данные. Токенизация - это процесс разбиения последовательности строк на более мелкие части, такие как слова, ключевые слова, фразы, символы и другие элементы, называемые токенами. (Источник: Техопедия). Текст в каждом обзоре фильма векторизуется, и после перетасовки набор данных соответственно разделяется на данные для обучения и тестирования.

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

Вложения слов

Один из эффективных способов связать слово с вектором - использовать плотные векторы слов, также известные как вложения слов. Векторы, полученные с помощью однократного кодирования, в основном очень разреженные и очень многомерные (размерность такая же, как и у количества слов в словаре). Однако вложения слов представляют собой векторы с плавающей запятой малой размерности, и в отличие от векторов, полученных в результате однократного кодирования, вложения слов изучаются из имеющихся данных. При разработке нашей модели мы будем использовать слой Embedding в Keras, чтобы сгенерировать 50-мерное вложение слов из нашего набора данных.

Построение модели

Наконец, мы строим нашу модель, используя Keras Functional API. Функциональный API Keras дает нам гибкость, необходимую для создания графоподобных моделей, совместного использования слоя для разных входных данных и использования моделей Keras так же, как функций Python. Как было сказано ранее, это будет 5-слойная 1D ConvNet, которая сглаживается в конце с помощью слоя GlobalMaxPooling1D и подается на слой Dense. В качестве альтернативы для выполнения этой задачи также можно использовать слой Flatten. Затем мы делаем наш прогноз, передавая вектор, полученный из плотного слоя, на другой плотный слой из 1 единицы и функцию активации сигмоида. Мы выбрали сигмовидную функцию активации на выходном слое, потому что наша задача классификации включает только два класса (положительный или отрицательный). Код для построения модели вставлен ниже:

На рисунке ниже также показан сопроводительный график модели, созданной с помощью TensorBoard.

Когда модель готова к использованию, мы приступим к ее адаптации к данным обучения и проверки, используя следующий код:

Обратные вызовы

Мы склонны терять контроль над тем, как наша модель обучается на предоставленном наборе данных в тот момент, когда мы вызываем метод fit () или fit_generator () в нашей модели, и это означает, что с моделью, недостаточно «умной», мы можем только наблюдать, как она работает очень хорошо. плохо во время тренировки или бросьте тренировку и начните все заново. Этот процесс действительно может быть дорогостоящим и неэффективным, поэтому, чтобы избежать этого, мы хотели бы разработать модель, которая может самоанализ и динамически предпринимать действия, которые положительно повлияют на обучение. Есть много вещей, которые нельзя предсказать во время тренировки. Например, нельзя сказать точное количество эпох, которое потребуется для достижения оптимальных потерь при проверке и точности.

В основном во время обучения мы склонны использовать произвольное количество эпох, и если модель выходит за рамки до того, как это количество эпох будет достигнуто, мы уменьшаем количество эпох и тренируемся снова, в противном случае мы увеличиваем количество эпох, и этот подход очень расточителен. Гораздо лучший способ справиться с этим во время обучения - прекратить обучение, когда мы поймем, что потеря валидации больше не улучшается. Этого можно добиться с помощью обратного вызова Keras. Обратный вызов - это объект (экземпляр класса, реализующий определенные методы), который передается модели в вызове для соответствия и вызывается моделью в различные моменты во время обучения. У него есть доступ ко всем доступным данным о состоянии модели и ее производительности, и он может принимать меры: прерывать обучение, сохранять модель, загружать другой набор весов или иным образом изменять состояние модели.

Некоторые способы использования обратных вызовов:

  • Контрольная точка модели - сохранение текущих весов модели в разных точках во время обучения.
  • Ранняя остановка - прерывание обучения, когда потеря валидации больше не улучшается (и сохраняется лучшая модель, полученная во время обучения).
  • Динамическая регулировка значений определенных параметров во время обучения, таких как оптимизатор скорости обучения.
  • Регистрация показателей обучения и проверки во время обучения или визуализация представлений, усвоенных моделью по мере их обновления. (Индикатор выполнения Keras мы всегда видим в нашем терминале во время тренировки!)

Ниже показан фрагмент того, как реализовать обратные вызовы в Keras:

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

Аргумент монитора в обратном вызове EarlyStopping контролирует точность проверки модели, а аргумент терпения прерывает обучение, когда параметр, переданный аргументу монитора, перестает улучшаться, если ему передано больше, чем число (эпох) (в данном случае 1).

Аргумент filepath в обратном вызове ModelCheckpoint сохраняет текущие веса после каждой эпохи в файл модели назначения, а аргументы monitor и save_best_only означают, что мы не переопределим файл модели, пока не улучшится потеря проверки (val_loss). Это позволяет нам сохранять лучшую модель, увиденную во время обучения.

Кроме того, обратный вызов ReduceLROnPlateau используется для снижения скорости обучения, когда потеря проверки перестала улучшаться. Это оказалось очень эффективной стратегией для выхода из локальных минимумов во время тренировки. Аргумент фактора принимает в качестве входных данных число с плавающей запятой, которое используется для деления скорости обучения при срабатывании триггера.

Тензорборд

Основная цель TensorBoard - помочь нам визуально контролировать все, что происходит внутри нашей модели во время обучения. Tensorboard дает нам доступ к нескольким важным функциям, таким как

  • визуальный мониторинг показателей во время обучения
  • визуализация архитектуры нашей модели
  • визуализация гистограмм активаций и градиентов
  • изучение вложений в 3D

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

$ mkdir log_dir_m1

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

На этом этапе мы можем запустить сервер TensorBoard из командной строки, указав ему прочитать журналы, которые обратный вызов в настоящее время записывает. Tensorboard автоматически устанавливается вместе с Tensorflow, и его можно запустить с помощью приведенной ниже команды в командной строке.

$ tensorboard --logdir=log_dir_m1

После запуска сервера мы можем перейти к http: // localhost: 6006 и посмотреть на обучение модели. Помимо показателей обучения и проверки,

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

TensorBoard также генерирует графическую архитектуру нашей модели. Вкладка встраивания также дает нам возможность проверить места встраивания и пространственные отношения 10000 слов во входном словаре, полученные слоем встраивания, но поскольку пространство встраивания 50-мерное, TensorBoard автоматически уменьшает его до 2D или 3D, используя размерность. алгоритмы редукции, такие как анализ главных компонентов (PCA) или T-распределенное стохастическое соседнее вложение (t-SNE). В облаке точек на рисунке ниже мы можем ясно видеть два кластера, обозначающих слова с положительной коннотацией и слова с отрицательной коннотацией. Это показывает, что вложения в нашей модели обучены специально для данной задачи (то есть классификации рейтингов фильмов), и это одна из основных причин, по которой рекомендуется обучать встраивание слов на основе конкретной задачи вместо использования предварительно обученных общие вложения слов. (Я нашел это подробное руководство по TensorBoard очень полезным, и вы можете проверить его, чтобы глубже погрузиться в TensorBoard.)

Прогнозы

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

Загрузка модели и токенизатора

Во время предварительной обработки данных мы использовали Tokenizer в Keras в нашем наборе данных, чтобы преобразовать его из текста в последовательности перед заполнением, чтобы обеспечить согласованность входных данных для нашего слоя. Во время скоринга тестовых данных было бы логично, если бы мы использовали тот же токенизатор, который мы использовали для наших обучающих данных, и для тестовых данных. Чтобы достичь этого, нам нужно было бы сохранить токенизатор, который подходил для обучающих данных, как объект pickle. Поэтому после токенизации обучающих данных в Части 1 мы используем следующий код для сохранения токенизатора как объекта pickle.

Кроме того, во время обучения мы смогли сохранить лучшую полученную модель как «movie_sentiment_m1.h5» в каталоге под названием model. Поэтому мы загрузим модель с помощью метода load_model в классе моделей Keras, а также загрузим токенизатор, который был сохранен как объект pickle, используя метод load в модуле pickle. Описанный выше процесс может быть выполнен с помощью кода из приведенного ниже фрагмента.

Имея под рукой нашу модель и токенизатор, мы продолжим и напишем простой скрипт для оценки наших текстовых образцов (находится в папке test_dir в репозитории github).

Оценка образцов текста

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

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

Для начала мы сначала напишем простой метод, который принимает в качестве аргументов оценку обзора и обзора, который был оценен, и на основе этой оценки шкала полярности от «Сильно положительного» до «Отрицательного» присваивается оценке. оценка и результат распечатывается.

Затем мы пишем другой метод декодирования обзора (аналогично тому, что было сделано в Части 1). Этот метод принимает в качестве входных данных список строковых объектов (содержащих текст), которые преобразуются в последовательности с помощью нашего токенизатора, а затем дополняются, чтобы соответствовать длине ввода, которая использовалась для модели во время обучения. Затем этот метод возвращает декодированный обзор и дополненную последовательность.

Наконец, мы добавляем последний метод, который будет принимать данные в различных форматах. Этот метод принимает в качестве аргументов источник текста и тип файла (если это файл или каталог файлов). Затем мы обрабатываем их согласно источнику. По сути, используя источник в виде простой строки, мы добавляем ее в список и передаем этот список методу декодированного обзора, который возвращает последовательность в ее дополненной форме и декодированный обзор. Затем мы вызываем метод predic () для модели и передаем ему заполненную последовательность, чтобы получить оценку. Вместе с оценкой и декодированным обзором мы передаем эту информацию методу review_rating, чтобы получить красивый результат для отображения. Данные из других источников (каталог файлов списка текстов строк) в основном проходят аналогичные процессы, в циклах for.

Затем мы можем продолжить и протестировать метод обзора оценок, используя образцы данных, доступные в репозитории test_dir, используя следующий код:

score_review('test_dir/test', file_type='dir')

Образец выходных данных, полученных в результате тестирования образцов обзора в форматах файлов внутри тестового каталога (находится в папке test_dir в репозитории github), показан на изображении ниже.

Вывод

В этом посте мы смогли понять основы встраивания слов, токенизации и одномерной сверточной нейронной сети, а также почему она подходит для классификации текста и обработки последовательности. Мы также узнали о концепции обратных вызовов, ее важности и о том, как реализовать ее во фреймворке Keras. Мы успешно протестировали нашу модель на тестовых данных из разных вымышленных источников. Наконец, мы увидели, как построить многоуровневую репрезентативную сеть с использованием функциональных API в Keras. Я надеюсь, что мы все получили удовольствие от этого проекта и узнали массу хороших вещей по пути. Хорошего дня!

Я очень благодарен Франсуа Шоле за его книгу по глубокому обучению и Стивену Берду, Юэну Кляйну и Эдварду Лоперу за их книгу по обработке естественного языка. Я также благодарен Эндрю Траску за его твит, который поощрял написание любой новой информации или полученных знаний, поскольку только объясняя то, что вы узнали, вы можете узнать то, что вы действительно узнали.

Прочтите эту статью, чтобы глубже погрузиться в Tensorboard: https://bit.ly/2STa5Ax