语义分割(零) https://blog.csdn.net/Qer_computerscience/article/details/84778682
来自伯克利的2014CVPR、2015PAMI非常经典的一篇用FCN进行语义分割的文章,后续也都基于此FCN架构进行进一步拓展。
下面对论文中主要思想进行总结
一、文章主要贡献
1.全卷积
常用的分类网络例如VGG、GoogleNet、AlexNet等,都是由features和classifier构成,由全连接层进行分类任务。同时也正是由于全连接的存在,导致网络只能接受固定大小的输入以适应固定数量的全连接神经元,而卷积网本身并没有对图像的size进行限制,不同的input size,卷积核依然有固定大小的感受野来产生corresponding features。作者采用了FCN架构,将传统分类网络的分类连接层转换成全卷积网络。(抛弃分类层,或构成dense conv层),在语义分割任务中,只需要将卷积层的输入,上采样缩小倍数到原始大小,就可以统计每一个pixel的误差进而反向传播。
2.多层信息融合
网络本身由很多个卷积部分构成,例如VGG16包含了5个卷积池化组,而global information解决是什么的问题,local information解决在哪里的问题,在卷积网中体现在深层和浅层信息中。Combining what and where,采用多层融合信息,更有利于最终的semantic segmentation。
3.end-to-end
网络端到端训练,基于FCN构成了end to end结构。
二、算法细节
文章采用了将全连接替换成全卷积层,通过1x1卷积核获得相应的感受野,但可以处理不同的输入尺寸了。
混合层的实现需要通过上采样,以VGG的conv5输入为例,经过卷积与池化,map的size经过了32x的下采样,我们可以通过插值的方式实现上采样,同样也可以通过deconvolution实现,同时卷积参数可以学习,能够达到非线性插值的效果。
在混合多层map的时候,如将32x上采样(deconv)2倍到16x,即可以与conv4的16x特征输出层混合,文中采用直接相加的方式,以此类推混合从深到浅层的信息。
三、简单实现
在这里我写了一个简单的pytorch实现版本,基于vgg16模型,混合了32s,16s,8s特征。
net结构如下所示:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import models
#build vgg16 net
cfg = {
'vgg16' : [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M']}
ranges = {
'vgg16': ((0, 5), (5, 10), (10, 17), (17, 24), (24, 31))}
def make_layers(cfg, batch_norm = False):
layers = []
in_channels = 3
for val in cfg:
if val == 'M':
layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
else:
conv2d = nn.Conv2d(in_channels, val, kernel_size=3, padding=1)
if batch_norm:
layers