FCN网络训练 SIFTFLOW数据集

论文全名:Fully Convolutional Networks for Semantic Segmentation


全卷积神经网络 FCN代码运行详解:

运行平台:

Ubuntu 14.04 + cudnn7

步骤1.代码准备:
下载新版caffe:   https://github.com/BVLC/caffe
下载fcn代码:      https://github.com/shelhamer/fcn.berkeleyvision.org
将下载后的压缩包解压 将解压后的代码丢进服务器

步骤2.编辑caffe和python接口:
cd进入caffe所在路径
以个人路径示例:/home/my/caffe-master/caffe-master 
在该目录下,执行
cp Makefile.config.example Makefile.config
vim Makefile.config(这句代码根据自己情况选择,如果需要修改相关设定,就使用这句,需要注意的是,将WITH_PYTHON_LAYER := 1前面的#去掉
如果使用cudnn,就把use cudann前面的#去掉
我这边安装的是openbla,所以我的设置为BLAS:=open)

make all  -j8  //8代表线程数量,可以加快编译速度

make test  -j8  //编译测试需要的文件
make runtest    //开始运行测试例子,这一句貌似有没有都行
以上结束后开始编译python接口
在下载的caffe源码包中,有个叫python的文件夹,cd进入这个文件夹
以我个人路径为例cd至 /home/wangkun/caffe-master/caffe-master/python
编译python:
make pycaffe
#测试是否成功
cd caffe-folder/python
python
import caffe
#如果上述命令未报错,说明成功
#添加caffe/python 到python path变量
vim ~/.bashrc
#set the caffe PYTHONPATH
export PYTHONPATH=/path/to/caffe/python:$PYTHONPATH

!如果是采用的Anaconda python,切记编译python接口在最后执行。

!如果是系统自带的python在make pycaffe可能出现python/caffe/_caffe.hpp:8:31: fatal error: numpy/arrayobject.h: No such file or directory
这是因为64位的python 库的存放路径问题。

查找arrayobject.h所在的目录:

sudo find / -name arrayobject.h

然后修改Makefile.config

PYTHON_INCLUDE := /usr/include/python2.7 \
                /usr/lib64/python2.7/site-packages/numpy   //这里修改成找到的路径
以上,编译结束,关于编译python,由于我这边服务器上使用的是Anaconda python,大家可以根据自己的实际情况进行python接口的编译

步骤3.数据文件下载
下载siftflow数据集:http://www.cs.unc.edu/~jtighe/Papers/ECCV10/siftflow/SiftFlowDataset.zip
并解压至 /fcn.berkeleyvision.org/data/ 下,并将文件夹名重命名为 sift-flow

步骤4.预训练模型下载:
下载VGG16的预训练模型并放在FCN源码文件夹中的ilsvrc-nets文件夹下
https://pan.baidu.com/s/1qYJeFfQ
以个人路径为例:/home/my/fcn.berkeleyvision.org-master/fcn.berkeleyvision.org-master/ilsvrc-nets

步骤5.为了避免运行程序时候出现no module named caffe
在代码中包含import caffe的py文件(solve.py)的第一行加入
import sys  
sys.path.append('/home/my/caffe-master/caffe-master/python')
其中, /home/my/caffe-master/caffe-master/python为你下载的caffe源码中python文件夹的路径


步骤6.cd进入fcn源码路径
以个人路径为例:/home/my/fcn.berkeleyvision.org-master/fcn.berkeleyvision.org-master
将其中所有的py文件,例如surgery.py等等,全部复制到siftflow-fcn32s文件夹中

步骤7.solver.prototxt文件修改
进入siftflow-fcn32s文件夹 打开solver.prototxt
其中snapshot:10000 表示训练10000次保存一次模型
snapshot_prefix:"/home/my/fcn.berkeleyvision.org-master/fcn.berkeleyvision.org-master/siftflow-fcn32s/train"
表示训练得到的模型,也就是model存放的路径
在此,我附上个人的solver.prototxt供大家参考
train_net: "trainval.prototxt"
test_net: "test.prototxt"
test_iter: 200
# make test net, but don't invoke it from the solver itself
test_interval: 999999999
display: 20
average_loss: 20
lr_policy: "fixed"
# lr for unnormalized softmax
base_lr: 1e-10
# high momentum
momentum: 0.99
# no gradient accumulation
iter_size: 1
max_iter: 300000
weight_decay: 0.0005
snapshot:10000
snapshot_prefix:"/home/my/fcn.berkeleyvision.org-master/fcn.berkeleyvision.org-master/siftflow-fcn32s/train"
test_initialization: false



步骤8.solve.py文件修改

在这里郑重声明一下:如果训练fcn32s的网络模型,

一定要修改solve.py

利用transplant的方式获取vgg16的网络权重;

具体操作为

[html]  view plain  copy
  1. import sys    
  2. sys.path.append('/home/my/caffe-master/caffe-master/python')  
  3. import caffe  
  4. import surgery, score  
  5.   
  6. import numpy as np  
  7. import os  
  8. import sys  
  9.   
  10. try:  
  11.     import setproctitle  
  12.     setproctitle.setproctitle(os.path.basename(os.getcwd()))  
  13. except:  
  14.     pass  
  15.   
  16. vgg_weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'  
  17. vgg_proto = '../ilsvrc-nets/VGG_ILSVRC_16_layers_deploy.prototxt'  
  18. weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'  
  19.   
  20. # init  
  21. caffe.set_mode_gpu()  
  22. # caffe.set_device(int(sys.argv[0]))  
  23. caffe.set_device(7)  
  24.   
  25. #solver = caffe.SGDSolver('solver.prototxt')  
  26. #solver.net.copy_from(weights)  
  27. solver = caffe.SGDSolver('solver.prototxt')  
  28. vgg_net=caffe.Net(vgg_proto,vgg_weights,caffe.TRAIN)  
  29. surgery.transplant(solver.net,vgg_net)  
  30. del vgg_net  
  31.   
  32. # surgeries  
  33. interp_layers = [k for k in solver.net.params.keys() if 'up' in k]  
  34. surgery.interp(solver.net, interp_layers)  
  35.   
  36. # scoring  
  37. test = np.loadtxt('../data/sift-flow/test.txt', dtype=str)  
  38.   
  39. for _ in range(50):  
  40.     solver.step(2000)  
  41.     # N.B. metrics on the semantic labels are off b.c. of missing classes;  
  42.     # score manually from the histogram instead for proper evaluation  
  43.     score.seg_tests(solver, False, test, layer='score_sem'gt='sem')  
  44.     score.seg_tests(solver, False, test, layer='score_geo'gt='geo')  
可以看到我注释了

[html]  view plain  copy
  1. #solver = caffe.SGDSolver('solver.prototxt')  
  2. #solver.net.copy_from(weights)  
[html]  view plain  copy
  1. 添加了  
[html]  view plain  copy
  1. solver = caffe.SGDSolver('solver.prototxt')  
  2. vgg_net=caffe.Net(vgg_proto,vgg_weights,caffe.TRAIN)  
  3. surgery.transplant(solver.net,vgg_net)  
  4. del vgg_net  



并且在import后添加了

[html]  view plain  copy
  1. vgg_weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'  
  2. vgg_proto = '../ilsvrc-nets/VGG_ILSVRC_16_layers_deploy.prototxt'  
  3. weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'  
关于
[html]  view plain  copy
  1. VGG_ILSVRC_16_layers_deploy.prototxt  
我附上我的百度网盘的链接 如果大家找不到 可以在这里下载

http://pan.baidu.com/s/1geLL6Sz

如果训练fcn16s,则可以直接copy自己的fcn32s的model的权重,不需要transplant,也就是不需要修改solve.py

如果训练fcn8s,则可以直接copy自己的fcn16s的model的权重,不需要transplant,也就是不需要修改solve.py

只有如此,才能避免loss高居不下的情况

步骤9.
以上配置全部结束,开始进行模型训练
进入siftflow-fcn32s文件夹
执行 python solve.py


步骤10.测试单张图片
在fcn源码文件夹,找到infer.py
以个人路径示例:/home/my/fcn.berkeleyvision.org-master/fcn.berkeleyvision.org-master
打开infer.py 在第一行加上
import sys  
sys.path.append('/home/my/caffe-master/caffe-master/python')
其中/home/my/caffe-master/caffe-master/python为自己所下载的cafe源码包中的python所在路径
其中,net = caffe.Net('deploy.prototxt', 'siftflow-fcn32s/train_iter_100000.caffemodel', caffe.TEST)
中, train_iter_100000.caffemodel为训练得到的模型

