Разбивая сложность на шаги корги

Иногда вам не нужно выбирать удовольствие вместо производительности, и в те редкие моменты вы идете ва-банк. Нужно подготовить завершающий проект с использованием нейронных сетей, но вы все равно хотите повеселиться? Щенки спешат на помощь!

Постановка задачи

Итак, обо всем по порядку. Целью этого проекта является использование сверточной нейронной сети (CNN), которая поможет предсказывать породы собак. Вы можете возразить, что порода не имеет значения, важна пушистость. Что ж, идентификация породы собак на самом деле может считаться важной по многим причинам, особенно для понимания состояния отдельных пород, проблем со здоровьем, поведения при взаимодействии и прочего. Если созданная мной модель окажется успешной, ее можно будет использовать для сокращения объема ручных усилий, необходимых для категоризации больших объемов немаркированных данных изображений собак.

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

Стратегия решения проблемы

Я решил построить конвейер, который можно использовать в вебе/приложении для обработки реальных изображений, сделанных пользователями. Модель принимает любое изображение, предоставленное пользователем, в качестве входных данных. Если на изображении обнаружена собака, он оценит породу собаки. Если, с другой стороны, обнаружится человек, он даст похожую породу собак… О, интрига! (Как вы можете судить из приведенного ниже, результаты могут быть действительно тревожными, поэтому я официально отмечаю этот проект как PG-13.)

Показатели

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

Исследование и визуализация данных

Udacity предоставил мне несколько наборов данных: один для собак, другой для людей.

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

Набор данных о собаках состоял из 133 категорий пород собак и 8351 изображения, из которых 6680 изображений использовались для обучения, 835 — для проверки и 836 — для тестирования. Весь набор данных о щенках был использован для обучения моей модели CNN.

Как вы можете видеть выше, для каждой породы собак в среднем около 50 изображений, при этом минимальное значение составляет 41, а максимальное достигает 70. Хотя ранее я упоминал, что представление довольно сбалансировано, теперь вы можете убедиться в этом сами.

Предварительная обработка данных

Изображения людей. Стандартной практикой является преобразование изображений в оттенки серого перед применением каких-либо алгоритмов распознавания лиц. Поэтому я использовал функцию detectMultiScale(gray), которая выполняет каскадный классификатор Хаара, хранящийся в face_cascade, и принимает изображение в градациях серого в качестве параметра.

Изображения собак.изображения были представлены в разных размерах и размерах, поэтому на этапе предварительной обработки мне пришлось уменьшить все до 224 x 224 пикселей, чтобы они соответствовали архитектуре моей сети. Затем изображения были преобразованы в 4D-тензор с применением preprocess_input, чтобы получить 4D-тензор, готовый для любой предварительно обученной модели в Keras.

Реализация и моделирование

Я использовал следующую архитектуру, которая дала наилучшие результаты:

  • Я определил четыре сверточных фильтра увеличивающегося размера (от 8 до 16, затем от 32 до 64).
  • Я использовал длину шага 2, так как она работала намного быстрее по сравнению с 1 (которая была медленной и не более точной).
  • Я выбрал GlobalAveragePooling, так как это рекомендуется в CNN для уменьшения пространственных измерений в целях классификации.
  • Я выбрал 5 эпох, потому что этого достаточно, чтобы получить точность › 1%.
  • Я использовал слой MaxPooling, чтобы уменьшить размеры входных изображений вдоль слоев CNN, что также должно противодействовать опасности переобучения.

Я попытался запустить CNN без слоев пула, но он работал намного медленнее, а точность была намного ниже. Это связано с тем, что объединение обычно используется для уменьшения размерности. Его безопасно использовать здесь, поскольку соседние пиксели, вероятно, похожи, и понижение дискретизации не уменьшит способность классификатора обнаруживать изображение.

Уточнение и настройка гиперпараметров

Первая версия CNN была далека от эпической. Его точность была ниже 4%! Но давайте оставаться позитивными: это все же лучше, чем случайное, но да, есть много возможностей для улучшения. Сначала я попытался использовать модель VGG16, которая показала точность 39%. Затем я переключился на другую предварительно обученную модель Inception V3. Вот и все стало интересно…

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

Оценка и проверка модели

Возвращаясь к простому детектору человеческого лица OpenCV, он работал довольно хорошо: он смог идентифицировать 100% всех людей; однако он также идентифицировал 11% собак как людей…

С другой стороны, детектор собак смог подтвердить, что 100% всех собак были собаками.

С моделью классификации пород собак точность обучения (после 50 эпох) достигла более 95%, а точность проверки была намного ниже (85%). Кроме того, точность теста достигла всего 80%, что свидетельствует о том, что модель, к сожалению, переоснащается. Вероятно, это связано с тем, что мы все еще использовали очень маленький набор данных, содержащий всего 133 категории и 6680 обучающих изображений. Но эй, могло быть и хуже!

Заключение

Я начал с нуля с модели CNN, которая имела показатель точности всего 3,7%, и обучил две модели с точностью 39% (VGG-16) и 80% (Inception-V3), используя трансферное обучение. Что мне показалось сложным, так это выбор правильной модели, а также длительное время обучения. Что мне показалось интересным, так это то, что модель идентифицировала похожую породу собак, когда предоставила изображение человека. Кто еще мог показать мне фотографию человека и заявить, что он похож на мастифа, если не наш собственный мистер Питон?

Улучшения

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

Ресурсы

Udacity предоставил набор данных, поэтому внешние источники не требовались. Реальную проделанную работу можно найти здесь, на моем Git.