Создаём нейронную сеть InceptionV3 для распознавания изображений |
||||||||||||||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2017-02-15 18:23 Привет, Хабр! Под катом пойдёт речь о реализации свёрточной нейронной сети архитектуры InceptionV3 с использованием фреймворка Keras. Статью я решил написать после ознакомления с туториалом "Построение мощных моделей классификации с использованием небольшого количества данных". С одобрения автора туториала я немного изменил содержание своей статьи. В отличие от предложенной автором нейронной сети VGG16, мы будем обучать гугловскую глубокую нейронную сеть Inception V3, которая уже предустановлена в Keras.
Вы научитесь:
При написании статьи я ставил перед собой задачу представить максимально практичный материал, который раскроет некоторые интересные возможности фреймворка Keras. В последнее время всё чаще появляются туториалы, посвящённые созданию и применению нейронных сетей. С большим удовольствием наблюдаю за интересной тенденцией: новые посты становятся всё более и более понятными для неспециалистов в области программирования. Некоторые авторы и вовсе делают попытки введения читателей в эту тему, применяя максимально естественный язык. Есть также отличные статьи (напр. 1, 2, 3), которые сочетают разумное количество теории и практики, что позволяет как можно быстрее понять необходимый минимум и начать создавать что-то своё. Итак, за дело! Перво-наперво, немного про библиотеки: Рекомендую установить платформу Anaconda. Я использовал Python 2.7. Для работы удобно использовать Jupyter notebook. Он уже предустановлен на Anaconda. Нам также понадобится установить фреймворк Keras. В качестве бэкенда я использовал Theano. Вы можете использовать и Tensorflow, потому что Keras поддерживает их оба. Установка CUDA для Theano на Windows описана здесь. 1. Данные: В нашем примере мы будем использовать изображения с соревнования по машинному обучению под названием "Dogs vs Cats" на kaggle.com. Данные будут доступны после регистрации. Набор включает в себя 25000 изображений: 12500 кошек и 12500 собак. Класс 1 соответствует собакам, класс 0- кошкам. После загрузки архивов, разместите по 1000 изображений каждого класса в директориях следующим образом:
Вам ничего не мешает пользоваться всем набором данных. Я, также как и автор оригинальной статьи, решил использовать ограниченную выборку, чтобы проверить эффективность работы сети с малым набором изображений. У нас есть три проблемы:
При ограниченном объёме изображения высока вероятность переобучения. Для борьбы с этим нужно:
Последний пункт должен нас настораживать, потому что глубокая нейронная сеть требовательна к ресурсам. Я на своей видеокарте не смог обучить даже VGG16, не говоря уж о таком гигантище, как Inception. Тем не менее, решение есть:
Единственным решением проблемы со временем я пока что вижу применение параллельных вычислений. Вам для этого нужна видеокарта с поддержкой CUDA. Я надеюсь, что установка CUDA для Python не вызовет у вас сильных затруднений. Импортируем библиотеки:
2. Создадим модель InceptionV3, загрузим в неё изображения, сохраним их: Большая картинка со схемой наших действий В библиотеке Keras находится несколько подготовленных нейронных сетей. Список аргументов модели include_top: включать или не включать верхнюю часть сети, которая представляет из полносвязный слой с 1000 выходов. Создаём нашу модель:
Теперь сделаем аугментацию данных. Для этого в Keras предусмотрены так называемые ImageDataGenerator. Они будут брать изображения прямо из папок и проводить над ними все необходимые трансформации. Картинки каждого класса должны быть в отдельных папках. Для того, чтобы нам не загружать оперативную память изображениями, мы их трансформируем прямо перед загрузкой в сеть. Для этого используем метод .flow_from_directory. Создадим отдельные генераторы для тренировочных и тестовых изображений:
Хочу выделить важный момент. Мы указали shuffle=False. То есть, изображения из разных классов не будут перемешиваться. Сначала будут поступать изображения из первой папки, а когда они все закончатся, из второй. Зачем это нужно, увидите позже. Прогоним аугментированные изображения через обученную Inception и сохраним вывод в виде numpy массивов:
Процесс займёт некоторое время. 3. Создадим верхнюю часть модели, загрузим в неё данные, сохраним их: Схема В оригинальном посте автор использовал один слой сети с 256 нейронами, однако я буду использовать два слоя по 64 нейрона в каждом и Dropout слой со значением 0.5. Это изменение я был вынужден внести из-за того, когда я обучал готовую модель (которую мы сделаем в следующем шаге), мой компьютер зависал и перезагружался. Загрузим массивы:
Обратите внимание, ранее мы указывали shuffle=False. А теперь мы легко укажем labels. Поскольку в каждом классе у нас 2000 изображений и все изображения поступали по очереди, у нас будет по 1000 нулей и 1000 единиц для тренировочной и для тестовой выборок. Создадим модель FFN сети, скомпилируем её:
Загрузим в неё наши массивы:
Теперь мы загружаем данные не из папок, поэтому используем обычный метод fit. Процесс обучения будет неприлично быстрым. У меня каждая эпоха заняла 1 сек: Оценим точность модели:
[0.56735104312408047, 0.95650000000000002] Наша модель удовлетворительно справляется со своей задачей. Но принимает она только numpy массивы. Это нас не устраивает. Для того, чтобы получить полноценную модель, которая принимает на вход изображения, мы соединим две наши модели и обучим их ещё раз. 4. Создадим итоговую модель, загрузим в неё аугментированные данные, сохраним веса: Схема
Загрузим в неё веса:
Скажу честно, я не заметил никакой разницы между эффективностью обучения модели с загрузкой весов или без неё. Но оставил этот раздел, потому что он описывает, как загрузить веса в определённые слои по имени (by_name=True). Заблокируем с 1 по 205 слои Inception:
Скомпилируем модель:
Обратите внимание, когда мы в первый раз обучали полносвязные слои из .npy массивов, мы использовали оптимизатор RMSprop. Теперь, для тонкой настройки модели мы используем Стохастический градиентный спуск. Сделано это для того, чтобы предотвратить слишком выраженные обновления уже обученных весов. Сделаем так, чтобы в процессе обучения сохранялись только веса с наибольшей точностью на тестовой выборке:
Создадим новые генераторы изображений для обучения полной модели. Мы будем трансформировать только учебную выборку. Тестовую трогать не будем.
pred_generator мы используем позже для демонстрации работы модели. Загрузим изображения в модель:
Слышим шум кулера и ждём… У меня на каждую эпоху уходило по 210-220 секунд. 200 эпох обучения заняли около 12 часов. 5. Оценим точность модели
[0.2364250123500824, 0.9100000262260437] Вот нам и пригодился pred_generator. Обратите внимание, val_samples должны соответствовать величине batch_size в генераторе! Точность 91,7%. Учитывая ограниченность выборки, возьму на себя смелость сказать, что это неплохая точность. Проиллюстрируем работу модели Просто смотреть на % правильных ответов и величину ошибки нам не интересно. Давайте посмотрим, сколько правильных и неправильных ответов дала модель для каждого класса:
pred_generator.next() удобная штука. Она загружает изображения в переменную и присваивает лейблы. Количество изображений каждого класса будет различным при каждой генерации:
Сколько изображений каждого класса модель предсказала правильно? pd.crosstab(labels,rounded_pred)
Для модели было загружено 100 случайных изображений: 51 изображение кошек и 49 собак. Из 51 кошки модель правильно распознала 47. Из 50 собак правильно были распознаны 41. Общая точность модели на этой узкой выборке составила 88%. Посмотрим, какие фотографии были распознаны неправильно:
Синие числа-истинный класс изображений. Красные числа- предсказанные моделью (если красное число меньше 0.5, модель считает, что на фото кот, если больше 0.5, то собака). Чем больше число приближается к нулю, тем сеть больше уверена, что перед ней кот. Интересно, что много ошибок с изображениями собак содержат породы небольшого размера или щенков. Посмотрим первые 20 изображений, которые модель предсказала правильно:
Видно, что модель прилично справляется с задачей распознавания изображений на сравнительно небольших выборках. Я надеюсь, что пост был вам полезен. С удовольствием выслушаю ваши вопросы или пожелания. Источник: habrahabr.ru Комментарии: |
|||||||||||||