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

本篇讨论利用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

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左右,这与之前的作者给出的准确率是差不多一样的,就百分位上有些小小的区别

作者论文结果如图:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏全栈之路

关于thinkPHP入门

由于学的语言过多,然后学php语法的时候,感觉挺容易的,于是直接上手thinkPHP,然后就是一脸懵逼,虽然中文文档写得很好(后来才觉得),但是对于刚入手的人并...

1003
来自专栏AI科技大本营的专栏

教程 | 如何在手机上使用TensorFlow

? 翻译 | AI科技大本营 参与 | zzq 审校 | reason_W 我们知道,TensorFlow是一个深度学习框架,它通常用来在服务器上训练需要大量...

5477
来自专栏Y大宽

多序列比对,进化树分析,保守性,密码子偏好性分(1)

打开https://www.ncbi.nlm.nih.gov/protein,输入BopA,search

1542
来自专栏fangyangcoder

tensorflow笔记(三)之 tensorboard的使用

http://www.cnblogs.com/fydeblog/p/7429344.html

975
来自专栏听雨堂

轻松水印-批量提取exif信息加水印的工具

        今天整理了一下自己的照片,选了一部分准备到网上冲印出来,整理好的照片,都没有日期,我很希望能够有日期,以后看到照片立刻就能想起来。但是,如果手工...

2265
来自专栏应用案例

如何用Python提取中文关键词?

本文一步步为你演示,如何用Python从中文文本中提取关键词。如果你需要对长文“观其大略”,不妨尝试一下。 ? 需求 好友最近对自然语言处理感兴趣,因为他打算利...

2398
来自专栏人工智能

第三课:把tensorflow,模型和测试数据导入Android工程

关于Android项目的创建这里就不做赘述了,我们直接进入主题,看下如何把机器学习库和训练的模型导入一个安卓应用中。 导入 Inference Interfac...

2318
来自专栏用户2442861的专栏

caffe python 图片训练识别 实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/details...

1912
来自专栏潇涧技术专栏

Android Ndk and Opencv Development 3

本节包括下面几个方面的内容: 1.如何实现Static Initialization从而不需要安装OpenCV Manager运行含OpenCV librar...

1082
来自专栏人工智能LeadAI

毫秒级检测!你见过带GPU加速的树莓派吗?

41510

扫码关注云+社区