Нам, людям, очень легко распознать изображение, но как это делает компьютер?

Этот проект является частью курса по машинному обучению для выпускников и был разработан в сотрудничестве с Хулио Фрейре.

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

Распознавание изображений — одна из самых важных и известных функций искусственного интеллекта. В настоящее время мы видим это повсюду, даже на наших телефонах. Поэтому выбор этого набора данных полезен в текущем контексте: где его можно использовать в наши дни? Если вы водите машину, едете на автобусе, гуляете по улицам или едете на велосипеде, в любом из этих вариантов дорожный знак важен. Например, одним из приложений нашего проекта является передача карты с помощью камеры и GPS, которые сообщат нам, каковы правила движения по определенной дороге.

В этом посте мы попытаемся объяснить, как нам удалось использовать алгоритмы машинного обучения для распознавания дорожных знаков. Точнее, как мы использовали полный конвейер нейронной сети для обучения нашего алгоритма и развернули нашу модель для производства, чтобы каждый мог ее использовать. Будьте с нами, пока мы рассказываем обо всех шагах, которые мы предприняли для достижения этой задачи.

Общая структура

Мы скачали набор данных с Kaggle и перешли к анализу сырых данных. Чтобы помочь нам в наших задачах, мы использовали Weights & Biases (W&B). W&B — это инструмент для MLOps, который обеспечивает лучшую визуализацию всех этапов создания набора данных и версий моделей, сравнения моделей и настройки гиперпараметров. На каждом этапе обучающие и тестовые наборы, а также соответствующие им метки загружались в наш проект на W&B.

После анализа данных и их разделения мы обучили модель нейронной сети LeNet-5 (NN) распознавать дорожные знаки. Используя развертки W&B, мы смогли попробовать множество различных комбинаций для архитектуры и конфигурации NN. Затем мы выбрали наиболее точный и запустили его в производство с помощью Heroku. Развертывание стало возможным благодаря интеграции Github CI/CD с Heroku. Конечный продукт доступен для тестирования в Приложении для распознавания дорожных знаков, куда любой желающий может загрузить изображение дорожного знака и проверить, правильно ли модель его распознает.

В следующих разделах мы объясним, что было сделано на каждом этапе пути. Следуя передовой практике кодирования в машинном обучении, мы разделили код на отдельные файлы: выборка данных, EDA и предварительная обработка, проверка данных, разделение данных, обучение и, наконец, тестирование. Все это будет объяснено ниже. Все кодирование было выполнено с использованием Python и Google Colab, а файлы можно найти в нашем репозитории Github.

Получить данные

На этом этапе нам нужно импортировать данные, чтобы начать работу над нашим проектом. Поскольку наши данные состоят из изображений, первая мысль такова: если мы откроем изображение с высотой и шириной, и каждый пиксель имеет один цвет RGB, этот набор данных представляет собой тензор с 4 измерениями, и файл csv не может обрабатывать такой формат. Тогда что мы можем сделать? В ряде решений, между преобразованием тензора в вектор-строку (выравнивание), мы решили сохранить импортированные данные в файле HDF5.

Краткое объяснение HDF5

HDF5 — это формат, который позволяет хранить большие объемы данных в различных форматах и ​​широко используется в сообществе машинного обучения. Это позволяет нам сохранить файл и экспортировать его в W&B как артефакт. Затем импортируйте артефакты из W&B и используйте их в качестве входных данных для нашей нейронной сети.

Исходные данные были разделены перед загрузкой. Данные были разделены на поезд и тест с изображениями 39k и 11k соответственно (соотношение примерно 80/20%). Кроме того, были файлы csv с метками для каждого изображения. Всего было 43 возможных метки, то есть 43 дорожных знака.

На этом первом этапе мы подключили наш Google Диск к Colab, чтобы обеспечить доступ к файлам внутри нашего Диска. Таким образом, мы смогли загрузить данные в нашу коллаборативную команду на W&B. По этой ссылке нашей совместной команды вы можете найти проект traffic_sign_recognition и увидеть все пробеги, которые мы создали с W&B при работе над этим проектом. Также все артефакты, которые были экспортированы в W&B, можно найти на странице Артефакты.

Перед загрузкой в ​​W&B мы решили использовать только часть всего набора данных. Весь набор данных содержит более 50 тыс. изображений. Итак, чтобы облегчить настройку гиперпараметров в бесплатной версии Google Colab, мы выбрали 30% этих изображений случайным образом. Изображения Поезд и Тест были экспортированы в W&B в виде файлов HDF5. Кроме того, соответствующие метки для наборов поезд и тест были экспортированы в W&B в виде файлов csv.

Исследовательский анализ данных (EDA) и предварительная обработка

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

Поскольку в наборе данных не было аномалий, не было необходимости в стадии предварительной обработки перед конвейером.

Проверка данных

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

Разделение данных

На этом четвертом этапе нам не нужно было выполнять какую-либо сегрегацию, потому что, как уже упоминалось, набор данных был разделен до загрузки. Таким образом, мы загружали только необработанные данные из W&B и экспортировали обратно в W&B как «segregated_data» для согласованности. Отдельные данные поезда и соответствующие метки, а также данные испытаний и соответствующие метки можно найти на странице артефактов нашего проекта.

Тренироваться

На этом пятом и самом длинном шаге мы собрали отдельные данные о поездах из W&B и разделили их на два новых набора: наборы поездов и наборы проверки. Проверочный набор составляет 10% от исходного набора поездов. Набор поездов используется для обучения модели, а набор проверки используется для анализа метрик и настройки гиперпараметров. Итак, мы сначала обучаем модель с помощью набора поездов, а затем проверяем обученную модель с помощью набора проверки.

Но перед тренировкой нам нужно было создать свой пайплайн. Поскольку у нас были только числовые признаки (изображения), нам не нужно было обрабатывать категориальные признаки. Поскольку все изображения имеют разный размер, то есть количество пикселей, мы изменили размер всех изображений до 30x30 пикселей. После преобразования изображений в массивы numpy мы нормализовали значения. Эти значения от 0 до 255, представляющие каждый канал изображения RGB. Итак, мы разделили весь набор изображений поезда на 255.

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

Таким образом, необработанные данные поступают в конвейер, обрабатываются и затем попадают в модель. На этапе обучения мы использовали нейронную сеть LeNet-5 в качестве классификатора и анализировали точность модели по проверочному набору. Мы выполнили настройку гиперпараметров с помощью разверток W&B. Мы настроили развертку, чтобы протестировать некоторые конфигурации для нашего обучения, суммируя до более чем 15 000 комбинаций. Из них мы выбрали 100, чтобы попробовать и найти лучший.

В целом, мы попробовали некоторые инструменты обучения, обобщения и пакетной нормализации. Для обучения мы рассмотрели различные функции потерь, скорость обучения, использование функции активации «relu» для исправления исчезающего градиента и использование отсечения градиента для исправления взрывающегося градиента. Кроме того, для обобщения мы рассмотрели добавление слоев Dropout, чтобы избежать переобучения и преждевременной остановки обучения с помощью обратных вызовов Early Stopping. Наконец, мы проверили, принесет ли использование пакетной нормализации пользу процессу классификации.

После запуска этих разных конфигураций развертка W&B показала нам наилучший результат (тот, который имеет самую высокую точность). Эта конкретная настройка привела к точности 97,36% по сравнению с проверочным набором. Затем эта модель конфигурации использовалась как наша лучшая модель. Наконец, пайплайн и лучшая модель были экспортированы в W&B, и их можно увидеть на странице Артефактов (конвейер и модель).

Изменение точности, потерь и точности проверки в течение нескольких эпох для всего цикла можно увидеть ниже.

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

Об архитектуре LeNet-5:

Мы использовали проверенную и успешную сверточную архитектуру LeNet-5. Подробнее об этом можно узнать здесь. Этот выбор был основан на том факте, что этот тип архитектуры широко используется при обработке изображений из-за того, что он вдохновлен нейронными связями зрительной коры человека. В основном LeNet-5 состоит из 7 слоев, из которых 3 сверточных слоя, 2 слоя субдискретизации и 2 полносвязных слоя.

Тест

На этом шестом и последнем шаге мы проверили нашу модель на тестовом наборе. Наши окончательные показатели были такими, как показано ниже, и их можно увидеть в этом прогоне W&B.

26–07–2022 00:05:09 | Точность теста: 0,9097

26–07–2022 00:05:09 | Точность теста: 0,9113

26–07–2022 00:05:09 | Тестовый отзыв: 0,9097

26–07–2022 00:05:09 | Тест F1: 0,9079

Развертывание

После всех предыдущих шагов мы можем развернуть нашу модель, чтобы каждый мог ее попробовать. Благодаря своей надежности и эффективности, мы использовали веб-фреймворк FastAPI, чтобы помочь нам в решении этой задачи. Кроме того, мы использовали Uvicorn для подключения фреймворка через шлюз. Эти двое составляют сильный дуэт для такого рода задач, особенно для начинающих. С их помощью мы можем разработать локальное приложение, а с помощью Heroku загрузить приложение на облачный сервер.

Хорошо, теперь мы знаем шаги по созданию приложения. Но кто отвечает за синхронизацию наших локальных файлов с серверами Heroku?

Гитхаб! Heroku идеально сочетается с GitHub! Эти двое - наш второй сильный дуэт. С такой реализацией можно выполнить интеграцию CI/CD, при которой любые изменения в локальных файлах могут быть гитированы и доставлены на серверы Heroku.

Поскольку это простой проект, мы следуем инструкциям Prof. Иванович Сильва в своих видео-классах с некоторыми адаптациями под наши нужды. Во-первых, мы использовали организованную структуру каталогов и в пути source/api создали main.py, в котором реализованы наш домашний маршрут (/) и прогнозируемый маршрут (/predict/). В домашнем маршруте мы используем метод GET, чтобы показать первый экран с кратким описанием проекта. В маршруте прогнозирования мы используем метод POST для загрузки изображения в виде файла. Затем приложение отвечает предсказанием того, какой дорожный знак представляет изображение.

Чтобы выполнить все эти шаги прогнозирования, мы создаем новый файл «predict.py», который содержит функцию чтения изображения. Также мы создаем архитектуру нейронной сети, загружаем веса, импортированные W&B, отправляем изображение на сервер, получаем прогноз и доставляем его пользователю. Итак, когда изображение загружается на страницу, вызывается «predict.py» для запуска процесса.

Все файлы и папки API «проталкиваются» в наш репозиторий распознавания дорожных знаков на GitHub. Нам нужно настроить активную версию модулей, зависимостей, войти в W&B и запустить тест API. После этого необходимо подключиться к Heroku и настроить используемый язык и секретный ключ W&B.

Теперь наш проект в прямом эфире! Нажмите здесь, чтобы попробовать сами!

Последние мысли

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