Принесите модель классификатора породы собаки, когда пойдете в парк для собак.
Введение
Цель этого проекта — определить породу собаки по изображению. Что самое интересное, система сначала определит, является ли изображение собакой или человеческим лицом. В случае с собакой он предскажет породу собаки. В случае человека он предскажет породу собак, на которую больше всего похож человек. Этот проект был разработан как завершающий проект для Data Scientist Nanodegree в Udacity.
Технология глубокого обучения превзошла любой другой традиционный алгоритм искусственного интеллекта в решении проблем, связанных с восприятием. Как люди, мы отдаем должное эволюции, которая позволила нам видеть, слушать, обонять и чувствовать мир вокруг нас. Каждый день мы видим несколько примеров технологии глубокого обучения, позволяющей компьютерам видеть, слушать и говорить! Эти узкие решения ИИ могут быть не такими интуитивными, как люди, но интересно наблюдать, как эти математические модели с небольшим количеством времени и усилий могут творить чудеса!
В этом случае выбор использования сверточных нейронных сетей и OpenCV очевиден. Модель обучалась на наборе данных, предоставленном Udacity, который содержит 133 категории пород собак и 8351 изображение. И я использовал рабочее пространство Udacity с поддержкой графического процессора с Keras и Tensorflow для обучения моделей.
Исследование и визуализация данных
Набор данных Humans, также предоставленный Udacity, содержал 13233 изображения. Набор данных о собаках содержит 133 различных категории пород собак и 8351 изображение собак. Из них 6680 изображений использовались для обучения, 835 — для проверки и 836 — для тестирования.
Как видите, набор данных сбалансирован в среднем по 50 изображений на класс породы собак. Поскольку это проблема классификации, я решил использовать точность в качестве метрики оценки. Если бы набор данных был слишком несбалансированным, то точность была бы подходящим выбором.
Давайте посмотрим на эти изображения собак.
Отдельные изображения были разного размера и ориентации, но большинство из них находились в диапазоне 300–500 пикселей по высоте и ширине. На этапе предварительной обработки размеры этих изображений были изменены до 224x224 пикселей, чтобы соответствовать архитектуре сети. Распределение высоты и ширины показано ниже.
Это собака или человек?
Каскадный классификатор Хаара на основе признаков OpenCV использовался для определения того, является ли изображение человеческим лицом или нет. Этот детектор был протестирован на первых 100 изображениях из наборов данных человека и собаки. Он достиг 100% точности на изображениях людей, но также распознал 11% изображений собак как человеческие лица.
Для обнаружения собак я использовал предварительно обученную модель ResNet-50, которая была обучена на известном наборе данных ImageNet. Модель ResNet-50 имеет те же 133 категории пород собак как часть выходных классов. Детектор собак был протестирован на том же наборе изображений, упомянутом выше, и он достиг 100% точности на изображениях собак, и он не обнаружил собак в наборе данных с человеческими лицами.
Хочу отметить, что определение породы собаки – непростая задача. Даже человеку было бы трудно отличить бретани от вельш-спрингер-спаниеля. Также лабрадоры бывают трех оттенков — желтого, шоколадного и черного. Наш алгоритм, основанный на зрении, должен будет преодолеть эту высокую внутриклассовую вариацию, чтобы определить, как классифицировать все эти разные оттенки как одну и ту же породу. Ну, если вы эксперт по собакам, то у вас может быть некоторое преимущество.
Предварительная обработка данных
При использовании TensorFlow в качестве бэкэнда, CNN Keras требуют в качестве входных данных 4D-массив с формой,
(nb_samples, строки, столбцы, каналы)
где nb_samples соответствует общему количеству изображений, а строк, столбцов и каналы соответствуют количеству строк, столбцов и каналов для каждого изображения соответственно. Поскольку мы имеем дело с цветными изображениями, количество каналов равно 3. И мы также изменяем размер всех изображений до квадратного изображения размером 224×224пикселя.
Для решения этой задачи была реализована функция предварительной обработки. Результатом этой функции является четырехмерный массив формы (nb_samples, 224, 224, 3). Поскольку я планирую использовать предварительно обученные модели, эта функция также включает дополнительный шаг нормализации, который вычитает средний пиксель (выраженный в RGB как [103,939,116,779,123,68]) из каждого изображения.
Создание CNN с нуля
Первый шаг — попытаться создать модель CNN с нуля. Учитывая сложность задачи, обучение модели CNN, обеспечивающей хорошую точность, потребует много времени и вычислительных ресурсов. Учитывая намерение нашего проекта, давайте определим пределы. Поскольку у нас есть 133 выходных класса, точность случайного выбора ниже 1%. Таким образом, все, что лучше случайного, является успехом.
Я использовал приведенную выше архитектуру CNN для первого эксперимента. Я определил несколько сверточных фильтров увеличивающегося размера (8, 16, 32), что является стандартной практикой при построении CNN.
Мы можем принять безопасное предположение, что соседние пиксели в наших изображениях похожи, и использовать слой MaxPooling для уменьшения размеров входных изображений в слоях CNN. Это также уменьшит вероятность переобучения, но не сильно повлияет на способность прогнозирования нашей модели. Я выбрал длину шага 2, так как он бежал намного быстрее.
И я также использовал GlobalAveragePooling, поскольку это рекомендуется в CNN для уменьшения пространственных измерений.
Я тренировал модель всего 5 эпох, так как она достигла точности теста 4,3%. Мы можем продолжать улучшать нашу модель, добавляя больше слоев и обучая большее количество эпох. Но мы также можем проявить смекалку и использовать трансфертное обучение в своих интересах.
Перенос обучения на помощь
Если я и видел дальше других, так это стоя на плечах гигантов.
Сэр Исаак Ньютон
Трансферное обучение позволяет нам использовать знания, полученные при решении одной проблемы, для решения другой, но связанной проблемы. Например, мы можем использовать модели, обученные на данных ImageNet, для решения задачи классификации пород собак. Здесь мы сохраняем слои, соответствующие части извлечения признаков из предварительно обученных моделей, и обучаем только окончательные слои классификации. Поскольку извлечение признаков является наиболее мучительной частью обучения модели, повторное его использование позволяет нам достичь хороших результатов с меньшими вычислительными ресурсами и временем.
Во-первых, я использовал узкие места из модели VGG16 и добавил только глобальный средний пул и плотные слои в последнюю очередь. Мне удалось добиться точности обучения 43% и точности теста 35% после обучения только для 20 эпох, и каждая эпоха занимала всего пару секунд. Я также заметил, что точность проверки продолжала расти по мере того, как я тренировался в течение большего количества эпох.
Затем я использовал узкие места из модели InceptionV3 для обучения другого классификатора. Как и в предыдущем эксперименте, я добавил слой GlobalAveragePooling, который сохраняет только важную информацию и значительно снижает размерность. Последний плотный слой используется для прогнозирования 133 категорий пород собак.
InceptionV3 обучается на наборе данных ImageNet, состоящем из 15 миллионов изображений, но в нашем наборе данных примерно 6000 изображений. Эта разница в размерах наборов данных приведет к переоснащению модели, поэтому я добавил слой Dropout, чтобы уменьшить переоснащение.
Оценка модели
Точность обучения и проверки для первых 30 эпох показана ниже.
Из этого графика видно, что модель все еще переоснащается. Это может быть связано с относительно небольшим размером нашего обучающего набора данных. У нас есть 133 категории и всего 6680 обучающих изображений, что означает лишь небольшой набор изображений для каждой категории.
Модель достигла точности теста 78% после обучения в течение 30 эпох. Обучение большему количеству эпох или настройка архитектуры модели могут не улучшить наши результаты. Более разумный подход состоит в том, чтобы поэкспериментировать с увеличением данных, чтобы увеличить дисперсию наших обучающих данных, что повысит точность проверки.
При тестировании на новых изображениях моя модель работала так, как я ожидал, не идеально, но достаточно хорошо. Как видно из этих тестовых изображений, моя модель может правильно определять породы собак с высокой межклассовой вариацией. т. е. он точно определил породы бретани и лабрадора.
Это не удается, когда речь идет о породах собак с низкой межклассовой изменчивостью. т. е. он обнаружил шоколадного лабрадора как «Chesapeake_bay_retriever» и черного лабрадора как «Labrador_retriever», но я рад, что он смог определить породу как ретривер.
Тест человеческого лица был забавной частью, и результаты были достаточно близки.
Следующим шагом будет выполнение увеличения данных, чтобы увеличить вариации в наборе обучающих данных и повысить точность модели.
Заключение
Мы начали с простой модели CNN с точностью 3% и обучили модель с точностью 78%, используя трансферное обучение, и небольшие усилия впечатляют. Точность может показаться низкой, но наша задача не настолько чувствительна, чтобы беспокоиться об этом. Учитывая время и усилия, мы можем достичь точности выше 90% в этой задаче, используя методы переноса обучения и увеличения данных.
Репозиторий GitHub можно найти по адресу:
Ссылки
1. Узкий ИИ
https://en.wikipedia.org/wiki/Weak_AI
2. Каскадные классификаторы Хаара на основе признаков http://docs.opencv.org/trunk/d7/d8b/tutorial_py_face_detection.html
3. Введение в глобальный средний пул
https://adventuresinmachinelearning.com/global-average-pooling-convolutional-neural-networks/
4. ВГГ16
https://neurohive.io/en/popular-networks/vgg16/
5. НачалоV3