От логистической регрессии к сверточным нейронным сетям с несколькими представлениями (MVCNN)

Вступление

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

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

Проблема, которую нам предстояло решить, заключалась в том, чтобы классифицировать 3D-модели автомобильных вилок по одной из пяти доступных категорий на основе 2D визуальной информации. Решение этой задачи имеет большое значение, особенно в контексте автономного планирования сборочных процессов при производстве автомобилей.

Самым интересным аспектом проблемы было наличие 8 изображений для каждого автомобильного разъема, 6 из которых соответствуют ортогональным проекциям объекта (т. Е. Разные виды: сверху, снизу, спереди, сзади, слева и справа), а 2 других - случайные изометрические проекции. На рисунке 1 ниже показан пример ортогональных проекций.

Испытания

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

Для проблемы несбалансированности классов методы повторной выборки не подходили. Действительно, понижение частоты дискретизации было практически невозможно, поскольку всего у нас было всего 833 автомобильных разъема (всего 833x8 = 6664 изображения), а для редких классов было очень мало образцов. Кроме того, использование увеличения данных, хотя и технически возможно, мне не показалось хорошей идеей просто потому, что ортогональные проекции, которые создавали виды изображений, являются типом инженерного чертежа со строгим набором правил. Следовательно, применение любого вида геометрического преобразования приведет к изображениям, которые не принадлежат к исходному распределению данных: использование их для обучения в основном похоже на то, чтобы подтолкнуть вашу модель к тому, чтобы научиться предсказывать изображения, с которыми она никогда не столкнется, таким образом излишне увеличивая сложность проблемы. Также стоит отметить, что цвета не имеют значения на наших изображениях. Чтобы лучше понять это, на рисунке 2 ниже представлен пример различных необработанных изображений автомобильной вилки.

Я решил решить проблему дисбаланса классов с помощью экономичного обучения, что в основном означает изменение функции затрат алгоритма машинного обучения путем введения набора весов, чтобы назначить более серьезные штрафы за ошибки, возникающие в «важных» классах. Это изменение помогает направить обучение модели на то, чтобы делать меньше этих дорогостоящих ошибок за счет потенциально большего количества «дешевых» ошибок. Чтобы проиллюстрировать этот момент, представьте, что у нас есть 50 точек данных, 49 принадлежащих классу A и 1 принадлежащая классу B. Для простоты мы также предполагаем потерю 0–1 (0 для правильного прогноза, 1 в противном случае). преобладающих потерь кросс-энтропии. В нормальных условиях, когда веса всех классов равны 1, модель будет пытаться научиться правильно предсказывать большинство точек данных, независимо от их класса. Но если мы предположим, что неправильная классификация выборки класса B несет в 100 раз больше стоимости класса A, и мы изменим нашу функцию стоимости, чтобы принять это во внимание, тогда модель в конечном итоге выберет классификацию этой одной точки данных класса B. правильно, даже если это означало сбой в предсказании всех остальных 49, потому что это параметр, который минимизирует общую стоимость: 49 * 1 + 0 * 100 = 49. Вместо этого, если мы допустили ошибку в точке данных класса B, и мы получили все другие образцы класса A правильно, стоимость будет: 49 * 0 + 1 * 100 = 100, что все еще намного выше, чем в предыдущем случае. Использовать экономичное обучение на практике так же просто, как передать словарь весов конструктору алгоритма (по крайней мере, тем, которые его поддерживают).

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

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

Обработка изображений

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

Оказывается, мы можем сделать и то, и другое, используя простой процесс: сначала мы обнаруживаем края с помощью Canny Edge Detector, а затем применяем две последовательные морфологические операции: Расширение к увеличиваем края и соединяем части, которые отсоединились после обнаружения края, затем мы используем Эрозию, чтобы сделать края более тонкими (расширение, за которым следует эрозия, обычно называется Закрытие и используется для заполнения дыр, которые меньше размера ядра этих операций). После этого нужно просто найти все контуры и сохранить самый большой, который будет соответствовать автомобильному разъему посередине. Таким образом, мы также отбрасываем все лишние артефакты вокруг границ. На рисунке 3 ниже показаны изображения автомобильной вилки до и после этого процесса.

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