其中,im = Image.open('test.jpg')为 测试的图片名,
plt.savefig('test_out.png')为将测试结果保存为test_output.png
此外 
out = net.blobs['score'].data[0].argmax(axis=0)
改成
out = net.blobs['score_sem'].data[0].argmax(axis=0)
我附上个人完整的infer.py的代码

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import sys  
sys.path.append('/home/my/caffe-master/caffe-master/python')
import caffe
import cv2
%matplotlib inline
# load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
im = Image.open('siftflow-fcn8s/test.jpg')
in_ = np.array(im, dtype=np.float32)
in_ = in_[:,:,::-1]
in_ -= np.array((104.00698793,116.66876762,122.67891434))
in_ = in_.transpose((2,0,1))

# load net
net = caffe.Net('siftflow-fcn8s/deploy.prototxt', 'siftflow-fcn8s-heavy.caffemodel', caffe.TEST)
# shape for input (data blob is N x C x H x W), set data
net.blobs['data'].reshape(1, *in_.shape)
net.blobs['data'].data[...] = in_
# run net and take argmax for prediction
net.forward()
out = net.blobs['score_sem'].data[0].argmax(axis=0)
#print "hello,python!"

#plt.imshow(out,cmap='gray');
plt.imshow(out)
plt.axis('off')
plt.savefig('test.png')



.使用infer.py时候遇到no display name and no $DISPLAY environment variable的话 证明服务器上没安装显卡
不支持plt命令,具体解决方法可以见我的另外一个博客中的问题1,2个解决方法:
http://blog.csdn.net/wangkun1340378/article/details/56834642

如果没有deploy文件,可以参考如下方法:

deploy文件如果没有 可以参照一下方法

首先,根据你利用的模型,例如模型是siftflow32s的,那么你就去siftflow32s的文件夹,

里面有train.prototxt文件,将文件打开,全选,复制,新建一个名为deploy.prototxt文件,粘贴进去,

然后ctrl+F 寻找所有名为loss的layer 只要有loss 无论是loss还是geo_loss 将这个layer统统删除

然后删除输入层,在fcn中就是第一个python层,即删除

layer {
  name: "data"
  type: "Python"
  top: "data"
  top: "sem"
  top: "geo"
  python_param {
    module: "siftflow_layers"
    layer: "SIFTFlowSegDataLayer"
    param_str: "{\'siftflow_dir\': \'../data/sift-flow\', \'seed\': 1337, \'split\': \'trainval\'}"
  }
}


然后在文件顶部加上

layer {
  name: "input"
  type: "Input"
  top: "data"
  input_param {
    # These dimensions are purely for sake of example;
    # see infer.py for how to reshape the net to the given input size.
    shape { dim: 1 dim: 3 dim: 256 dim: 256 }
  }
}

其中shape{dim:1 dim:3 dim:256 dim:256}中的dim可以随意设置,此处虽然为1 3 256 256,但是caffe会根据所读取的图片进行重新设置dim


此外,关于siftflow-fcn需要的deploy文件,我在这里附上一个下载地址,如果不愿意自己制作可以下载这个:

https://pan.baidu.com/s/1nxeLxBr



需要额外注意的是 如果使用siftflow数据集训练得到的model

在测试时候 也请使用siftflow数据集中的img进行test,我以一张voc数据集的img利用siftflow数据集得到的model示例

FCN网络训练 SIFTFLOW数据集_第1张图片FCN网络训练 SIFTFLOW数据集_第2张图片

可以看到voc的图像 在利用siftflow数据集进行测试的结果并不好

在siftflow数据集中 class.txt文件中是包含person这个类别的 但在这个例子中 仍然无法将person完整分割出来

这是因为 train data中 person类别的多样性不足 在大家自己制作自己的数据集时候

不仅要完整包含自己所需要的类别(class) 在保证数据集的数量足够大的同时 更要注意每一个class的 多样性

例如 person的姿势 多样性 等等 只有如此 才能使得分割结果更加完善

fcn只是工具 就像汽车的发动机 

我们使用fcn 时候 我们的数据集就是机油  

机油纯度高(数据集做得好) 汽车跑的就快,跑的远(分割结果就好)

在此,fcn的训练已经结束,祝大家顺利


如果想下载官方的训练好的model 试试结果可以在这里下载到

http://dl.caffe.berkeleyvision.org/

以上,FCN的训练和测试全部结束,这次有个朋友催我做这个,做得比较仓促,如果有问题,欢迎指摘

感谢Zoro_H提供的 利用siftflow训练得到的model 对voc数据集中图片的测试结果
对于deploy文件的错误,感谢qq_37685880等人的指正

你可能感兴趣的:(caffe,深度学习',深度学习,FCN,语义分割)