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

В этом руководстве мы будем использовать набор данных IMDb из пакета Keras. Набор данных содержит набор из 50 000 поляризованных обзоров из базы данных фильмов. Он уже разделен на две категории по 25 000 отзывов; один для обучения и один для тестирования. Каждый из двух наборов содержит 50% положительных и 50% отрицательных классов. Этот набор данных уже обработан, то есть последовательности слов уже преобразованы в целые числа, готовые к моделированию.

Подготовка данных

Как обычно, первое, что мы сделаем, это загрузим набор данных. Аргумент num_words=1000 означает, что мы сохраняем 10 000 наиболее часто встречающихся слов в обучающих данных. Редкие слова будут отброшены, что позволит нам работать с векторными данными приемлемого размера. Переменные train_data и test_data — это списки отзывов. train_labels и test_labels — это разные классы нулей и единиц, поскольку это проблема бинарной классификации.

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

  • дополнить списки, чтобы они имели одинаковую длину, превратив их в целочисленный тензор формы (выборки, word_indices), а затем использовать в качестве первого слоя в нашей сети слой способный обрабатывать целочисленные тензоры.
  • one-hot кодирует списки, чтобы превратить их в векторы 0 и 1. Это означает превращение последовательности [3,5] в 10 000-мерный вектор, который будет состоять из 0, кроме индексов 3 и 5, которые будут равны 1. Тогда мы сможем использовать первый слой в нашей NN в качестве плотного слоя, способного обрабатывать векторные данные с плавающей запятой.

Построение нейронной сети

Теперь данные готовы для использования в нашей нейронной сети. Входные данные — это векторы, а метки — масштаберы (1 и 0). Тип сети, которая хорошо справляется с такой задачей, представляет собой простой набор полностью связанных (плотных) слоев с активациями relu: (Dense(16, активации='relu').

Аргумент в каждом плотном слое (16) — это значение количества скрытых единиц или нейронов в слое. Скрытый блок – это измерение в пространстве представления слоя.

Наличие 16 скрытых единиц означает, что весовая матрица W будет иметь форму (input_dimension, 16): скалярное произведение с W проецирует входные данные на 16-мерное пространство представления (а затем мы добавим вектор смещения b и применим операцию relu). Наличие большего количества скрытых единиц (многомерное пространство представления) позволяет нашей сети обучаться более сложным представлениям, но также делает ее вычислительно затратной и может привести к изучению нежелательных шаблонов (переоснащение).

В отношении такого стека слоев Dense необходимо принять два ключевых архитектурных решения:

  • сколько слоев использовать
  • сколько скрытых юнитов выбрать для каждого слоя

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

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

Промежуточные слои будут использовать relu в качестве функции активации, а последний слой будет использовать сигмовидную активацию, чтобы вывести вероятность (показатель от 0 до 1, указывающий, насколько вероятно, что образец имеет целевое значение). 1).

Сборник моделей

Наконец, нам нужно выбрать функцию потерь, а также оптимизатор. Поскольку мы столкнулись с проблемой двоичной классификации, а выходом является вероятность (мы заканчиваем нашу сеть одноэлементным слоем с сигмовидной активацией), лучше всего использовать функцию потерь binary_crossentropy. Обычно это лучший выбор при работе с моделями, которые выводят вероятность. Мы передаем оптимизатору, функцию потерь, а также метрики в строках. Чтобы во время обучения отслеживать точность модели на данных, которые она никогда раньше не видела, нам нужно будет создать проверочный набор, выделив 10 000 выборок из исходных данных обучения.

Модель поезда

Теперь мы можем обучить модель на 20 эпох (20 итераций по всем выборкам в тензорах x_train и y_train) в мини-пакетах по 512 выборок. В то же время мы также отслеживаем потери и точность 10 000 выборок, которые мы выделили, передав аргумент validation_data. Вызов model.fit() возвращает объект History.

Оценка модели

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

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

Переобучайте модели и делайте прогнозы

Использование базового и наивного подхода дает точность 88%, однако, используя более индивидуальный и интуитивно понятный подход, мы можем достичь более высокой точности (около 95%).

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

Заключение

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