Как понять U-Net самым простым способом.
Всем привет!
В этой статье я хочу просто объяснить одну из самых популярных структур моделей для решения задачи сегментации изображений - UNET.
Если вы не слышали о нем и не видели его архитектуру, это не проблема, потому что в этой статье я начну с простой структуры, а в конце остановлюсь на традиционном UNET. Давайте начнем.
Содержание
- Какую задачу решает UNET?
- МиУНЕТ
- Оригинальный UNET
Какую задачу решает UNET?
Модель UNET создавалась в медицине для поиска опухолей в легких или головном мозге, но в настоящее время имеет гораздо более широкую область применения.
Например, ваша задача - найти на изображениях прямоугольники, независимо от того, какого они цвета или формы.
У нас есть красный и желтый прямоугольники на зеленом фоне. Это вход для модели UNET.
Нам нужно определить положительные области на изображении, где у нас есть прямоугольники как 1 и отрицательные области как 0 (как двоичная классификация). Если мы изменим значения пикселей красного и желтого цветов на 1 и зеленую область на 0, мы получим изображение в масштабе серого или двоичную маску или цель ( контролируемый срок обучения):
Модель UNET научится находить эти белые области на изображениях. Он работает с любыми объектами: кошками, людьми, автомобилями, зданиями, дорогами и т. Д.
МиУНЕТ
MiUNET или mini UNET - это упрощенная и урезанная версия исходного UNET. (и где-то поменяли)
Если вы хотите понять что-то сложное, самый правильный способ - упростить и исследовать каждый шаг, чтобы объяснить это простейшими словами даже ребенку. - древний математик Кирюша, 200 г. до н.э.
Прежде всего, возьмем данные из предыдущего абзаца и добавим туда фигуры.
Упрощенная архитектура будет состоять из четырех частей: свертка, повышающая дискретизация, конкатенация и снова свертка (но с другой целью).
Теперь давайте пройдемся по каждому этапу и исследуем его.
- Свертка + 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.
Удачи !
С наилучшими пожеланиями, Бондаренко К., инженер по машинному обучению.