Sementic Segmentation-Segnet
Segnet
介绍
2015年,Segnet模型由Vijay Badrinarayanan, Alex Kendall, Roberto Cipolla发表, 在FCN的语义分割任务基础上,搭建编码器-解码器对称结构,实现端到端的像素级别图像分割。
Segnet作为我接触的第一个网络,其模型框架和思路都比较简单,应用当年很火的VGG16框架,去掉全连接层,搭建对称模型,但是这在各种框架还没有大肆兴起的2014年,基于Caffe实现端到端的像素级别网络模型也是很不容易的。之后在MATLAB2016中,Segnet成为内置的用于语义分割的深度学习算法。2016年,Segnet研究组在原有网络框架基础加入了跳跃连接,算是有了进一步发展。不过之后兴起的各种规模更大层次更深的深度网络(以Resnet为主要框架)已经基本把Segnet碾压。
本文对Segnet只简要介绍,对详细原理不做太多描述。
文章链接: SegNet. Arxiv收录于 2 Nov 2015 (v1), last revised 10 Oct 2016 (this version, v3)
网络框架

Segnet语义分割网络的关键在于下采样和上采样。在上采样的过程中,使用下采样时记录的Max Value像素位置指标。
Batch Normlization
在SegNet的每个卷积层后加上一个Batch Normlization层,Batch Normlization层后面为ReLU激活层。 文中指出,加入Batch Normlization层明显改善了语义分割效果。
Loss Function
使用Softmax 损失函数。
Segnet网络代码
基于Tensorflow :
#####################
# Downsampling path #
#####################
net = conv_block(inputs, 64)
net = conv_block(net, 64)
net = slim.pool(net, [2, 2], stride=[2, 2], pooling_type='MAX')
skip_1 = net
net = conv_block(net, 128)
net = conv_block(net, 128)
net = slim.pool(net, [2, 2], stride=[2, 2], pooling_type='MAX')
skip_2 = net
net = conv_block(net, 256)
net = conv_block(net, 256)
net = conv_block(net, 256)
net = slim.pool(net, [2, 2], stride=[2, 2], pooling_type='MAX')
skip_3 = net
net = conv_block(net, 512)
net = conv_block(net, 512)
net = conv_block(net, 512)
net = slim.pool(net, [2, 2], stride=[2, 2], pooling_type='MAX')
skip_4 = net
net = conv_block(net, 512)
net = conv_block(net, 512)
net = conv_block(net, 512)
net = slim.pool(net, [2, 2], stride=[2, 2], pooling_type='MAX')
#####################
# Upsampling path #
#####################
net = conv_transpose_block(net, 512)
net = conv_block(net, 512)
net = conv_block(net, 512)
net = conv_block(net, 512)
if has_skip:
net = tf.add(net, skip_4)
net = conv_transpose_block(net, 512)
net = conv_block(net, 512)
net = conv_block(net, 512)
net = conv_block(net, 256)
if has_skip:
net = tf.add(net, skip_3)
net = conv_transpose_block(net, 256)
net = conv_block(net, 256)
net = conv_block(net, 256)
net = conv_block(net, 128)
if has_skip:
net = tf.add(net, skip_2)
net = conv_transpose_block(net, 128)
net = conv_block(net, 128)
net = conv_block(net, 64)
if has_skip:
net = tf.add(net, skip_1)
net = conv_transpose_block(net, 64)
net = conv_block(net, 64)
net = conv_block(net, 64)
分割效果

数据集:SegNet (3.5K dataset training - 140K)
精确度结果:
| 类别 | 精确度 |
|---|---|
| Building | 89.6 |
| Tree | 83.4 |
| Sky | 96.1 |
| Car | 87.7 |
| Sign-Symbol | 52.7 |
| Road | 96.4 |
| Pedestrian | 62.2 |
| Fence | 53.45 |
| Column-Pole | 32.1 |
| Side-walk | 93.3 |
| Bicyclist | 36.5 |
| Class avg. | 71.20 |
| Global avg. | 90.40 |
| mIoU | 60.10 |
| BF | 46.84 |
作者:Freeverc
来源:优快云

Segnet,由VijayBadrinarayanan等人于2015年提出,基于VGG16框架改进而成,采用编码器-解码器结构进行像素级图像分割。其创新之处在于利用下采样时的MaxValue位置信息进行上采样,加入BatchNormlization层提高分割效果,并使用Softmax损失函数。Segnet在MATLAB2016中作为内置算法,虽然之后被更深层的网络如Resnet所超越,但在语义分割领域仍具有一定影响力。
5082





