В этой статье давайте поговорим о задаче AUTODRI, представленной в конкурсе AICrowd's Blitz 3. Задача задачи просто определена: учитывая изображения с 4 камер, прикрепленных со всех 4 сторон автомобиля, наша задача - предсказать значение угла поворота для этого точного момента.

Ссылка на описание проблемы: https://www.aicrowd.com/challenges/ai-for-good-ai-blitz-3/problems/autodri

Давайте сначала формально опишем проблему

Задача требует от нас спрогнозировать угол поворота автомобиля в диапазоне [-720, 720] с учетом изображений с четырех углов камеры (спереди, слева, справа, сзади).

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

Показатель оценки для этого конкурса - это среднеквадратическая ошибка из основных значений истинности в наборе тестовых данных.

Это хорошее время, чтобы начать записывать некоторые идеи по проблеме и быстро переходить к анализу данных. (Попробуйте сами проанализировать данные и посмотреть, что вы можете найти, и оставьте любые дополнения к нашим в комментариях ниже).

Если вы хотите увидеть код, лежащий в основе всего анализа и создания модели, перейдите по ссылке в нашу записную книжку Google Colab и поэкспериментируйте. Остальная часть блога посвящена исключительно идеям и наблюдениям.

Ссылка на блокнот Google Colab: https://colab.research.google.com/drive/1k6ZTjIdEe2gZvLg1wpR8zMN2Go5hWIvg?usp=sharing

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

Что касается всех проблем с изображением, мы, очевидно, начинаем с просмотра данных и проверки, имеют ли они смысл для нас, людей. И вроде как. Многие из этих изображений очень похожи друг на друга, что говорит нам о том, что это просто кадры из видео о вождении.

Давайте посмотрим на первые несколько строк нашего данного DataFrame, загрузив его в pandas:

Давайте теперь посмотрим, как выглядит распределение угла поворота нашего набора данных. Это единственная непрерывная переменная в нашем DataFrame.

На данный момент мы не проводили тщательного анализа, но идея состоит в том, что разница в наборах данных для поездов и валидации составляет почти 47000, тогда как отправка всех 0 в общедоступной таблице лидеров покажет вам, что дисперсия в тестовом наборе данных просто около 18000. Зондирование таблицы лидеров, например. отправка всех нулей, чтобы получить оценку дисперсии набора данных, или попытка угадать среднее значение, отправив разные постоянные значения, - это хакерство, часто используемое командами, чтобы гарантировать, что тестовые данные не будут радикально отличаться от того, на чем они тренируются.

Хочешь водить машину !? 🚓

Визуализации являются центральным элементом любого приложения машинного обучения, и это особенно простое и полезное приложение.

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

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

Код для создания симуляции вождения выше.

Конвейер данных: TensorFlow Records

Менее известным компонентом TensorFlow является формат файла TFRecord, собственный двоичный формат хранения TensorFlow.

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

Когда мы, наконец, будем готовы обучаться на Kaggle или Google Colab TPU, эти TFRecords будут неоценимы, поскольку генераторы изображений Keras будут серьезно снижать скорость, обеспечиваемую TPU, и невозможно читать файлы из disk в любом случае при обучении на кластере TPU.

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

Соберем нашу Модель 💡

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

Вот изображение архитектуры, которую мы используем:

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

Идея использования всех 4 изображений вместе является основой всех задач с несколькими входами. И это все, что мы здесь делаем. В следующем разделе мы начнем с идей по более сложным моделям, но этого достаточно в качестве основы.

Функция потерь

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

Чтобы быть устойчивыми к выбросам в особенно зашумленном наборе данных, мы также попробовали другие потери, такие как расхождение KL и log (cosh (ошибка)), но они служат только в качестве метрик, поскольку потери Хубера напрямую улучшают нашу метрику, и это основная цель. любого конкурса.

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

Отправляясь отсюда

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

Переобучение - всегда проблема, поэтому лучше вводить более простые функции. Сделайте это, добавив фильтр OpenCV Canny в функцию получения изображения файла TFRecords. Мы также обрезали верхнюю половину этих изображений, так как модель должна попытаться сфокусироваться на линиях дороги. Вы можете видеть, что часто по линейным фигурам ясно, в какую сторону идти, шансы переобучения значительно снижаются.

Другая идея в том же духе заключается в следующем. Возьмите изображения и обучите UNet генерировать сегментированный вывод для этих изображений. Смотрите рисунки на всех рядах, они содержат только одноцветные объекты, дорогу, небо и т. Д. Вы можете узнать, как обучить пользовательскую модель UNet, из руководства TensorFlow здесь https://www.tensorflow.org/tutorials / images / segmentation и обучитесь работе с набором данных CityScape здесь https://www.cityscapes-dataset.com/downloads/ (для его загрузки вам понадобится идентификатор университета).

Наконец, мы также можем попробовать объединить выходные данные для модели. Вот график для набора поездов и проверки, когда данные разделены на ячейки более 60 градусов вправо, более 60 градусов влево и идущие прямо (до 60 градусов с каждой стороны). Это действительно помогает некоторым моделям меньшего размера работать лучше.

Здесь можно использовать гораздо более продвинутые идеи, например, обучение с подкреплением, учитывая, что у нас есть видео, в котором мы должны принимать решения на основе прошлых ценностей. Отличным примером этой идеи является использование для игры в Atari Breakout (структура задачи идентична, сверточные сети с буфером воспроизведения для запоминания нескольких последних кадров). Чтобы узнать больше о том, как это реализовать, прочтите руководство по github здесь: «https://github.com/yandexdataschool/Practical_RL/blob/d51a1ee19ebab79bfc9d854b41aeb0010ea6cafa/week04_approx_rl/homework_pytorb_main.

Возьмите домой мораль

Мы надеемся, что после прочтения этого блога и изучения нашего кода вы будете знакомы со следующим:

  1. Использование EfficientNets и других предварительно обученных моделей в качестве основы
  2. Настройка конвейера данных в TensorFlow Data с помощью TFRecords
  3. Создание базовых графиков и изучение особенностей данных
  4. Визуализация изображений и видео данных с помощью OpenCV
  5. Фильтры OpenCV и сегментация изображений как идеи при извлечении функций
  6. Создание моделей с несколькими входами и слоями конкатенации

Мы надеемся, что это была интересная и информативная основа, с которой вы могли поиграть. Все идеи в блогах на самом деле помогли нам набрать приличный балл и в настоящее время занимают 7-е место в таблице лидеров и 2-е место в общем зачете.

Это была самая сложная проблема для нас в этом конкурсе, мы опубликуем наши окончательные модели сразу после окончания конкурса и очень ценим любые отзывы о нашем процессе построения моделей (это наш первый серьезный конкурс для всех членов нашей команды 😆). Самое замечательное, что мы здесь узнали, - это ценность визуализаций и их приверженность, просто опробовать каждую идею, а затем начинают поступать осознания.

Ждем ваших комментариев и советов. Большое спасибо за чтение!