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

#update: Мы только что запустили новый продукт: API обнаружения объектов нанонеток

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

Что такое семантическая сегментация?

Семантическая сегментация - естественный шаг на пути от грубого вывода к точному:

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

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

  • AlexNet: новаторский CNN в Торонто, победивший в конкурсе ImageNet в 2012 году с точностью тестирования 84,6%. Он состоит из 5 сверточных слоев, max-pooling, ReLU как нелинейностей, 3 полностью сверточных слоев и dropout.
  • VGG-16: эта оксфордская модель выиграла конкурс ImageNet 2013 года с точностью 92,7%. Он использует стек сверточных слоев с небольшими рецептивными полями в первых слоях вместо нескольких слоев с большими рецептивными полями.
  • GoogLeNet: эта сеть Google выиграла конкурс ImageNet 2014 с точностью 93,3%. Он состоит из 22 слоев и недавно представленного строительного блока под названием начальный модуль. Модуль состоит из уровня сеть в сети, операции объединения, сверточного слоя большого размера и сверточного слоя малого размера.
  • ResNet: эта модель Microsoft победила в конкурсе ImageNet в 2016 году с точностью 96,4%. Он известен своей глубиной (152 слоя) и наличием остаточных блоков. Остаточные блоки решают проблему обучения действительно глубокой архитектуры, вводя соединения пропуска идентификации, чтобы слои могли копировать свои входные данные на следующий уровень.

Каковы существующие подходы семантической сегментации?

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

  • Кодировщик обычно представляет собой предварительно обученную классификационную сеть, такую ​​как VGG / ResNet, за которой следует сеть декодеров.
  • Задача декодера - семантически проецировать отличительные признаки (более низкое разрешение), изученные кодировщиком, на пространство пикселей (более высокое разрешение), чтобы получить плотную классификацию.

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

1 - Семантическая сегментация на основе региона

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

R-CNN (Регионы с функцией CNN) является одним из примеров работы для методов на основе регионов. Он выполняет семантическую сегментацию по результатам обнаружения объекта. Чтобы быть конкретным, R-CNN сначала использует выборочный поиск для извлечения большого количества предложений объектов, а затем вычисляет характеристики CNN для каждого из них. Наконец, он классифицирует каждую область с помощью линейных SVM, зависящих от класса. По сравнению с традиционными структурами CNN, которые в основном предназначены для классификации изображений, R-CNN может решать более сложные задачи, такие как обнаружение объектов и сегментация изображения, и даже становится одной важной основой для обоих полей. Более того, R-CNN может быть построен поверх любых структур тестов CNN, таких как AlexNet, VGG, GoogLeNet и ResNet.

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

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

Из-за этих узких мест недавние исследования были предложены для решения проблем, включая SDS, Hypercolumns, Mask R-CNN.

2 - Полностью сверточная семантическая сегментация на основе сети

Исходная Полностью сверточная сеть (FCN) изучает отображение пикселей в пиксели без извлечения предложений по регионам. Сетевой конвейер FCN является продолжением классической CNN. Основная идея - сделать так, чтобы классический CNN принимал на вход изображения произвольного размера. Ограничение CNN принимать и производить метки только для входов определенного размера исходит от полностью связанных уровней, которые являются фиксированными. В отличие от них, FCN имеют только сверточные и объединяющие слои, которые дают им возможность делать прогнозы для входных данных произвольного размера.

Одна из проблем в этой конкретной FCN заключается в том, что при распространении через несколько чередующихся сверточных и объединяющих слоев разрешение выходных карт функций снижается. Следовательно, прямые предсказания FCN обычно имеют низкое разрешение, что приводит к относительно нечетким границам объектов. Для решения этой проблемы было предложено множество более продвинутых подходов на основе FCN, включая SegNet, DeepLab-CRF и Dilated Convolutions.

3 - Семантическая сегментация с недостаточным контролем

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

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

Выполнение семантической сегментации с помощью полностью сверточной сети

В этом разделе давайте рассмотрим пошаговую реализацию самой популярной архитектуры семантической сегментации - полностью сверточной сети (FCN). Мы реализуем его с помощью библиотеки TensorFlow в Python 3 вместе с другими зависимостями, такими как Numpy и Scipy.

В этом упражнении мы будем маркировать пиксели дороги на изображениях с помощью FCN. Мы будем работать с Kitti Road Dataset для обнаружения дорог / полос. Это простое упражнение из программы нано-дипломов Udacity Self-Driving Car, о настройке которой вы можете узнать больше в этом репозитории GitHub.

Вот ключевые особенности архитектуры FCN:

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

Существует 3 версии FCN (FCN-32, FCN-16, FCN-8). Мы реализуем FCN-8, как подробно описано ниже:

  • Кодировщик. В качестве кодировщика используется предварительно обученный VGG16. Декодер запускается с уровня 7 VGG16.
  • FCN Layer-8: последний полностью подключенный уровень VGG16 заменяется сверткой 1x1.
  • FCN Layer-9: FCN Layer-8 повышается дискретизация 2 раза, чтобы соответствовать размерам с уровнем 4 VGG 16, с использованием транспонированной свертки с параметрами: ( ядро = (4,4), stride = (2,2), paddding = 'same'). После этого было добавлено пропускаемое соединение между уровнем 4 VGG16 и FCN Layer-9.
  • FCN Layer-10: FCN Layer-9 повышается дискретизация 2 раза, чтобы соответствовать размерам с уровнем 3 VGG16, с использованием транспонированной свертки с параметрами: (ядро = (4,4), stride = (2,2), paddding = 'same'). После этого было добавлено пропускаемое соединение между уровнем 3 VGG 16 и FCN Layer-10.
  • FCN Layer-11: FCN Layer-10 передискретизируется 4 раза, чтобы соответствовать размерам с размером входного изображения, поэтому мы получаем фактическое изображение обратно, а глубина равна количеству классов, используя транспонированную свертку с параметрами: (kernel = (16,16), stride = (8,8), paddding = 'same').

Шаг 1

Сначала мы загружаем предварительно обученную модель VGG-16 в TensorFlow. Взяв сеанс TensorFlow и путь к папке VGG (которую можно загрузить здесь), мы возвращаем кортеж тензоров из модели VGG, включая вход изображения, keep_prob (для управления частотой отсева), уровень 3, уровень 4, и слой 7.

Шаг 2

Теперь мы сосредоточимся на создании слоев для FCN, используя тензоры из модели VGG. Учитывая тензоры для вывода слоя VGG и количество классов для классификации, мы возвращаем тензор для последнего слоя этого вывода. В частности, мы применяем свертку 1x1 к слоям кодировщика, а затем добавляем уровни декодера в сеть с помощью пропуска соединений и повышающей дискретизации.

Шаг 3

Следующим шагом является оптимизация нашей нейронной сети, также как и создание функций потерь TensorFlow и операций оптимизатора. Здесь мы используем перекрестную энтропию в качестве функции потерь и Адама в качестве алгоритма оптимизации.

Шаг 4

Здесь мы определяем функцию train_nn, которая принимает важные параметры, включая количество эпох, размер пакета, функцию потерь, работу оптимизатора и заполнители для входных изображений, изображений меток, скорости обучения. Для процесса обучения мы также установили keep_probability равным 0,5 и learning_rate равным 0,001. Чтобы отслеживать прогресс, мы также распечатываем потери во время тренировки.

Шаг 5

Наконец-то пора тренировать нашу сеть! В этой функции run мы сначала строим нашу сеть с помощью функций load_vgg, Layers и optimize. Затем мы обучаем сеть с помощью функции train_nn и сохраняем данные вывода для записей.

Что касается наших параметров, мы выбираем epochs = 40, batch_size = 16, num_classes = 2 и image_shape = (160, 576). После выполнения 2 пробных прогонов с отсевом = 0,5 и отсевом = 0,75, мы обнаружили, что второе испытание дает лучшие результаты с лучшими средними потерями.

Чтобы увидеть полный код, перейдите по этой ссылке: https://gist.github.com/khanhnamle1994/e2ff59ddca93c0205ac4e566d40b5e88

Если вам понравился этот материал, я бы хотел, чтобы вы нажали кнопку хлопка 👏 , чтобы другие могли наткнуться на него. Я также рекомендую ознакомиться с этим руководством от Neptune о том, как исследовать данные для сегментации изображения и обнаружения объектов. Выглядит очень подробно!

О нанонцах