Сегментация: семантическая, инстанс и U-Net

Сегментация — самая «дотошная» задача: решение принимается не по картинке и не по рамке, а по каждому пикселю.

Сегментация — разметка каждого пикселя изображения классом, что даёт маску с точными границами объектов.

Зачем такая точность

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

Семантическая против инстанс

ТипЧто различаетПример
Семантическаяклассы, но не отдельные объектывсе пиксели «человек» — один класс, людей не разделяет
Инстанс (экземплярная)отдельные объекты одного классачеловек №1, человек №2, человек №3 — раздельно

Семантическая сегментация отвечает «к какому классу относится пиксель», но три стоящих рядом человека сольёт в одну область «человек». Инстанс-сегментация различает их как отдельные экземпляры — это сложнее и ближе к детекции, но с точными масками вместо рамок.

Архитектура U-Net

Классификационная CNN сжимает картинку до набора чисел — но для сегментации нужен выход того же размера, что и вход (маска по пикселям). Поэтому архитектуры сегментации строят в форме буквы U:

Вход (картинка)
   \  кодировщик: свёртки+пулинг, размер падает,
    \ выделяются признаки («что на картинке»)
     \____________ узкое «горлышко» ____________
     /
    /  декодировщик: апсемплинг, размер растёт обратно,
   /   восстанавливается маска («где именно»)
Выход (маска того же размера)

Левая ветвь (кодировщик) сжимает картинку, понимая «что» на ней. Правая (декодировщик) постепенно увеличивает размер обратно, восстанавливая точную маску. Ключевая хитрость U-Net — skip-связи между симметричными уровнями: они возвращают декодировщику точные детали границ, потерянные при сжатии. Без них маска вышла бы размытой.

Как меряют качество

Для масок используют тот же IoU, что и в детекции, но по пикселям (часто его называют Jaccard), и близкий Dice-коэффициент. Оба сравнивают предсказанную маску с истинной: насколько они совпадают по площади.

# IoU по пикселям маски (1 = объект, 0 = фон)
pred = [1,1,0,0, 1,1,0,0]
true = [1,1,1,0, 1,0,0,0]

inter = sum(p == 1 and t == 1 for p, t in zip(pred, true))
union = sum(p == 1 or t == 1 for p, t in zip(pred, true))
print("Пересечение:", inter)
print("Объединение:", union)
print("IoU маски:", round(inter / union, 3))

Вывод:

Пересечение: 3
Объединение: 5
IoU маски: 0.6

Итог

  • Сегментация размечает каждый пиксель — точнее рамок детекции.
  • Семантическая различает классы, инстанс — ещё и отдельные объекты класса.
  • U-Net: кодировщик сжимает («что»), декодировщик восстанавливает маску («где»), skip-связи возвращают детали.
  • Качество маски меряют IoU/Dice по пикселям.
Проверьте себя
1. Чем инстанс-сегментация отличается от семантической?
AИнстанс работает быстрее
BСемантическая помечает классы, но не разделяет объекты; инстанс различает отдельные экземпляры одного класса
CСемантическая точнее по пикселям
DМежду ними нет разницы
2. Зачем в U-Net нужны skip-связи между кодировщиком и декодировщиком?
AЧтобы ускорить обучение в 10 раз
BЧтобы вернуть декодировщику точные детали границ, потерянные при сжатии, и получить чёткую маску
CЧтобы уменьшить число классов
DЧтобы перевести картинку в HSV
3. Почему для сегментации не подходит обычная классификационная CNN без декодировщика?
AОна слишком быстрая
BОна сжимает картинку до набора чисел, а нужен выход того же размера — маска по пикселям
CОна не умеет считать свёртку
DОна работает только с серым
Поддержать проект