В этом посте мы покажем, как построить глубокую нейронную сеть, которая может классифицировать изображения с точностью 90%, что было очень сложно до появления глубоких нейронных сетей, особенно сверточных нейронных сетей.
Глубокое обучение — одна из самых интересных тем в области искусственного интеллекта, оно было разработано на основе концепций из области биологии и теперь представляет собой набор алгоритмов.
Факты доказали, что глубокое обучение может сыграть очень хорошую роль во многих областях, таких как компьютерное зрение, обработка естественного языка и распознавание речи.
За последние 6 лет глубокое обучение применялось в очень широком диапазоне областей, и многие недавние технологические прорывы связаны с глубоким обучением.
Вот несколько примеров:Беспилотные автомобили Tesla, система маркировки фотографий Facebook, виртуальные помощники, такие как Siri или Cortana, чат-боты, камеры, способные распознавать объекты, — все это технологические прорывы благодаря глубокому обучению.
Во многих областях производительность глубокого обучения в когнитивных задачах, таких как понимание языка и анализ изображений, достигла человеческого уровня.
Как построить глубокую нейронную сеть, которая может достичь точности 90% в задачах классификации изображений?
Эта проблема может показаться очень простой, но до появления глубоких нейронных сетей, особенно сверточных нейронных сетей (CNN), это была сложная проблема, которую ученые-компьютерщики изучали в течение многих лет.
Эта статья разделена на следующие три части, чтобы объяснить:
-
показать наборы данных и варианты использования,И объясните сложность этой задачи классификации изображений.
-
Создайте специальную среду для глубокого обучения,Эта среда построена на базе сервиса EC2 на базе графического процессора AWS.
-
Обучите две модели глубокого обучения:Первая модель представляет собой сквозной конвейер с нуля с использованием Keras и TensorFlow, а другая модель использует нейронную сеть, предварительно обученную на большом наборе данных.
Интересный пример: классификация изображений кошек и собак
Существует множество наборов данных изображений, предназначенных для сравнительного анализа моделей глубокого обучения, набор данных, который я использовал в этом посте, взят из конкурса Cat vs Dogs Kaggle, этот набор данных содержит большое количество собак и кошек с изображением метки.
Как и каждое соревнование Kaggle, этот набор данных содержит две папки:
-
папка для тренировок:Он содержит 25 000 изображений кошек и собак, каждое из которых имеет тег как часть имени файла. Мы будем использовать эту папку для обучения и оценки нашей модели.
-
Тестовая папка:Он содержит 12 500 изображений, каждое из которых названо числом. Для каждого изображения в этом наборе данных наша модель предсказывает, является ли изображение собакой или кошкой (1 = собака, 0 = кошка). Фактически, эти данные также используются Kaggle для оценки моделей, а затем ранжирования их в списках лидеров.
Давайте посмотрим на характеристики этих изображений.Эти изображения различны и имеют разное разрешение. Кошки и собаки на картинках имеют разную форму, расположение и цвет тела.
У них разные позы, одни сидят, а другие нет, их настроение может быть радостным или грустным, кошка может спать, а собака лаять. Фотографии можно делать на любом фокусном расстоянии и под любым углом.
Возможности этих изображений безграничны, и для нас, людей, естественно, легко идентифицировать домашнее животное в сцене из серии фотографий разного типа, но для машины это нетривиальная задача.
На самом деле, если машины должны выполнять автоматическую классификацию, нам нужно знать, как четко охарактеризовать кошек и собак, то есть почему мы думаем, что это изображение — кошка, а то — собака. Это требует изображения внутренних характеристик каждого животного.
Причина, по которой глубокие нейронные сети так хорошо работают с задачами классификации изображений, заключается в их способности автоматически изучать несколько уровней абстракции, которые при заданной задаче классификации дают более простые представления признаков для каждого класса.
Глубокие нейронные сети могут распознавать паттерны экстремальных вариаций и устойчивы к искаженным изображениям и изображениям, подвергнутым простым геометрическим преобразованиям.Давайте посмотрим, как глубокие нейронные сети справляются с этой проблемой.
Настройка среды глубокого обучения
Глубокое обучение требует больших вычислительных ресурсов, и вы можете испытать это на собственном опыте, запустив модель глубокого обучения на своем собственном компьютере.
Но если вы используете графические процессоры, скорость обучения будет значительно увеличена, потому что графические процессоры очень эффективны в задачах параллельных вычислений, таких как умножение матриц, а нейронные сети почти заполнены операциями умножения матриц, поэтому вычислительная производительность будет невероятной.
У меня нет мощного графического процессора на моем собственном компьютере, поэтому я решил использовать виртуальную машину в Amazon Cloud Services (AWS) под названием p2.xlarge, которая является частью Amazon EC2.
Конфигурация этой виртуальной машины включает графический процессор Nvidia с 12 ГБ видеопамяти, 61 ГБ ОЗУ, 4 виртуальных ЦП и 2496 ядер CUDA.
Вы можете видеть, что это бегемот по производительности, и приятно, что мы можем использовать его всего за 0,90 доллара в час. Конечно, вы можете выбрать другие виртуальные машины, которые лучше сконфигурированы, но для задач, с которыми мы будем иметь дело прямо сейчас, виртуальной машины p2.xlarge более чем достаточно.
Моя виртуальная машина работает в системе Deep Learning AMI CUDA 8 Ubuntu Version, теперь давайте лучше разберемся в этой системе.
Эта система основана на сервере Ubuntu 16.04, который упаковал все необходимые нам фреймворки глубокого обучения (TensorFlow, Theano, Caffe, Keras) и установил драйвер графического процессора (я слышал, что установка драйвера самостоятельно — это кошмар).
Если вы не знакомы с AWS, вы можете обратиться к следующим двум статьям:
-
https://blog.keras.io/running-jupyter-notebooks-on-gpu-on-aws-a-starter-guide.html
-
https://hackernoon.com/keras-with-gpu-on-amazon-ec2-a-step-by-step-instruction-4f90364e49ac
Эти две статьи могут сообщить вам две вещи:
-
Настройте и подключитесь к виртуальной машине EC2.
-
Настройте сеть для удаленного доступа к Jupyter Notebook.
Создание классификатора изображений кошек/собак с помощью TensorFlow и Keras
После того, как среда настроена, мы начинаем строить сверточную нейронную сеть, которая может классифицировать изображения кошек и собак, и использовать фреймворки глубокого обучения TensorFlow и Keras.
Давайте сначала представим Keras: Keras — это высокоуровневый API-интерфейс нейронной сети, написанный на чистом Python и основанный на бэкэнде Tensorflow, Theano и CNTK.Keras создан для поддержки быстрых экспериментов и может быстро преобразовывать ваши идеи в результаты.
Создание сверточной нейронной сети с нуля
Во-первых, мы настроили сквозной конвейер для обучения CNN,Он пройдет следующие этапы: подготовка и дополнение данных, проектирование архитектуры, обучение и оценка.
Мы построим график потерь и показателей точности для обучающих и тестовых наборов, что позволит нам более интуитивно оценить, как модель улучшилась с течением времени.
подготовка данных
Прежде чем приступить к работе, первое, что нужно сделать, — загрузить и разархивировать обучающий набор данных с Kaggle.
Нам пришлось реорганизовать данные, чтобы Керасу было проще их обрабатывать. Создаем папку data и внутри нее создаем две подпапки:
-
train
-
validation
Ниже двух папок выше каждая папка по-прежнему содержит две подпапки:
-
cats
-
dogs
В итоге получаем следующую файловую структуру:
data/
train/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001.jpg
cat002.jpg
...
validation/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001.jpg
cat002.jpg
Эта файловая структура позволяет нашей модели узнать, из какой папки брать изображения и метки для обучения или тестирования. Вот функция, которая позволяет вам перестроить это файловое дерево,Имеет 2 параметра: общее количество изображений, вес тестового набора r.
Я использовал:
-
n: 25000 (размер всего набора данных)
-
р: 0,2
-
ratio = 0.2
-
n = 25000
-
organize_datasets(path_to_data='./train/',n=n, ratio=ratio)
Теперь давайте загрузим Keras и его зависимости:
Генератор изображений и увеличение данных
При обучении модели мы не загружаем весь набор данных в память, потому что это неэффективно, особенно если вы все еще используете свой собственный локальный компьютер.
Мы будем использовать класс ImageDataGenerator, который может без ограничений принимать поток изображений из обучающих и тестовых наборов. В классе ImageDataGenerator мы будем вводить случайные модификации в каждой партии.
Мы называем этот процесс увеличением данных. Он может генерировать больше изображений, чтобы наша модель не видела двух одинаковых изображений. Этот подход предотвращает переоснащение, а также помогает модели поддерживать лучшее обобщение.
Мы собираемся создать два объекта ImageDataGenerator. train_datagen соответствует тренировочному набору, val_datagen соответствует тестовому набору, оба будут масштабировать изображение, а train_datagen также внесет некоторые другие изменения.
Затем на основе двух предыдущих объектов мы создаем два генератора файлов:
-
train_generator
-
validation_generator
Каждый генератор может генерировать пакеты данных изображения в каталоге с дополнением данных в реальном времени. Таким образом, данные будут генерироваться в бесконечном цикле.
Структура модели
Я буду использовать CNN с 3 слоями свертки/объединения и 2 полносвязными слоями. 3 сверточных слоя будут использовать 32, 32, 64 фильтра 3*3 соответственно. На двух полносвязных слоях я использовал отсев, чтобы избежать переобучения.
Я использую стохастический градиентный спуск для оптимизации с параметрами скорости обучения 0,01 и импульса 0,9.
Keras предоставляет очень удобный способ показать полную картину модели. Для каждого слоя мы можем видеть форму вывода и количество обучаемых параметров. Целесообразно проверить перед тем, как приступить к примерке модели.
model.summary()
Давайте посмотрим на структуру сети.
Структурная визуализация
Перед обучением модели я определяю две функции обратного вызова, которые будут вызываться во время обучения:
-
Один используется для раннего прекращения обучения, когда функция потерь не может улучшить производительность на тестовых данных.
-
Один для хранения показателей потерь и точности для каждой эпохи: его можно использовать для построения графика ошибки обучения.
Я также использую keras-tqdm, отличный индикатор выполнения, который идеально интегрируется с keras. Это позволяет нам очень легко контролировать процесс обучения модели.
Чтобы использовать его, вам просто нужно загрузить класс TQDMNotebookCallback из keras_tqdm и передать его в качестве третьей функции обратного вызова.
На рисунке ниже показано действие keras-tqdm на простом примере.
Еще несколько слов о тренировочном процессе:
-
Мы используем метод fit_generator, который представляет собой вариант (стандартный метод подбора), который принимает генератор в качестве входных данных.
-
Мы обучаем модель более 50 эпох.
Эта модель очень затратна в вычислительном отношении:
-
Если бы вы работали на своем собственном компьютере, каждая эпоха занимала бы 15 минут.
-
Если вы, как и я, работаете на виртуальной машине p2.xlarge на EC2, это занимает 2 минуты на каждую эпоху.
Результат классификации
Мы достигли точности 89,4% после запуска модели в течение 34 эпох (погрешность обучения/тестирования и точность показаны ниже), что является хорошим результатом, учитывая, что я не тратил много времени на проектирование структуры сети. Теперь мы можем сохранить модель для дальнейшего использования.
model.save(`./models/model4.h5)
Ниже мы наносим значения метрик потерь при обучении и тестировании на одном графике:
Мы прервали процесс обучения, когда значение тестовых потерь не улучшилось в течение двух последовательных эпох.
Ниже приведены графики точности обучающих и тестовых наборов.
Эти две метрики увеличивались до тех пор, пока модель не начала переход на плато переобучения.
Загрузите предварительно обученную модель
Мы добились хороших результатов с нашими CNN, но есть еще один способ получить более высокие баллы: напрямую загрузить веса сверточной нейронной сети, предварительно обученной на большом наборе данных, который содержит изображения 1000 видов кошек и собак.
Такая сеть будет изучать особенности, имеющие отношение к нашей задаче классификации.
Я собираюсь загрузить веса сети VGG16, в частности, я собираюсь загрузить веса сети во все сверточные слои. Эта часть сети будет действовать как детектор функций для обнаружения функций, которые мы добавим к полностью связанным слоям.
По сравнению с LeNet5, VGG16 — это очень большая сеть с 16 слоями, которая может обучать весам и 140 миллионам параметров.Чтобы узнать о VGG16, см. эту ссылку в формате PDF: https://arxiv.org/pdf/1409.1556.pdf
Теперь мы передаем изображение в сеть, чтобы получить представления функций, которые будут использоваться в качестве входных данных для классификатора нейронной сети.
Изображения передаются по сети по порядку, поэтому мы можем легко связать метку с каждым изображением.
Теперь мы проектируем небольшую полносвязную нейронную сеть с дополнительными функциями, извлеченными из VGG16,Мы используем его как классификационную часть CNN.
После 15 эпох модель достигла точности 90,7%. Этот результат уже хорош, обратите внимание, что каждая эпоха теперь занимает всего 1 минуту для запуска на моем собственном компьютере.
Многие громкие имена в области глубокого обучения призывают всех использовать предварительно обученные сети для задач классификации, Фактически, предварительно обученные сети обычно используют очень большие сети, созданные на очень большом наборе данных.
А Keras позволяет нам легко загружать предварительно обученные сети, такие как VGG16, GoogleNet, ResNet.Для получения дополнительной информации об этом, пожалуйста, обратитесь сюда: https://keras.io/applications/
Есть хорошая поговорка: не будь героем! Не изобретайте велосипед! Используйте предварительно обученную сеть!
Что можно сделать дальше?
Если вы заинтересованы в улучшении традиционной CNN, вы можете:
-
На уровне набора данных вводятся дополнительные данные.
-
Изучите гиперпараметры сети: количество сверточных слоев, количество и размер фильтров и проверьте эффект после каждой комбинации.
-
Измените метод оптимизации.
-
Попробуйте разные функции потерь.
-
Используйте более полносвязные слои.
-
Внедрить более агрессивный отсев.
Если вы заинтересованы в получении лучших результатов классификации с помощью предварительно обученной сети, вы можете попробовать:
-
Используйте другую структуру сети.
-
Используйте более полносвязные слои с большим количеством скрытых единиц.
Если вы хотите узнать, чему научилась модель глубокого обучения CNN, вы можете:
-
Визуализируйте карты объектов.
-
Вы можете обратиться к: https://arxiv.org/pdf/1311.2901.pdf
Если вы хотите использовать обученную модель:
-
Модель можно разместить в веб-приложении и протестировать с новыми изображениями кошек и собак. Это также хороший способ хорошо проверить обобщение вашей модели.
Суммировать
Это пошаговое руководство, которое поможет вам создать среду глубокого обучения на AWS и научит вас создавать сквозную модель с нуля. В этой статье также рассказывается, как построить модель CNN на основе предварительно обученная сеть.
Глубокое обучение в Python — это радость, а Keras значительно упрощает предварительную обработку данных и построение сетевых слоев.
Если однажды вам понадобится построить нейронную сеть в соответствии с вашими собственными идеями, вам могут понадобиться другие фреймворки глубокого обучения.
Сейчас в области обработки естественного языка многие начали использовать сверточные нейронные сети, вот некоторые работы, основанные на этом:
-
Классификация текстов с использованием CNN:
https://chara.cs.illinois.edu/sites/sp16-cs591txt/files/0226-presentation.pdf
-
Автоматически генерировать подписи к изображениям:
https://cs.stanford.edu/people/karpathy/sfmltalk.pdf
-
Классификация текстов на уровне слов:
https://papers.nips.cc/paper/5782-character-level-convolutional-networks-fortext-classification.pdf
Авторы: Ахмед Бесбес, Чжан Шэнцянперевести
Монтажер: Тао Цзялун, Сунь Шуцзюань
Вклад: Для тех, кто заинтересован в представлении статей, пожалуйста, свяжитесь с editor@51cto.com