- v1 название статьи: "СЕМАНТИЧЕСКАЯ СЕГМЕНТАЦИЯ ИЗОБРАЖЕНИЙ С ГЛУБОКИМ СВЕРТОЧНЫМ СЕТКОМ И ПОЛНОСТЬЮ СВЯЗНОЙ CRFS"
- ссылка на документ v1:АР Вест V.org/PDF/1412.70…
- Название статьи v2: «DeepLab: Семантическая сегментация изображений с помощью глубоких сверточных сетей, Atrous Convolution и полносвязных CRF»
- ссылка на документ v2:АР Вест V.org/ABS/1606.00…
- Название статьи v3: «Переосмысление Atrous Convolution для семантической сегментации изображений»
- ссылка на документ v3:АР Вест V.org/ABS/1706.05…
- Название статьи v3+: «Кодер-декодер с Atrous Separable Convolution для сегментации семантического изображения»
- ссылка на документ v3+:АР Вест V.org/ABS/1802.02…
0 Обзор
Всего DeepLab разделен на 4 версии, а именно: v1, v2, v3 и v3+. Небольшое чувство YOLO. Каждому поколению DeepLab есть что сказать об этом.
У Unet есть естественные преимущества для обработки медицинских изображений, поэтому, когда я читал статью DeepLab, я не стремился воспроизвести его код, а изучить его основные навыки, а затем интегрировать его в Unet.
1 v1
В версии первого поколения ключевым изменением является изменение структуры VGG на DRN.Чтобы узнать о DRN, см.:Наггетс.Талант/пост/691748…
Я нашел модифицированный код VGG в deeplabv1 pytorch, вы можете им насладиться:
import torch
import torch.nn as nn
from torchvision import models
class VGG16_LargeFOV(nn.Module):
def __init__(self, num_classes=21, input_size=321, split='train', init_weights=True):
super(VGG16_LargeFOV, self).__init__()
self.input_size = input_size
self.split = split
self.features = nn.Sequential(
### conv1_1 conv1_2 maxpooling
nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
### conv2_1 conv2_2 maxpooling
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
### conv3_1 conv3_2 conv3_3 maxpooling
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
### conv4_1 conv4_2 conv4_3 maxpooling(stride=1)
nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
### conv5_1 conv5_2 conv5_3 (dilated convolution dilation=2, padding=2)
### maxpooling(stride=1)
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=2, dilation=2),
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=2, dilation=2),
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=2, dilation=2),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
### average pooling
nn.AvgPool2d(kernel_size=3, stride=1, padding=1),
### fc6 relu6 drop6
nn.Conv2d(512, 1024, kernel_size=3, stride=1, padding=12, dilation=12),
nn.ReLU(True),
nn.Dropout2d(0.5),
### fc7 relu7 drop7 (kernel_size=1, padding=0)
nn.Conv2d(1024, 1024, kernel_size=1, stride=1, padding=0),
nn.ReLU(True),
nn.Dropout2d(0.5),
### fc8
nn.Conv2d(1024, num_classes, kernel_size=1, stride=1, padding=0)
)
if init_weights:
self._initialize_weights()
def forward(self, x):
output = self.features(x)
if self.split == 'test':
output = nn.functional.interpolate(output, size=(self.input_size, self.input_size), mode='bilinear', align_corners=True)
return output
def _initialize_weights(self):
for m in self.named_modules():
if isinstance(m[1], nn.Conv2d):
if m[0] == 'features.38':
nn.init.normal_(m[1].weight.data, mean=0, std=0.01)
nn.init.constant_(m[1].bias.data, 0.0)
if __name__ == "__main__":
model = VGG16_LargeFOV()
x = torch.ones([2, 3, 321, 321])
y = model(x)
print(y.shape)
Нет ничего редкого, если вы установите pytorch, вы можете запустить его напрямую,Первый раз я увидел выпадающие 2D-слои, лол..
Выходные данные DCNN на приведенном выше рисунке относятся к результату работы VGG16, и затем они должны быть обработаны CRF. Эта CRF является условным случайным полем, я, честно говоря, не совсем понимаю эту штуку, но, к счастью, после DeepLabv3 она уже не используется. Как видно из рисунка:
- CRF имеет эффект обработки краев, и после обработки краев эффект очень хороший;
- CRF имеет количество итераций, поэтому в статье также предлагается CRFasRNN. Понятие поля достаточно сложное, благо после v3 не используется, иначе будет блокпост на инженерной дороге.
2 v2
Основанная на первой версии, эта версия находится под влиянием SPP (объединение пространственных пирамид) и предлагает объединение пространственных пирамид отверстий ASPP. Во-вторых, измените основу v1 с VGG16 на реснет.
В GoogleNet предлагается начальный модуль, а затем есть Xception.Эти начальные модули представляют собой сверточные слои разного размера ядер свертки параллельно, а затем, наконец, соединяются.Структура.
Структура ASPP здесь аналогична структуре Inception:
Он состоит из сверточных слоев с разными коэффициентами расширения, а затем применяется метод сращивания.сумма, здесь показан код pytorch структуры ASPP:
import torch
import torch.nn as nn
import torch.nn.functional as F
class _ASPP(nn.Module):
"""
Atrous spatial pyramid pooling (ASPP)
"""
def __init__(self, in_ch, out_ch, rates):
super(_ASPP, self).__init__()
for i, rate in enumerate(rates):
self.add_module(
"c{}".format(i),
nn.Conv2d(in_ch, out_ch, 3, 1, padding=rate, dilation=rate, bias=True),
)
for m in self.children():
nn.init.normal_(m.weight, mean=0, std=0.01)
nn.init.constant_(m.bias, 0)
def forward(self, x):
return sum([stage(x) for stage in self.children()])
Кроме того, v2 использует стратегию распада учебной бригады Poly:
В статье говорится, что при мощности = 0,9 эффект наилучший.
3 v3
- Использование Multi-grid, с точки зрения непрофессионала, заключается в использовании большего количества сверток расширения с большими коэффициентами расширения, коэффициент расширения v2 останавливается на 4, и теперь он равен 16:
- Добавить слой BN в структуру ASPP;
4 v3+
- Улучшение находится в разделе декодирования:
Как и в части декодера Unet, инновации в этой части ограничены.
- Опираясь на отделимую свертку MobileNet, она заменяется отделяемой сверткой коллизий:
- Рисунок на модуле Xception:
5 Резюме
В целом, я думаю, что самая большая инновация DeepLab — это объединить кодировщик DRN для семантической сегментации, а затем предложить модуль ASPP.
Кроме того, если вы чувствуете, что содержание моей статьи недостаточно подробно, вы можете прочитать исходную статью, приведенную в начале статьи, Что касается различных версий DeepLab, реализованных PyTorch, я нашел такой пост для справки:zhuanlan.zhihu.com/p/68531147