Подход 1: извлечение функций и машинное обучение

До эры глубокого обучения исследователи вручную создавали экстракторы признаков для описания изображений. Но что мы подразумеваем под экстрактором признаков? По сути, это функция, которая извлекает числовое представление изображения или его части и предназначена для захвата некоторых из его отличительных характеристик. Представьте, что у нас есть изображение RGB, состоящее из трех 2D-матриц для каждого из цветовых каналов со значениями от 0 до 255. Мы можем квантовать каждую из этих матриц, скажем, в 4 ячейки (0–63, 64–127, 128–191, 192–255), где каждая ячейка содержит значения пикселей, которые находятся в соответствующем диапазоне. Таким образом, мы можем представить 2D-матрицу с вектором из 4 числовых значений (x_1, x_2, x_3, x_4), где каждый x_k - это количество значений в матрице, которые попадают в ячейку с номером k. Мы можем повторить этот процесс для 3 каналов изображения RGB, и после конкатенации мы получим вектор размером 12 (4 бина * 3 канала), представляющий это изображение. Мы только что создали простой экстрактор функций, который фиксирует цветовую информацию изображения. Несмотря на простоту по своей природе, вы можете использовать такую ​​технику для задач, где цвет является наиболее информативным фактором. На рисунке 4 показан этот экстрактор функций в действии. Обратите внимание, как более высокие интервалы доминирующего цвета каждого изображения более выделяются в векторе признаков. Это представление определенно отражает различия между тремя изображениями.

Академическое сообщество на протяжении многих лет придумало множество вручную разработанных экстракторов функций для различных целей. Некоторые важные из них - это HOG (гистограмма ориентированных градиентов), SIFT (масштабное инвариантное преобразование признаков), SURF (ускоренные надежные функции), LBP (локальные двоичные шаблоны) и т. Д. Основное внимание в процессе разработки этих экстракторов уделяется для обеспечения устойчивости к определенным свойствам изображений: масштабу, освещению, частичной окклюзии, вращению, искажению и т. д. Эти методы были центральной опорой традиционного компьютерного зрения и просуществовали до появления глубокого обучения, где они были по существу заменены нейронными сетями, которые могут изучить свой собственный механизм извлечения признаков применительно к задаче, которую им необходимо решить, в непрерывном режиме. Неудивительно, что это помогло им добиться в целом превосходных результатов.

Хорошо, хватит болтовни! Итак, как мы можем использовать эти экстракторы функций для решения нашей проблемы? Сначала мы обсудим, как они традиционно использовались для решения стандартных задач классификации изображений, а затем представим, как я адаптировал этот процесс к задаче с несколькими представлениями.

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

