Как понять U-Net самым простым способом.

Всем привет!

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

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

Содержание

  1. Какую задачу решает UNET?
  2. МиУНЕТ
  3. Оригинальный UNET

Какую задачу решает UNET?

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

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

У нас есть красный и желтый прямоугольники на зеленом фоне. Это вход для модели UNET.

Нам нужно определить положительные области на изображении, где у нас есть прямоугольники как 1 и отрицательные области как 0 (как двоичная классификация). Если мы изменим значения пикселей красного и желтого цветов на 1 и зеленую область на 0, мы получим изображение в масштабе серого или двоичную маску или цель ( контролируемый срок обучения):

Модель UNET научится находить эти белые области на изображениях. Он работает с любыми объектами: кошками, людьми, автомобилями, зданиями, дорогами и т. Д.

МиУНЕТ

MiUNET или mini UNET - это упрощенная и урезанная версия исходного UNET. (и где-то поменяли)

Если вы хотите понять что-то сложное, самый правильный способ - упростить и исследовать каждый шаг, чтобы объяснить это простейшими словами даже ребенку. - древний математик Кирюша, 200 г. до н.э.

Прежде всего, возьмем данные из предыдущего абзаца и добавим туда фигуры.

Упрощенная архитектура будет состоять из четырех частей: свертка, повышающая дискретизация, конкатенация и снова свертка (но с другой целью).

Теперь давайте пройдемся по каждому этапу и исследуем его.

  1. Свертка + MaxPooling

Давайте создадим этот слой с ядром свертки = 3x3x3

Шаг = 1

Padding = 0

И количество фильтров = 64

То же самое и с MaxPooling (форма фильтра 3x3x64).

Форма вывода свертки = (10–3 + 2 * 0) / 1 +1 = 8

После свертки получаем изображение (тензор) 8x8x64.

Применяя MaxPooling, мы получаем (8–3 + 2 * 0) / 1 +1 = 6, а форма изображения будет 6x6x64.

В основном мы сделали так:

Мы уменьшили ширину и высоту, но увеличили глубину с 3-х канального изображения RGB до 64-слойного изображения глубины.

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

2. Повышение дискретизации

Что такое повышающая дискретизация? Нам нужно увеличить ширину и высоту нашего изображения до 8x8 (объяснено далее), и есть несколько способов сделать передискретизацию, здесь будет показан «ближайший сосед».

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

Мы дублируем значения пикселей для каждого слоя без каких-либо весов и других сложных операций.

3. Конкатенация

Вот ответ, почему нам нужно повышать дискретизацию до 8, а не до 10.

Если вы посмотрите на картинку в начале этого абзаца с общей структурой модели, вы увидите, что этот слой свертки имеет два выхода с формами 8x8x64 , где один переходит к maxpooling, а другой к операции конкатенации.

Конкатенация производится по третьей оси (глубина):

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

4. Свертка

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

Мы применим здесь два сверточных слоя без maxpooling.

Первый: F = 3x3x128, P = 2, S = 1, количество фильтров = 64.

Получаем вывод: 10х10х64.

Второй: F = 3x3x64, P = 1, S = 1, количество фильтров = 1.

Результат: 10x10x1

Отлично, теперь давайте посмотрим на модель целиком.

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

Вы можете попробовать это на Python, используя keras:

from keras import Input, Model
from keras.layers import Conv2D, MaxPooling2D, concatenate, UpSampling2D
from keras.optimizers import Adam


input_size = (None, None, 3)

inputs = Input(shape=input_size)
conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)


conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)


ups = UpSampling2D(size=(2, 2))(conv2)
up1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(ups)
merge1 = concatenate([conv1, up1], axis=3)


conv3 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge1)
conv4 = Conv2D(1, 1, activation='sigmoid')(conv3)

model = Model(input=inputs, output=conv4)

model.compile(optimizer=Adam(lr=0.1), loss='binary_crossentropy')
print(model.summary())

В этом состоянии ваша модель сможет работать с любой исходной формой данных изображения (высотой и шириной) и возвращать те же самые.

Краткий обзор оригинального UNET

В левой части структуры модели находятся блоки сверточных слоев + активации ReLU и слоев MaxPooling. В этом примере исходное изображение имеет форму 572x572x1, внизу форма будет 28x28x1024 после свертки и объединения.

В правой части модели происходит процесс уменьшения глубины и увеличения высоты и ширины. Переход снизу вверх: 28x28x1024 → 56x56x1536 (самая низкая конкатенация и первая повышающая дискретизация) → 54x54x512 (свертка для уменьшения глубины и уменьшения бит W и H) → 104x104x768 (вторая повышающая дискретизация) → 102x102x256 (свертка для уменьшения глубины) → 100x100x256 → 200x200x384 → 198x198x128 → 196x196x128 → 392x392x192 → 390x390x64 → 388x388x64 → 388x388x2.

В этой модели вывод имеет глубину = 2. Это может быть ссылка на количество классов для сегментации, но в нашей задаче двоичной сегментации вывод должен быть 388x388x1 в качестве двоичной маски серой шкалы.

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

Я надеялся, что эта статья помогла вам разобраться в UNET.

Удачи !

С наилучшими пожеланиями, Бондаренко К., инженер по машинному обучению.