путем семантической сегментации изображений с использованием сверточных нейронных сетей

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

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

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

Вызов

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

Для выполнения этой задачи программа должна уметь последовательно выполнять 2 шага:

  • Найдите еду на исходном изображении
  • Удалите с исходного изображения все, кроме еды.

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

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

«Классическое» компьютерное зрение

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

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

  1. Измените размер изображения до 500 на 500 пикселей.
  2. Выполните медианное размытие с окном 5 на 5 пикселей
  3. Выполните кластеризацию k-ближайших соседей (kNN) по цветам изображений
    (с k = 7)
  4. Возьмите оттенки серого изображения
  5. Выполните медианное размытие с окном 9 на 9 пикселей
  6. Выполните кластеризацию kNN по цветам изображений
    (с k = 4)
  7. Выполните бинарный пороговый фильтр на изображении с порогом 200
  8. Найдите первый двоичный объект из 0, начиная с центра изображения в ширину, залейте его единицами на растровое изображение маски и установите для остальной части растрового изображения значение 0.

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

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

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

В целом, этот конвейерный подход Computer Vision работает, но имеет очень ограничительные возможности. Реализация делает несколько предположений:

  • Еда всегда в центре изображения
  • Фон, окружающий еду, всегда значительно светлее, чем еда (черные тарелки не допускаются).
  • Сама еда никогда не может быть очень светлой (из-за бинарного порогового фильтра).
  • Еда никогда не может вылиться из контейнера (из-за этапа заполнения водой)

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

Предпосылки глубокого обучения

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

Искусственные нейронные сети

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

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

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

Сверточные нейронные сети

Сверточные нейронные сети (CNN), тип искусственной нейронной сети, часто используются в качестве моделей глубокого обучения обработки изображений. Это связано с тем, что сверточные слои содержат «фильтры», в отличие от нейронов, содержащихся в обычных слоях с прямой связью. Эти фильтры представляют собой наборы весов, которые являются общими для всего ввода слоя. CNN могут достигать результатов, аналогичных нейронным сетям с прямой связью (FFNN), с меньшим количеством весов, поскольку каждый нейрон в FFNN присваивает уникальный вес каждому из своих входных значений. Фильтры CNN эффективно позволяют сверточным слоям CNN научиться распознавать шаблоны во входных данных независимо от того, где во входных данных встречается шаблон. Это то, что FFNN не может сделать так эффективно.

Семантическая сегментация изображения

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

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

Помеченные данные

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

Трансферное обучение

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

Вы могли бы значительно сократить объем необходимых обучающих данных, если бы могли, например, сделать следующее:

  • Возьмем сеть, которая была обучена распознавать людей на картинках.
  • Сохраните все более ранние слои, которые предположительно участвуют в распознавании форм и как эти формы могут объединяться в более сложные структуры.
  • Отбросьте более поздние слои, которые, скорее всего, отвечают за распознавание структур, характерных для человеческого тела.
  • Перенастройте эти последние слои в слои, которые распознают структуры, характерные для продуктов питания.

Семантическая сегментация изображения с использованием keras_segmentation

При поиске предварительно обученных сетей сегментации изображений, которые можно использовать для обучения передачи, я наткнулся на пакет Python keras_segmentation на Github. Пакет предоставляет некоторые из самых популярных сетевых архитектур сегментации, а также методы, позволяющие легко их обучать и оценивать. Это очень полезный пакет, и я настоятельно рекомендую его всем, кто хочет опробовать сегментацию изображений без необходимости писать много шаблонного кода, который участвует в таком процессе. Что наиболее важно, для целей тестового приложения пакет поставляется с парой предварительно обученных сетей, а также с методами передачи весов и выполнения трансферного обучения. Я протестировал пару предварительно обученных сетей и остановился на реализации pspnet, которая была обучена на наборе данных ADE20k. Бумага, описывающая pspnet, очень техническая, но ее стоит прочитать, если вам интересно.

Процесс и результаты

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

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

Я создал новый pspnet, перенес соответствующие веса из предварительно обученной сети и настроил обучение, используя методы, предоставляемые keras_segmentation.

После обучения сети в течение 15 эпох с помощью 64 пакетов по 16 расширенных обучающих примеров на эпоху, сеть смогла достичь точности сегментации 0,97 на данных проверки, что означает, что 97% пикселей проверочных изображений были правильно классифицированы.

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

У использования подхода глубокого обучения перед классическим компьютерным зрением есть несколько недостатков. Нейронную сеть нельзя настроить так же, как предложенный ранее конвейер. Вы просто не можете надеяться разобраться в 46 765 250 параметрах этой сети и вручную настроить их, чтобы улучшить производительность сети. Именно по этой причине искусственные нейронные сети считаются черными ящиками. Если вы хотите внести изменения в модель, вам придется ее переобучить. Другой очевидный недостаток заключается в том, что края масок, создаваемых этой моделью, заметно менее точны, чем конвейер компьютерного зрения, который мы определили ранее, хотя это, вероятно, может быть улучшено в будущем.

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

Это сеть, которая была реализована в экспериментальном проекте.

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

Заключение

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