Дескрипторы из всех изображений собираются, а затем группируются для создания набора прототипов (то есть центроидов), которые действуют как «Словарь визуальных слов». Затем мы выполняем квантование изображения: мы находим визуальные слова в каждом изображении и создаем вектор функции подсчета, аналогично тому, как мы делаем это в подходе «Мешок слов», который обычно встречается в задачах классификации текста. Шаги процесса подробно описаны ниже:

  1. Извлеките все функции из всех «обучающих» изображений (потенциально много функций на изображение) после преобразования их в оттенки серого в матрицу формы FxM, где F - количество найденных функций, а M - размер экстрактора функций (обычно 64 или 128).
  2. Кластеризируйте матрицу FxM с помощью алгоритма кластеризации (например, K-средних), где K, количество кластеров, будет представлять наш словарь визуальных слов, найденных во всем наборе данных. Тогда каждый кластер представляет собой визуальное слово.
  3. Для каждого изображения извлеките все функции, спрогнозируйте их кластеры и подсчитайте, сколько функций попадает под каждый кластер. Другими словами, мы подсчитываем появление каждого визуального слова словаря (также называемого кодовой книгой) в изображении. Результатом является вектор признаков размером (1, K), представляющий изображение. Применяя ко всем изображениям в наборе данных, мы получаем матрицу формы (N, K), где N - количество изображений, а K - размер словаря (т. Е. Количество кластеров). Другими словами, матрица, в которой строки представляют наши изображения (точки данных), а столбцы представляют атрибуты или функции. Каждая ячейка этой матрицы представляет количество функций, обнаруженных в изображении строки, которые принадлежат кластеру столбцов.
  4. Используйте любой классический алгоритм машинного обучения для этой матрицы для классификации: логистическая регрессия, SVM, случайный лес, MLP и т. Д. Тем не менее, в таких ситуациях следует избегать использования древовидных методов, потому что проблема, скорее всего, линейна, как и в большинстве случаев. задачи классификации текстов.

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

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

Хорошо, теперь давайте поговорим о некоторых практиках. Большинство моих решений было принято с целью оптимизировать как время, так и производительность. Что касается экстракторов функций, SIFT - довольно хороший выбор, но на самом деле я использовал SURF, который, по сути, является более быстрой версией SIFT с относительно аналогичной производительностью. Что касается размеров функций SURF, я выбрал 64 вместо 128, главным образом, чтобы ускорить дальнейшее обучение. Я ожидаю, что 128 обеспечит немного лучшую производительность. Получившаяся матрица имела около 800K признаков размера 64. Следующим важным решением был выбор количества кластеров K в K-средних. Это потому, что K представляет количество визуальных слов, которые будут составлять столбцы окончательной матрицы признаков. Часто в таких ситуациях, чем выше значение, тем лучше, но действует закон убывающей отдачи, и после определенного момента предельное улучшение не будет стоить увеличения сложности. В моем случае я выбрал K = 200, но значения до 800 являются стандартными, и с ними следует поэкспериментировать. После этого я просто создал окончательную матрицу функций размером 833x200 (количество автомобильных пробок x количество кластеров). На рисунке 7 показаны два примера векторов признаков и одно случайно выбранное изображение для каждой вилки.

После обучения модели логистической регрессии я получил в среднем около 87% взвешенной точности (невзвешенная точность легко находится в диапазоне 90–95%). Это довольно приличный результат, но можем ли мы добиться большего? Мы обязательно можем попробовать!

Подход 2: сверточные нейронные сети с несколькими представлениями

Этот раздел посвящен настраиваемой архитектуре нейронной сети для решения проблемы с несколькими представлениями. Если мы сделаем шаг назад и на секунду задумаемся над проблемой, как бы мы использовали нейронную сеть для сопоставления наших входных данных с их классом? Что ж, в стандартной задаче классификации изображений мы бы выбрали основу популярной архитектуры CNN (ResNet, Inception, VGG и т. Д.) В качестве экстрактора признаков, а затем добавили бы поверх нее блок классификатора, состоящий из одного или нескольких плотные слои как форма трансферного обучения. Если бы мы попытались использовать аналогичный принцип в нашей задаче с многовидовым изображением, мы могли бы представить себе создание базового блока сети (экстрактора признаков) несколько раз, по одному для каждого вида изображения. Таким образом, мы извлекаем функции из всех 8 изображений отдельно с помощью трансферного обучения. Тем не менее, мы все равно останемся с тем же вопросом, который у нас был раньше: вместо того, чтобы объединять информацию из изображений в начале, мы отложили вопрос, и теперь мы должны объединить информацию из нескольких наборов карт функций (т. Е. карты характеристик, представляющие каждое представление, созданное базовыми CNN). Один из способов решения этой проблемы - объединить эти карты функций вместе. Например, если бы карты характеристик каждого вида имели форму KxKxC, мы могли бы сложить 8 из них по размеру каналов в один большой набор карт характеристик формы KxKx8C. Рисунок 8 иллюстрирует этот процесс.

Проблема с этим подходом, независимо от того, как мы выбираем стек, заключается в том, что он предполагает, что существует порядок просмотров изображений, хотя на самом деле его нет. Если мы сначала складываем карты функций вида сверху, а затем - снизу, то ожидается, что мы сделаем то же самое для каждой автомобильной вилки. Тем не менее, нет ссылки, указывающей, что для автомобильной вилки сверху, а что снизу, мы можем рассматривать любой вид как любую сторону. Или, иначе говоря, если мы возьмем два автомобильных разъема и одно представление первого, не будет возможности найти «эквивалентное» представление во втором автомобильном разъеме. Таким образом, следует избегать любых предположений, основанных на порядке.

Нам остается второй вариант - найти операцию, которая объединяет информацию из нескольких значений в одно. Оказывается, в CNN есть одна такая функция, и мы называем ее пулом. Мы могли бы использовать некоторую форму объединения по размеру представлений, чтобы объединить 8 наборов карт функций в одну и ту же форму, тем самым объединяя информацию из всех представлений изображений. Это все хорошо, но пока это всего лишь теоретическая идея, есть ли какие-либо доказательства того, что это действительно может работать? Что ж, одно такое доказательство можно найти в классификации текста, где мы объединяем вложения каждого слова в тексте в одно вложение, например, взяв среднее значение всех вложений. Мы пытаемся сделать что-то подобное для наших просмотров изображений. Но, возможно, лучшим доказательством было бы найти статью, в которой была предпринята попытка такого подхода и в которой приводились экспериментальные результаты, подтверждающие его. Быстрый поиск в Google покажет, что есть одна такая статья (хотя и не единственная), и она удобно называется: Multi-View Convolutional Neural Networks for 3D Shape Recognition. На рисунке 9 показана архитектура, предложенная в статье, которая почти полностью совпадает с тем, что мы объяснили выше.

Я реализовал эту архитектуру MVCNN в PyTorch и использовал ResNet34 Base для CNN1. После слоя Average View Pooling я добавил сверху блок, состоящий из серии слоев Dense и регуляризации Dropout, которую я называю Блок классификатора. Для обучения я изначально зафиксировал базовый CNN1 и обучил только блок классификатора: обычно это называется извлечением признаков при переносе обучения. Затем я разморозил все веса во всей сети, снизил скорость обучения до очень низкого значения и обучил всю MVCNN от начала до конца: это называется точной настройкой в ​​трансферном обучении . В конечном итоге моя взвешенная точность достигла отметки 98%… довольно впечатляюще, да? На самом деле не так уж и много. Помимо странной метрики производительности и дисбаланса классов, следует ожидать высоких оценок, потому что эта задача, возможно, не очень сложна для машинного обучения.

Да, да, я знаю, что вы, вероятно, пришли сюда только из-за кода, и я рад помочь! В этом репозитории на github вы найдете все, что вам нужно: code. Ноутбук хорошо прокомментирован, но, к сожалению, я не могу поделиться данными. Если вы хотите поэкспериментировать с предлагаемыми здесь методами и у вас нет подходящего набора данных, подумайте об использовании теста для классификации многовидовых изображений: ModelNet40. Если вас больше интересует первый подход, подойдет любой обычный набор данных классификации изображений.

Вот и все, ребята, надеюсь, вы кое-что узнали. Не стесняйтесь возвращаться, если вам понравился контент, я скоро добавлю больше статей.

А пока, сайонара ~

использованная литература

[1] Су, Ханг и др. «Многовидовые сверточные нейронные сети для распознавания трехмерных форм». Материалы международной конференции IEEE по компьютерному зрению. 2015 г.