pytorch语义分割
Pytorch语义分割
最近整合了部分pytorch实现的图象语义分割模型,简单做一下总结,代码在git:pytorch-semantic-segmentation
一、简介
基于深度的图象语义分割任务不同于分类与检测任务,分类任务利用深度模型提取特征后输出特征向量并计算各类概率,简单理解为“一图对应一标记”。检测则在分类任务基础上增加了候选框的生成和回归的任务,模型同时做物体区域定位与区域分类任务,结果可以理解为“一图对应多标记”。而语义分割则属于密集分类任务,分类的对象为每一个像素点,直观理解为"All in, all out"。模型的输入为图象,输出为与原图同样大小的预测图,每一个像素点的值则对应原图相应点的类别。
如下图所示,左边为原图,右边为分割标记图,被划分为3个区域,黑色背景为一个类别,粉色人为一类别,摩托车为一类别,具体在训练的时候可以转化为{'background':0, 'person':1, 'motobicycle':2},也就是将现在看到的rgb图象转化为灰度标记图,灰度图中每一个像素点的值均为该点的类别。
二、模型
主要通过模型介绍来理解语义分割流程。
2.1 FCN
FCN的提出打开了基于深度的语义分割思路。FCN模型前面部分用VGG16提取特征,后面将VGG的全连接改为卷积层,最后直接对卷积输出特征图进行upsampling就得到了分割结果。
模型结构没什么说的,解释一下语义分割训练的过程和loss的计算。
假设我的数据包含21个类别,反映到灰度图上也就对应了0-20个灰度值. 图片进入网络搅拌后输出,最后的输出层请注意 :
nn.Conv2d(Input-Channel, NUM_CLASSES)
输出的通道数为类别个数,即会输出21个通道的特征图,每一个特征图对应于相应类别的概率值。例如第5个特征图,每一个像素值就表示原图对应像素为第5类别的概率值(称为概率不太准确,最后特征图会进行log_softmax处理)。
最后用cross-entropy计算loss,pytorch中给出的公式为:
loss(x,class)= x[class], x为最后输出特征图,class为该像素点标记的类别
一句话说明,对最后loss有贡献的只是像素点标记类别所对应的特征图的值,早死语!咩有画图不好解释。这位小哥解释的蛮好loss解释。
2.2 Encoder-Decoder
之后的分割网络很多都是基于编解码的结构。优美又有效,大体来讲decoder过程将upsampling替换为transpose-conv,
前面采用dilation卷积,以扩大感受野。(大概是可解释性立足于效果,有效就能解释)
三、结语
小白的简单的记录,并不完善完整。有新想法再来分享。
git代码有包括fcn、segnet、unet、erfnet,模型在继续完善,也在修改代码让她尽量简单干净。
不足、有误的地方请提出,欢迎讨论。