Статья перенесена из публичного аккаунта WeChat [Machine Learning Alchemy]. Перепечатка статьи или сообщение для связи с автором WeChat: cyx645016617
Unet на самом деле довольно прост, поэтому сегодняшняя статья не будет очень длинной.
0 Обзор
Семантическая сегментация — важная ветвь обработки изображений и машинного зрения. В отличие от задач классификации, семантическая сегментация должна определять категорию каждого пикселя изображения для точной сегментации. Семантическая сегментация в настоящее время широко используется в автономном вождении, автоматическом картографировании, медицинской визуализации и других областях.
На приведенном выше рисунке показаны результаты сегментации задачи мобильной сегментации в автономном вождении, которая может эффективно идентифицировать автомобили (темно-синий), пешеходов (красный), светофоры (желтый), дороги (светло-фиолетовый) и т. д.
Можно сказать, что Унетсамый обычный, самый простой— это простая, эффективная, понятная, простая в построении модель сегментации, которую можно обучить на небольших наборах данных.
Unet — это уже очень старая модель сегментации, модель, предложенная в «U-Net: сверточные сети для сегментации биомедицинских изображений» в 2015 году.
Ссылка на бумагу:АР Вест V.org/ABS/1505.04…
До Unet это была старая сеть FCN, FCN была обрывком Fully Convolutional Netowkrs, но этоВ основном это фреймворк и текущая сеть сегментации, кто посмеет сказать, что сверточный слой не используется.Однако точность сети FCN ниже, и ее не так просто использовать, как Unet. Сейчас есть Segnet, Mask RCNN, DeepLabv3+ и другие сети, но сегодня я сначала представлю Unet, ведь от одного укуса не потолстеешь.
1 Unet
Unet на самом деле довольно прост, поэтому сегодняшняя статья не будет очень длинной.
1.1 Выдвинуть первоначальное намерение (не важно)
- Первоначальной целью Unet было решить проблему сегментации медицинских изображений;
- U-образная сетевая структура для получения контекстной информации и информации о местоположении;
- В 2015 году неоднократно выигрывал первые места в соревнованиях по отслеживанию ячеек ISBI.Изначально это должно было решить задачу сегментации на клеточном уровне.
1.2 Структура сети
Эта структура состоит в том, чтобы сначала свернуть и объединить изображение.В документе Unet оно объединяется 4 раза.Например, изображение в начале имеет размер 224x224, затем оно станет 112x112, 56x56, 28x28, 14x14 с четырьмя различными размерами.Затем мы увеличиваем или деконволюцируем карту признаков 14 x 14, чтобы получить карту признаков 28 x 28. Эта карта признаков 28 x 28 и предыдущая карта признаков 28 x 28 объединяются с повреждением канала, а затем скручивается карта объединенных признаков. Продукт и повышающая дискретизация для получения 56 x 56 карта признаков, которая затем объединяется с предыдущей функцией 56x56, свертывается, а затем подвергается повышающей дискретизации.После четырех апсемплингов можно получить результат прогнозирования 224x224 с тем же размером, что и входное изображение.
По сути, в целом это тоже структура Encoder-Decoder:Сеть Unet очень проста: первая половина — это извлечение признаков, а вторая половина — повышение частоты дискретизации. В некоторых источниках эта структура называетсяАрхитектура кодировщик-декодер, потому что общая структура сети представляет собой большую английскую букву U, поэтому она называется U-net.
- Кодер: левая половина состоит из двух сверточных слоев 3x3 (RELU) плюс слой максимального пула 2x2 для формирования модуля понижающей дискретизации (как можно увидеть в коде позже);
- Декодер: есть половинные части, которые состоят из слоя свертки с повышающей дискретизацией (слоя деконволюции) + сшивки признаков concat + двух слоев свертки 3x3 (ReLU) многократно (как видно в коде);
В то время, по сравнению с ранее предложенной сетью FCN, Unet использовалсоединениекак метод слияния карт признаков.
- FCN объединяет функции, добавляя соответствующие значения пикселей карты функций;
- U-net может формировать более толстые элементы, объединяя количество каналов, конечно, это будет потреблять больше памяти;
Преимущества Unet, на мой взгляд, таковы: карта объектов, полученная за счет более глубокого сетевого слоя, имеет большее поле зрения, неглубокая свертка фокусируется на текстурных функциях, а глубокая сеть фокусируется на основных функциях, поэтому глубокие и мелкие функции все с сеткой Значимое; другой момент заключается в том, что край карты признаков большего размера, полученной с помощью деконволюции, является недостатком информации.В конце концов, каждый признак субдискретизации и уточнения неизбежно потеряет некоторые краевые признаки, и потерянные признаки не будут восстановлены. от повышающей дискретизации, поэтому поиск краевых функций достигается за счет объединения функций.
2 Почему Unet хорошо справляется с сегментацией медицинских изображений
Это открытый вопрос, если у вас есть какие-либо мнения, пожалуйста, ответьте на обсуждение.
Большинство задач семантической сегментации медицинских изображений сначала используют Unet в качестве основы. Конечно, преимущества Unet, описанные в предыдущей главе, определенно могут быть использованы в качестве ответа на этот вопрос. Давайте поговорим об этом здесь.Особенности медицинской визуализации
Согласно обсуждению пользователей сети, полученные результаты:
-
Семантика медицинских изображений относительно проста, а структура фиксирована. Следовательно, семантическая информация относительно проста по сравнению с автоматическим вождением, поэтому нет необходимости отфильтровывать бесполезную информацию.Все признаки медицинских изображений важны, поэтому важны низкоуровневые признаки и высокоуровневые семантические признаки, поэтому лучше использовать структуру соединения с пропуском (сращивание признаков) U-образной структуры.
-
Медицинские изображения содержат меньше данных и их трудно получить.Объем данных может составлять всего несколько сотен или даже меньше 100. Поэтому, если используется большая сеть, такая как DeepLabv3+, ее легко переобучить. Преимущество больших сетей заключается в более сильных возможностях представления изображений, в то время как более простые и менее многочисленные медицинские изображения не содержат так много контента для выражения, поэтому некоторые люди обнаружили, чтоВ малом порядке раздельная модель SOTA и облегченный Unet не имеют преимущества перед богами и демонами.
-
Медицинская визуализация имеет тенденцию быть мультимодальной. Например, в соревновании ISLES по инфаркту мозга чиновник предоставил данные CBF, MTT, CBV и других мультимодальных модальностей (можно этого не понимать). следовательноВ задачах медицинской визуализации часто необходимо разработать сеть для извлечения различных модальных функций, поэтому легкий и простой Unet может иметь большее рабочее пространство.
3 Код модели Pytorch
Это код, который я написал сам, поэтому он не очень краток, но его следует хорошо понять, и он точно такой же, как я объяснял ранее (вы можете связаться со мной, если у вас есть какие-либо вопросы: cyx645016617):
import torch
import torch.nn as nn
import torch.nn.functional as F
class double_conv2d_bn(nn.Module):
def __init__(self,in_channels,out_channels,kernel_size=3,strides=1,padding=1):
super(double_conv2d_bn,self).__init__()
self.conv1 = nn.Conv2d(in_channels,out_channels,
kernel_size=kernel_size,
stride = strides,padding=padding,bias=True)
self.conv2 = nn.Conv2d(out_channels,out_channels,
kernel_size = kernel_size,
stride = strides,padding=padding,bias=True)
self.bn1 = nn.BatchNorm2d(out_channels)
self.bn2 = nn.BatchNorm2d(out_channels)
def forward(self,x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
return out
class deconv2d_bn(nn.Module):
def __init__(self,in_channels,out_channels,kernel_size=2,strides=2):
super(deconv2d_bn,self).__init__()
self.conv1 = nn.ConvTranspose2d(in_channels,out_channels,
kernel_size = kernel_size,
stride = strides,bias=True)
self.bn1 = nn.BatchNorm2d(out_channels)
def forward(self,x):
out = F.relu(self.bn1(self.conv1(x)))
return out
class Unet(nn.Module):
def __init__(self):
super(Unet,self).__init__()
self.layer1_conv = double_conv2d_bn(1,8)
self.layer2_conv = double_conv2d_bn(8,16)
self.layer3_conv = double_conv2d_bn(16,32)
self.layer4_conv = double_conv2d_bn(32,64)
self.layer5_conv = double_conv2d_bn(64,128)
self.layer6_conv = double_conv2d_bn(128,64)
self.layer7_conv = double_conv2d_bn(64,32)
self.layer8_conv = double_conv2d_bn(32,16)
self.layer9_conv = double_conv2d_bn(16,8)
self.layer10_conv = nn.Conv2d(8,1,kernel_size=3,
stride=1,padding=1,bias=True)
self.deconv1 = deconv2d_bn(128,64)
self.deconv2 = deconv2d_bn(64,32)
self.deconv3 = deconv2d_bn(32,16)
self.deconv4 = deconv2d_bn(16,8)
self.sigmoid = nn.Sigmoid()
def forward(self,x):
conv1 = self.layer1_conv(x)
pool1 = F.max_pool2d(conv1,2)
conv2 = self.layer2_conv(pool1)
pool2 = F.max_pool2d(conv2,2)
conv3 = self.layer3_conv(pool2)
pool3 = F.max_pool2d(conv3,2)
conv4 = self.layer4_conv(pool3)
pool4 = F.max_pool2d(conv4,2)
conv5 = self.layer5_conv(pool4)
convt1 = self.deconv1(conv5)
concat1 = torch.cat([convt1,conv4],dim=1)
conv6 = self.layer6_conv(concat1)
convt2 = self.deconv2(conv6)
concat2 = torch.cat([convt2,conv3],dim=1)
conv7 = self.layer7_conv(concat2)
convt3 = self.deconv3(conv7)
concat3 = torch.cat([convt3,conv2],dim=1)
conv8 = self.layer8_conv(concat3)
convt4 = self.deconv4(conv8)
concat4 = torch.cat([convt4,conv1],dim=1)
conv9 = self.layer9_conv(concat4)
outp = self.layer10_conv(conv9)
outp = self.sigmoid(outp)
return outp
model = Unet()
inp = torch.rand(10,1,224,224)
outp = model(inp)
print(outp.shape)
==> torch.Size([10, 1, 224, 224])
Во-первых, повышающая дискретизация и два сверточных слоя строятся отдельно для многократного использования в построении модели Unet. Тогда выходные и входные данные модели имеют одинаковый размер, что указывает на то, что модель может работать.
Справочный блог: