您的位置:首页 > Web前端

caffe随记(八)---使用caffe训练FCN的pascalcontext-fcn32s模型(pascal-context数据集)

2017-11-30 13:55 1336 查看


本篇讨论利用caffe进行FCN训练(采用的是pascal-context数据集

1、下载FCN的框架

https://github.com/shelhamer/fcn.berkeleyvision.org

如图是我在windows下的视图



因为不同的数据源和不同的FCN类型的网络结构并不同,对数据源的读取方式也不同,因此有很多分支,本篇博文以pascalcontext-fcn32s为例子讲解fcn的训练过程。

把上面的东西拷进服务器,我是放在 ~/caffe/examples/ 目录下的。文件夹命名为fcn.berkeleyvision.org

进行训练之前要先保证caffe的安装和编译工作已经完成,且make和make pycaffe成功。

2、下载VOC2010数据集

http://host.robots.ox.ac.uk/pascal/VOC/voc2010/#devkit

原始数据集至少要包含以下两个文件:



解压后得到一个文件夹VOCdevkit,放进服务器。

我是放在 ~/caffe/data/pascalvoc/ 目录下的。

输入 
ln –s ~/caffe/data/pascalvoc/VOCdevkit/VOC2010   ~/caffe/examles/fcn.berkeleyvision.org/data/pascal/VOC2010

这是建立软连接,至于为什么到第9步就知道了,至于这个linux命令(ln)就自行百度吧

3、下载pascalcontext数据

http://www.cs.stanford.edu/~roozbeh/pascal-context/

下载如下几个数据:



把这两个压缩包解压后连同那个txt文件一起拷入到服务器中。
放在第一步中那个fcn.berkeleyvision.org文件夹下的data中的pascal-context文件夹中去,以我的路径为例,就应该放入:
~/caffe/examples/ fcn.berkeleyvision.org/data/pascal-context

4、下载预训练model

https://github.com/BVLC/caffe/wiki/Model-Zoo#models-used-by-the-vgg-team-in-ilsvrc-2014



下载完成后更名为vgg16-fcn.caffemodel然后放入fcn.berkeleyvision.org文件夹中去,至于为什么更名我待会儿会提到

5、添加python目录

如果fcn.berkeleyvision.org不在python的搜索目录中,那么就编辑 ~/.bashrc,增加以下一行内容到bashrc中去
export PYTHONPATH="你的路径/fcn.berkeleyvision.org:$PYTHONPATH"

然后logout重新登录后生效


6、更改相关路径

更改pascalcontext-fcn32s文件夹中的train.prototxt和val.prototxt里的路径,把param_str中的context_dir和voc_dir更改为自己的路径

根据我们前面存放文件的路径,这里只需要把../.../data/pascal-context改为../data/pascal-context,把../../data/pascal更改为../data/pascal,就是去掉前面一个../就行

7、创建目录

在fcn.berkeleyvision.org/pascalcontext-fcn32s目录下创建snapshot/train

8、更改层名

由于下载的vgg16layer.caffemodel中也有fc6,fc7和train.txt、val.txt中的fc6、fc7不一致,会导致错误,
所以我们把train.txt、val.txt中的所有fc6、fc7改成fc6x和fc7x,包括里面的blob名,目的是不让这个权重值传过去
如图所示:



这是我截取的训练过程中的日志,若你最后成功进行训练了,就会打印出相关内容
(注意:这一步的设置其实是错误的,这是我第一次尝试的步骤,正确的步骤请看文末我的分割线更新的内容)

9、更正solve.py

也在fcn.berkeleyvision.org目录中有个solve.py,我们需要更改其中一些东西

首先在第一行假如以下内容:

import sys

然后它原来的weights是:

weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'



这里改一下路径,改成:../vgg16-fcn.caffemodel(因为caffemodel我们就放在上一层的文件夹中的,这也是为什么前面让改名的原因,就是为了跟这里一致

然后我们第一步讲到了一个建立软连接的过程,你看一下sovle.py中有一行



这就是为什么建立了一个软连接的原因

10、重新编译

需要把caffe目录下的Makefile.config中的

WITH_PYTHON_LAYER=1

这句打开,然后make clean

再 make all

再 make pycaffe

11、安装python setproctitle包

如果系统缺少setproctitle。执行以下命令安装:

pip install setproctitle

显示以下内容说明安装成功



12、开始训练

在pascalcontest-fcn32s下,输入以下命令开始训练:

python solve.py

然后就会开始搭建layer然后各种信息打印出来开始迭代,



--------------------------------------------------------------------------------------分割线---------------------------------------------------------------------------------------------

这个占的内存有点大:我的情况如下:



占了将近4个多G的内存

而且还很慢,跑了好几个小时才跑到8000次,
而且8000次的时候出现了 Begin seg tests,然后就一直停在那里一度不知道发生了什么,如图



最后等了好久才又有信息显示出来:



从时间上看,光是这里就隔了将近一个小时吧,所以大家一定要有耐心,然后这里显示的准确度确实还不高
而且从开始算起已经跑了5个小时了才跑了将近9000次,离我们solver中规定的300000次还远的不得了……所以等出结果了我再来更新博文吧

-------------------------------------------------------------------8.15分割线------------------------------------------------------------------------

跑了30个小时之后我发现loss依然很大accuracy依然很小,和开始并没有区别我的天啊o( ̄ヘ ̄o#)
现在直接暂停了这个训练开始找原因,找出原因后会及时更新的……

-----------------------------------------------------------------8.15分割线-------------------------------------------------------------------------

大概知道是什么问题了,本来我以为我的方法和其他网上的博客的方法都一样是不会出问题的,现在看来真的都是那个大家都介绍的方法出问题了。不然为什么没有人把结果贴图贴出来呢? o( ̄ヘ ̄o#)
这个问题是这样的,出在第8步预训练的VGG16的weights的传递过程中,咱们之前把VGG16卷积层的weights拷过去了,然后由于FCN是把全连接层都改成了卷积层,所以我们对于FC6和FC7的处理是直接不要它的权重初值。
就如同我上面第8步所写,这里是有问题的。至于什么问题,我目前是认为那两个层没有设置初始权重导致无法收敛,更为细节的原因我还需要再研究一下

正确的步骤如下:
①我们首先应该运行一下这个文件夹(fcn.berkeleyvision.org/pascalcontext-fcn32s/)里的 net.py
直接输入 python net.py
这个的作用就是把train.prototxt 和val.prototxt按照net.py中所描述的细节设置一遍,你可以理解为把网络和各个Layer初始化一遍,运行完这个之后,你再去看那两个prototxt,应该会发现之前被改动的fc6,fc7又改回来了;

②还是把那两个prototxt中的数据来源改一下,这个是可以改动的,就如第6步中所述,改成你自己合适的路径;

③重点来了,更改solve.py

[cpp]
view plain
copy

import sys  
import caffe  
import surgery, score  
  
import numpy as np  
import os  
import sys  
  
try:  
    import setproctitle  
    setproctitle.setproctitle(os.path.basename(os.getcwd()))  
except:  
    pass  
  
###############################                                //这两行是我们需要增加的  
vgg_weights ='../../VGG16/vgg16-fcn.caffemodel'                //路径请根据自己的位置修改就好  
vgg_proto = '../../VGG16/VGG_ILSVRC_16_layers_deploy.prototxt'//路径请根据自己的位置修改  
##############################  
  
# weights = '../vgg16-fcn.caffemodel'  //这个是原来的操作,注释掉  
  
# init  
caffe.set_device(int(sys.argv[1]))  
caffe.set_mode_gpu()  
  
solver = caffe.SGDSolver('solver.prototxt')  
# solver.net.copy_from(weights)        //这个也是原来的操作,注释掉  
vgg_net = caffe.Net(vgg_proto,vgg_weights,caffe.TRAIN)  //这里开始的3行都是我们需要增加的  
surgery.transplant(solver.net,vgg_net)  
del vgg_net  
  
# surgeries  
interp_layers = [k for k in solver.net.params.keys() if 'up' in k]  
surgery.interp(solver.net, interp_layers)  
  
# scoring  
val = np.loadtxt('../data/pascal/VOC2010/ImageSets/Main/val.txt', dtype=str)  
  
for _ in range(50):  
    solver.step(8000)  
    score.seg_tests(solver, False, val, layer='score')  
~  
~  
~  
~  

④我们这里需要用到 vgg16-fcn.caffemodel 和VGG_ILSVRC_16_layers_deploy.prototxt
caffemodel我们之前已经下载了,prototxt这个其实github上可以搜到,很多的,顺手给个链接把:
https://gist.github.com/northeastsquare/ea30d8e12a1e7c91ac82381f2df8c861


然后把这两个文件放到你sovle.py中写的对应位置去即可

至于为什么这么改?
其实它是先把这个权重值放到了VGG16的网络中,就是vgg_net = caffe.Net(vgg_proto,vgg_weights,caffe.TRAIN)这一句话
然后把vgg_net的权值通过一个函数转化到我现在这个solver.net里面去,surgery.transplant(solver.net,vgg_net)
就是这么一个过程,附上transplant函数的源码以供参考





然后就ok了

输入 python solve.py 0
附上一张成功转换权值的过程图




可以看到fc6和fc7的权重也被合理reshape之后coercing过去了

⑥看一下现在的loss下降的速度
开始时:





1个小时后:





才一个小时就下降到十八万了,这回感觉没毛病了,就等过几天跑完来更新博文了。

-----------------------------------------------------------------8.18分割线--------------------------------------------------------------------------




8-18 14:30的seg tests情况,overall accuracy已经达到了66.06%,mean accuracy达到了49.43%左右。
可见的确是精度在提高,但是真的感觉训练速度很慢,我的Tesla K40C现在用了67个小时了,也才只完了112000迭代,而迭代总数设置的是30 0000, 也就是说如果跑完的话,估计需要180多个小时,粗略的估计是7--8天左右,我的神啊……

--------------------------------------------------------------------8.31分割线------------------------------------------------------------------
最近开学太忙忘了更了,现在贴上最终的结果:





可以看到结果稳定在0.664左右,这与之前的作者给出的准确率是差不多一样的,就百分位上有些小小的区别
作者论文结果如图:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: