Введение
Мы, люди, в высшей степени искусны в том, чтобы взглянуть на любое изображение и понять, что внутри него. На самом деле, это почти незаметная реакция с нашей стороны. Анализ занимает доли секунды.
Это совершенно другая игра с мячом для машин. За последние пару десятилетий было предпринято множество попыток сделать машины более умными для решения этой задачи — и, возможно, мы, наконец, справились с этой задачей благодаря методам глубокого обучения (и компьютерного зрения)!
Эти алгоритмы глубокого обучения особенно распространены в камерах наших смартфонов. Они анализируют каждый пиксель данного изображения для обнаружения объектов, размытия фона и целого ряда трюков.
Большинство этих смартфонов используют несколько камер для создания такой атмосферы. Тем не менее, Google находится в своей собственной лиге. И я рад поделиться в этой статье подходом с использованием их модели DeepLab V3+, которая присутствует в телефонах Google Pixel!
Давайте вместе построим вашу первую модель сегментации изображений!
Эта статья требует хорошего понимания сверточных нейронных сетей (CNN). Перейдите к статье ниже, чтобы узнать о CNN (или быстро освежить в памяти):
Оглавление
- Введение в сегментацию изображений
Семантическая сегментация
Сегментация экземпляров - Начало работы с DeepLab от Google
- Введение в Atrous Convolutions
- Сепарабельные свертки по глубине — что это такое?
- Понимание архитектуры модели DeepLab
- Обучение нашей модели семантической сегментации
- DeepLabV3+ в пользовательском наборе данных
Введение в сегментацию изображений
Сегментация изображения — это задача разделения изображения на несколько сегментов. Это значительно упрощает анализ данного изображения. И, по сути, не к этому ли мы всегда стремимся в компьютерном зрении?
Это очень похоже на группировку пикселей на основе определенных характеристик. Теперь эти характеристики часто могут привести к различным типам сегментации изображения, которые мы можем разделить на следующие:
- Семантическая сегментация
- Сегментация экземпляра
Давайте на минутку разберемся в этих понятиях.
1. Семантическая сегментация
Посмотрите на изображение ниже:
Это классический пример семантической сегментации в действии. Каждый пиксель на изображении принадлежит одному определенному классу — машине, зданию, окну и т. д. И всем пикселям, принадлежащим к определенному классу, присвоен один цвет. Потрясающе, правда?
Чтобы дать формальное определение этому понятию,
Семантическая сегментация — это задача присвоения класса каждому пикселю данного изображения.
Обратите внимание, что это существенно отличается от классификации. Классификация присваивает один класс всему изображению, тогда как семантическая сегментация относит каждый пиксель изображения к одному из классов.
Два популярных приложения семантической сегментации включают:
- Автономные транспортные средства. Они в значительной степени полагаются на такие сегментированные изображения для навигации по маршрутам.
- Портретный режим на телефоне Google Pixel. Здесь вместо нескольких классов нам нужно классифицировать каждый пиксель как принадлежащий либо к переднему плану, либо к фону, а затем размыть фоновую часть изображения.
2. Сегментация экземпляров
Мне нравится изображение выше! Он аккуратно демонстрирует, чем сегментация экземпляров отличается от семантической сегментации. Потратьте секунду, чтобы проанализировать его, прежде чем читать дальше.
Различные экземпляры одного и того же класса сегментируются индивидуально при сегментации экземпляров. Другими словами, сегменты осведомлены об экземплярах. На изображении выше мы видим, что разным экземплярам одного и того же класса (человека) присвоены разные метки.
Алгоритмы сегментации изображений
Сегментация изображения — давняя проблема компьютерного зрения. Для решения этой задачи было разработано довольно много алгоритмов, таких как алгоритм Watershed, пороговое значение изображения, кластеризация K-средних, методы разбиения графа и т. д.
Также были предложены многие архитектуры глубокого обучения (например, полностью подключенные сети для сегментации изображений), но модель Google DeepLab дала на сегодняшний день наилучшие результаты. Вот почему в этой статье мы сосредоточимся на использовании DeepLab.
Начало работы с DeepLab от Google
DeepLab — это современная модель семантической сегментации, разработанная и открытая компанией Google еще в 2016 году. С тех пор в модель было внесено множество улучшений, включая DeepLab V2, DeepLab V3 и последнюю версию DeepLab V3+.
В этом разделе мы поймем архитектуру DeepLab V3+ и узнаем, как использовать ее в нашем пользовательском наборе данных.
Модель DeepLab в целом состоит из двух этапов:
- Этап кодирования. Целью этого этапа является извлечение необходимой информации из изображения. Это делается с помощью предварительно обученной сверточной нейронной сети. Теперь вам может быть интересно, почему CNN?
Если вы ранее работали с CNN для классификации изображений, то вы, возможно, знаете, что сверточные слои ищут разные функции в изображении и передать эту информацию последующим слоям, теперь для задачи сегментации, которая включает в себя основную информацию, объекты, присутствующие на изображении, и их местоположение, и, поскольку CNN отлично выполняет классификацию, они могут легко обнаружить присутствующие объекты. - Этап декодирования. Информация, извлеченная на этапе кодирования, используется здесь для восстановления вывода соответствующих размеров.
Какие методы используются на обоих этих этапах? Давайте разберемся!
Понимание методов, используемых на этапах кодирования и декодирования
Архитектура DeepLab основана на объединении двух популярных архитектур нейронных сетей:
Нам нужно убедиться, что наша модель устойчива к изменениям размера объектов при работе с CNN. Это связано с тем, что если бы наша модель обучалась с использованием только изображений небольших объектов, то она могла бы плохо работать с масштабированными версиями входных изображений.
Эта проблема может быть решена с помощью сетей объединения пространственных пирамид. Они используют несколько масштабированных версий входных данных для обучения и, следовательно, собирают многомасштабную информацию.
Сети объединения пространственных пирамид способны кодировать многомасштабную контекстную информацию. Это делается путем исследования входящих функций или операций объединения с несколькими скоростями и с эффективным полем зрения.
Сети пула пространственных пирамид обычно используют параллельные версии одной и той же базовой сети для обучения на входных данных в разных масштабах и объединения функций на более позднем этапе.
Не все, что присутствует во входных данных, будет полезно для нашей модели. Мы хотели бы извлечь только важные функции, которые можно использовать для представления большей части информации. Это просто хорошее эмпирическое правило, которому нужно следовать в целом.
Именно здесь сети Encoder-Decoder работают хорошо. Они учатся преобразовывать входные данные в плотную форму, которую можно использовать для представления всей входной информации (даже для реконструкции входных данных).
Введение в Atrous Convolutions
Объединение пространственных пирамид использует несколько экземпляров одной и той же архитектуры. Это приводит к увеличению вычислительной сложности и требований к памяти при обучении. Не у всех из нас графические процессоры работают свободно, так как же нам смягчить это?
Как обычно, у Google есть ответ.
DeepLab ввел понятие сложных сверток, обобщенной формы операции свертки. Для сверток Atrous требуется параметр, называемый скоростью, который используется для явного управления эффективным полем зрения свертки. Обобщенная форма атрофических извилин дается как:
Нормальная свертка — это частный случай сложных сверток с r = 1.
Следовательно, сложные свертки могут собирать информацию из большего эффективного поля зрения, используя то же количество параметров и вычислительную сложность.
DeepLab использует жесткую свертку со скоростями 6, 12 и 18
Название Atrous Spatial Pyramid Pooling (ASPP) появилось благодаря DeepLab, использующему Spatial Pyramid Pooling с жесткими извилинами. Здесь АСПП использует 4 параллельные операции, т.е. 1 х 1 свертка и 3 х 3 атрусная свертка со скоростями [6, 12, 18]. Он также добавляет функции уровня изображения с глобальным средним пулом. Билинейная повышающая дискретизация используется для масштабирования объектов до правильных размеров.
Разделимые по глубине свертки
Глубокие свертки — это метод выполнения сверток с меньшим количеством вычислений, чем стандартная операция свертки. Это включает в себя разбиение операции свертки на два этапа:
- Глубинная свертка
- Точечная свертка
Давайте разберемся в этом на примере.
Предположим, у нас есть изображение размером 12 x 12, состоящее из 3 каналов. Итак, форма ввода будет 12 х 12 х 3. Мы хотим применить к этому входу свертку 5 х 5.
Поскольку у нас есть 3 ядра 5 x 5 для каждого входного канала, применение свертки с этими ядрами дает выходную форму 8 x 8 x 1. Нам нужно использовать больше ядер и складывать выходные данные вместе, чтобы увеличить количество выходных каналов. .
Я проиллюстрирую эти две концепции с помощью диаграмм, чтобы дать вам интуитивное понимание того, о чем мы говорим.
Глубинная свертка
На этом первом шаге мы применяем свертку с одним ядром формы 5 x 5 x 1, что дает нам результат размером 8 x 8 x 3:
Точечная свертка
Теперь мы хотим увеличить количество каналов. Мы будем использовать ядра 1 x 1 с глубиной, соответствующей глубине входного изображения (3 в нашем случае). Эта свертка 1 x 1 x 3 дает результат формы 8 x 8 x 1. Мы можем использовать столько сверток 1 x 1 x 3, сколько требуется, чтобы увеличить количество каналов:
Допустим, мы хотим увеличить количество каналов до 256. Что нам делать? Я хочу, чтобы вы подумали об этом, прежде чем увидите решение.
Мы можем использовать 256 1 x 1 x 3 на входе 8 x 8 x 3 и получить выходную форму 8 x 8 x 256.
Понимание архитектуры модели DeepLab
DeepLab V3 использует предварительно обученный Resnet-101 ImageNet с жесткими извилинами в качестве основного экстрактора признаков. В модифицированной модели ResNet в последнем блоке ResNet используются жесткие извилины с разной скоростью расширения. Он использует Atrous Spatial Pyramid Pooling и билинейную повышающую дискретизацию для модуля декодера поверх модифицированного блока ResNet.
DeepLab V3+ использует Aligned Xception в качестве основного средства извлечения признаков со следующими изменениями:
- Все операции максимального объединения заменены разделяемой по глубине сверткой с шагом.
- Дополнительная пакетная нормализация и активация ReLU добавляются после каждой свертки по глубине 3 x 3.
- Глубина модели увеличена без изменения структуры входной сети.
Декодер DeepLab V3+
Кодировщик основан на шаге вывода (отношении размера исходного изображения к размеру конечного закодированного объекта), равном 16. Вместо использования билинейной повышающей дискретизации с коэффициентом 16 закодированные объекты сначала передискретизируется с коэффициентом 4 и объединяется с соответствующими низкоуровневыми функциями из модуля кодера, имеющими те же пространственные размеры.
Перед конкатенацией к объектам низкого уровня применяются свертки 1 x 1, чтобы уменьшить количество каналов. После конкатенации применяются несколько сверток 3 x 3, и функции повышают дискретизацию в 4 раза. Это дает выход того же размера, что и входное изображение.
Обучение DeepLabV3+ на пользовательском наборе данных
Давайте запачкаем руки кодированием! Во-первых, клонируйте репозиторий Github исследования Google, чтобы загрузить весь код на свой локальный компьютер.
Подготовка набора данных. Для обучения модели DeepLab на нашем пользовательском наборе данных нам необходимо преобразовать данные в формат TFRecord. Переместите свой набор данных в model/research/deeplab/datasets. Наш каталог набора данных должен иметь следующую структуру:
TFRecord — это специальный формат хранения двоичных данных TensorFlow. Он упрощает работу с огромными наборами данных, поскольку двоичные данные занимают гораздо меньше места и могут быть считаны очень эффективно.
Формат TFRecords очень удобен при работе с наборами данных, которые слишком велики для хранения в памяти. Теперь с диска считываются только те данные, которые требуются в данный момент. Звучит как беспроигрышный вариант!
- Папка JPEGImages содержит исходные изображения.
- Папка SegmentationClass содержит изображения с метками классов в виде значений пикселей (ожидается изображение с одним каналом, где значением каждого пикселя является classID)
- train.txt и val.txt содержат имена изображений, которые будут использоваться для обучения и проверки соответственно.
- trainval.txt содержит имена всех изображений
Теперь запустите build_voc2012_data.py со значениями флагов, измененными в соответствии с нашей структурой каталогов. Это преобразует ваши данные в формат TFRecord и сохраняет их в место, указанное ‘— output_dir’.
Откройте segmentation_dataset.py и добавьте DatasetDescriptor, соответствующий вашему пользовательскому набору данных. Например, мы использовали набор данных Pascal с 1464 изображениями для обучения и 1449 изображений для проверки.
А теперь пришло время обучить нашу собственную модель сегментации изображений!
Обучение нашей модели сегментации изображений
Нам нужно запустить файл train.py, находящийся в папке models/research/deeplab/. Измените флаги в соответствии с вашими требованиями.
# From tensorflow/models/research/ python deeplab/train.py \ --logtostderr \ --training_number_of_steps=90000 \ --train_split="train" \ --model_variant="xception_65" \ --atrous_rates=6 \ --atrous_rates=12 \ --atrous_rates=18 \ --output_stride=16 \ --decoder_output_stride=4 \ --train_crop_size=769 \ --train_crop_size=769 \ --train_batch_size=1 \ --dataset="cityscapes" \ --tf_initial_checkpoint=${PATH_TO_INITIAL_CHECKPOINT} \
Это обучит модель на вашем наборе данных и сохранит файлы контрольных точек в train_logdir.
Оценка нашей модели сегментации изображений
Теперь, когда у нас есть файлы контрольных точек для нашей обученной модели, мы можем использовать их для оценки ее производительности. Запустите скрипт eval.py с измененными ФЛАГами. Это позволит оценить модель изображений, упомянутых в файле val.txt.
python "${WORK_DIR}"/eval.py \ --logtostderr \ --eval_split="val" \ --model_variant="xception_65" \ --atrous_rates=6 \ --atrous_rates=12 \ --atrous_rates=18 \ --output_stride=16 \ --decoder_output_stride=4 \ --eval_crop_size=513 \ --eval_crop_size=513 \ --checkpoint_dir="${TRAIN_LOGDIR}" \ --eval_logdir="${EVAL_LOGDIR}" \ --dataset_dir="${PASCAL_DATASET}" \ --max_number_of_evaluations=1
Мы выполнили этап обучения для 1000 шагов и получилиmeanIntersectionOverUnion0,834894478.
Помните, что вариант_модели для обучения и оценки должен быть одинаковым.
Аналогичным образом запустите vis.py с соответствующими флагами для визуализации результатов:
python "${WORK_DIR}"/vis.py \ --logtostderr \ --vis_split="val" \ --model_variant="xception_65" \ --atrous_rates=6 \ --atrous_rates=12 \ --atrous_rates=18 \ --output_stride=16 \ --decoder_output_stride=4 \ --vis_crop_size=513 \ --vis_crop_size=513 \ --checkpoint_dir="${TRAIN_LOGDIR}" \ --vis_logdir="${VIS_LOGDIR}" \ --dataset_dir="${PASCAL_DATASET}" \ --max_number_of_iterations=1
Давайте посмотрим на некоторые результаты нашей обученной модели.
Хорошо смотритесь! Поздравляем с обучением и запуском вашей первой модели сегментации изображений.
Конечные примечания
Это было довольно много, чтобы научиться переваривать! После того, как вы ознакомитесь с этими концепциями, попробуйте использовать их для своего пользовательского набора данных (Kitti — хороший выбор из-за его небольшого размера) и узнайте больше интересных практических вариантов использования.
Я настоятельно рекомендую вам ознакомиться с документом DeepLab и сообщением в блоге Google AI, касающимся этого выпуска:
Я с нетерпением жду возможности поделиться вашими отзывами, предложениями и опытом использования DeepLab. Вы можете связаться со мной в разделе комментариев ниже.
Вы также можете прочитать эту статью о приложении Analytics Vidhya для Android.
Первоначально опубликовано на https://www.analyticsvidhya.com 26 февраля 2019 г.