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

Обзор

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

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

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

Как работает сегментация?

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

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

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

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

Бинарная сегментация

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

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

Например, если пиксель [0,0] в верхнем левом углу маски имеет значение 0,8, это означает, что пиксель [0,0] в верхнем левом углу изображения принадлежит классу автомобилей с вероятностью 0,8. .

Поскольку у нас есть только два класса — автомобиль и фон — это называется бинарной сегментацией. Мы используем сигмовидную активацию, чтобы гарантировать, что все выходные данные находятся между нулем и единицей. Чтобы делать прогнозы, мы устанавливаем пороговое значение, например 0,5, при превышении которого делаем вывод, что пиксель принадлежит к данному классу.

Мультиклассовая сегментация

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

Если наше входное изображение имеет размер 256x256x3, мы выводим вектор маски 256x256x4. Количество каналов в векторе маски определяется количеством классов, поэтому первый канал соответствует классу пешеходов, второй — классу тротуаров, а третий — улице. У нас есть четвертый канал для представления фонового класса.

Затем мы формируем распределение вероятностей по классам, выполняя операцию softmax на каналах. Например, рассмотрим пиксель [0,0] в маске. Затем в маске элемент [0,0,0] (первая строка, первый столбец и первый канал) представляет вероятность того, что пиксель [0,0] во входном изображении принадлежит классу пешеходов.

Учитывая все четыре канала, пусть элементы [0,0,0], [0,0,1], [0,0,2] и [0,0,3] в маске равны [0,1, 0,6, 0,2, 0,1 ]. Это распределение подразумевает, что пиксель [0,0] на входном изображении принадлежит классу тротуара.

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

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

Мы также можем использовать Intersection over Union (IoU) или потерю Dice. Эта потеря иногда предпочтительнее, потому что она наказывает модель за то, что она не создает маску, которая хорошо перекрывается с предоставленной меткой.

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

Учебное пособие по семантической сегментации

Обзор

Здесь мы рассмотрим применение семантической сегментации к набору данных МРТ-сегментация мозга, доступному на Kaggle. Это задача бинарной сегментации, в которой нас просят определить местонахождение глиомы на МРТ головного мозга, полученной из архива изображений рака.

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

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

Чтение данных

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

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

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

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

Модель

Поскольку уже было показано, что она эффективна в медицинских приложениях для сегментации, мы будем использовать модель UNet. Существует также реализация UNet++ в ядре Kaggle, указанная ниже.

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

Модель добавляет высокоуровневые карты объектов к низкоуровневым картам объектов, чтобы высокоуровневая информация распространялась на глубокие уровни сети, позволяя этим функциям обеспечивать контекст для окончательного прогноза.

Обучение

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

Результаты

Ниже приведены некоторые результаты экспериментов. Они генерируются с помощью UNet на расширенном наборе данных вместе с Dice Loss. Результаты различных других экспериментов доступны в оригинальной записной книжке Kaggle.

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

Вывод

Здесь мы узнали, как работает сегментация изображений и как обучить модель в PyTorch сегментировать изображения. Исходное ядро ​​Kaggle содержит больше экспериментов, код обработки данных и реализации UNet и UNet++. Пожалуйста, оставьте отзыв, похлопайте в ладоши и следите за новостями!

Ресурсы