前言
最近实习完回学校,继续开始我的图像语义分割研究了,为毕业论文做准备,首先还是看了一下最近的一些最新的分割论文,在ICNet论文中找到一个很好的图表,显示各个方法在CItyscapes数据集的测试集上的时间和精度指标情况:
由上图可以看到精度上很高的方法有Resnet38,PSPNet,DUC三种方法,速度上较快的只有ICNet(考虑到精度因素);除了上图中的方法之外,2018年最新的模型中deeplab v3+在这个测试集上精度达到了最好的82.1(时间没有考虑),所以本次主要实验的baseline使用PSPNet,下面就开始漫漫征程的第一步——跑通PSPNet
# 配置环境
## 准备工作
深度学习的第一步当然是配置环境了,好的环境简直就是成功的一半了。不过这里就不详细介绍了,得益于出去实习的四个月我之前配置好环境的服务器还是完好的保存着没有人用,所以可以有一套完好的caffe训练环境,需要配置的童鞋可以参考我之前的:Unbuntu配置Caffe以及调试DeepLab记录
我自己配置的环境是Ubuntu 16.04+NVIDIA-Linux-x86_64-384.98驱动
+CUDA8.0+Anaconda2+cuDNN5.0.5+OpenCV2.4.13.4+caffe
在此环境下首先还需要下载的就是:
1. PSPNet论文
2. PSPNet caffe源码
3. MATLAB 2015b(链接:https://pan.baidu.com/s/10q16mB_62EZL_aVCdo545w 密码:1ggm),这里需要稍微注释一下,我本来下的2016b,但是看到caffe的官网上:
所以我还是猥琐的换回2015a算了,也是因为之前实习的时候配置用的2016b结果没有弄好(好尴尬,写这篇博客的时候才发现自己还是看错了,人家支持的是2015a,我下的是2015b,哎,这粗心的毛病啥时候能改的好啊。。。),不过最终还是配置成功了,不放心的童鞋还是可以自己去下2015a。为什么需要下MATLAB是因为作者的评价代码是用的MATLAB,为了和作者保持一致,还是配置一下matcaffe吧
## 开始配置
1、首先我们来安装MATLAB2015b,我主要参考的是
https://blog.csdn.net/hejunqing14/article/details/50265049
2、安装好了之后就是非常艰难的源码编译过程了,主要可以参考:
https://blog.csdn.net/WZZ18191171661/article/details/70149070 ,首先还是修
改Makefile.config,我是直接把之前编译成功的caffe的Makefile.config复制到PSPNet源码里面进行编译的,刚开始问题就来了:
1 | In file included from ./include/caffe/util/device_alternate.hpp:40:0, |
这个问题是我之前编译成功的caffe的cuDNN版本和PSPNet的版本不一致导致的,参考
https://blog.csdn.net/u011070171/article/details/52292680 中的方法顺利解决
3、在make runtest的时候我出现了下面的错误
网上一般的解答都是网络中feature map大小不一致造成的,可是我又不是在训练自己的网络的时候遇到的,我也很无奈,所以就放着了,毕竟这个也并没有影响到后面的测试以及训练,不过有大牛知道还是希望告知一下的。
4、然后就是编译MATLAB的caffe接口了,make matcaffe还好没有报错,但是make mattest的时候:
主要参考:http://www.cnblogs.com/laiqun/p/6031925.html 以及 caffe官网,但是我用
1 | ldd ./matlab/+caffe/private/caffe_.mexa64 |
查询C++的动态链接库的时候,发现了两个没有链接到的运行时库,尝试了各种方法将运行时库链接上了,可是还是编译不成功,最后我把终端重启了一次之后就好了,我也很迷。。。
至此基本上就完成了所有的编译过程,可以进行到下面的步骤了。
# PSPNet运行
## 数据集准备
PSPNet论文中用到的数据集为:
- ADE20K
- Cityscapes
- PASCAL VOC2012以及PASCAL VOC2012增强数据集
## 数据集处理
作者在使用这些数据之前都进行了一系列的预处理,下面就来介绍一下:
1、ADE20K
下载完成后解压数据集可以发现它分为training和validation两个部分,每个部分都由很多子文件夹组成,具体的图片以及标签为:
官方对于以上的图片解释如下:
作者对于以上的数据集主要使用的了原始图像以及分割的标记图像(上图中的ADE_val_00000001.jpg和ADE_val_00000001_seg.png),同时作者对分割的标记图像进行了预处理,转化为代表类别的灰度图像,转化工具是ADE20K官方提供的MATLAB转换代码,对于代码的介绍可以参考官网:
将demo.m进行修改后可以进行转换(我自己也没有写出来,有大牛写出来了希望@我一下,万分感谢),官网代码的github上也有对应的issues:https://github.com/hszhao/PSPNet/issues/76
2、Cityscapes
作者使用的是下面这四个部分:
对于这个数据集的介绍可以参考:https://blog.csdn.net/Cxiazaiyu/article/details/81866173
上面的数据集同样要进行预处理,首先按照上面博文的介绍运行cityscapesscripts/helpers/labels.py脚本可以看到下面的各个类别的情况:
而论文中使用的类别情况也和这个默认的trainId是一致的,所以我们直接使用cityscapesscripts/preparation/createTrainIdLabelImgs.py脚本来对数据集进行转换即可,只需要将文件夹放成如下结构:
然后修改脚本中:
1 | def main(): |
部分的路径即可将原始的标签图片转换到上表所示的类别情况中
3、PSCAL VOC2012
该数据集的处理主要参考:https://blog.csdn.net/Xmo_jiao/article/details/77897109
运行及测试
在PSPNet官方代码中evaluation文件夹下的.m文件以及evaluationCode文件夹下的文件即为整个测试的所有脚本,其中最主要需要注意的分别为,可以参考:PSPNet测试代码解读:
- eval_all.m:测试的主函数
- eval_sub.m:运行caffemodel产生预测图片
- eval_acc.m:将预测的图片和标签图片进行对比生成测试指标
根据自己的实际情况修改脚本中的路径并按照代码将各个测试的图片放入相应的位置就可以进行测试了
主要修改的脚本为eval_all.m:
1 | # 修改路径部(这里以ADE20K为例) |
测试图片文件夹结构为:
测试情况如下:
1、PASCAL VOC2012:
2、Cityscapes
3、ADE20K
由于上面的转换代码没有写出来,所以测试的结果很低(不能讲预测的类别标签和真实的标签进行匹配)
PSPNet训练
本次训练首先使用PASCAL VOC数据集进行训练,该数据集对应的label标签以及数据上面的:https://blog.csdn.net/Xmo_jiao/article/details/77897109 都有对应的下载链接,所以主要涉及到的是配置文档:
配置文档
solver.prototxt
参考论文中的数据:
可有得到下面的配置文件:
1 | train_net: "prototxt/VOC2012_train.prototxt" |
train.prototxt
该训练网络要考虑下面这些问题:
主要参考的是:
https://github.com/SoonminHwang/caffe-segmentation/tree/master/pspnet/models
里面分享的网络
run.sh
1 | #!/bin/sh |
数据增强
按照上面论文中的截图可以看到作者使用了以下数据增强:
- 随机镜像
- 随机在[0.5, 2]之间进行resize
- 随机在[-10, 10]之间随机旋转
- 随机高斯模糊
下面是进行数据增强的脚本:
其中主要是旋转部分考虑到旋转后的图像会产生黑边,而label图像每一个像素点都是类别特征,所以黑边可能会影响到训练,因此参考:
https://blog.csdn.net/YhL_Leo/article/details/51510432 这篇博文求每次旋转后图片的内接最大矩形,然后将博文中的C++代码用python改写成下面旋转处理部分
1 | """ |
对应的标签处理脚本如下:
1 | import os |
进行数据增强后的图片文件夹结构为:
按照上面的配置可以进行训练:
这是我用原始模型进行finetune一天之后的情况,很明显没有收敛,其中第一个精度是整个网络的精度,后面的两个loss分别是总体的和拉出一个分支的loss,下面的精度分别对应21类的精度,由于每一轮的batchsize为1,所以每一次只有1-2个类的精度会显示出来,明显很低,而且用中间保存的caffemodel进行测试结果也很不好,如果有哪位大神完美复现了,可以一起交流学习一下,后续自己也会继续探索,感恩!!!