参考文章: http://blog.csdn.net/u013059662/article/details/52770198

caffe的安装配置,以及fcn的使用在我前边的文章当中都已经提及到了,这边不会再细讲。在下边的内容当中,我们来看看如何使用别人提供的数据集来训练自己的模型!在这篇文章之后,我计划还要再写如何fine-tune和制作自己的数据集,以及用自己的数据集fine-tune。

(一)数据准备(以SIFT-Flow 数据集为例)

下载数据集:  http://pan.baidu.com/s/1dFxaAtj   ,并解压至/fcn.berkeleyvision.org/data/下,并将文件夹名重命名为sift-flow。这里一定要注意,/fcn.berkeleyvision.org/data/下本来就有一个文件夹叫sift-flow,千万不要覆盖。同时,这些原本就存在的文件夹里的东西还要全部复制到新解压的sift-flow文件夹下边。你可以先把原本的sift-slow重新命名为sitf-flow_1,然后再解压复制!

(二) 下载预训练模型

下载VGG-16的预训练模型放至/fcn.berkeleyvision.org/ilsvrc-nets/目录下,并重命名为vgg16-fcn.caffemodel

下载地址: http://pan.baidu.com/s/1gfeF4wN

(三)源码修改

1. prototxt文件修改

进入siftflow-fcn32s文件夹下,将test.prototxttrainval.prototxt中的fc6fc7分别替换为其他名称,例如:fc6_newfc7_new

原因是我们下载的预训练模型VGG-16原模型中包含有fc6和fc7这两个全连接层,而在prototxt中,使我们新添加的卷积层,在模型加载时,如果名称一样,而结构数据不同,便会报错。如果改名之后,原来的fc6/7则会被忽略,而使用我们新的层。

2. caffe path的加入

由于FCN代码和caffe代码是独立的文件夹,因此,须将caffe的Python接口加入到path中去。这里有两种方案,一种是在所有代码中出现import caffe 之前,加入:

1 import sys
2 sys.path.append('caffe根目录/python')

另一种一劳永逸的方法是:在终端或者bashrc中将接口加入到PYTHONPATH中:

export PYTHONPATH=caffe根目录/python:$PYTHONPATH

(四)训练

1 $ cd cd siftflow-fcn32s/
2 $ python solve.py

这里会遇见几个问题:

(1)No module named surgery,score

原因是下载的fcn源码解压根目录下有两个文件:surgery.py和score.py。这两个文件是下载下来就自带的,并不是caffe自带的,也不是前边我安装caffe时需要配置的。由于我是在/fcn根目录/siftflow-fcn32s/这个文件夹下执行的,会导致找不到这两个文件。所以,解决方案就是:

 cp surgery.py score.py ./siftflow-fcn32s/

将surgery.py和score.py拷贝到siftflow-fcn32s下。

(2)ImportError: No module named setproctitle

解决方案是:安装setproctitle! sudo pip install setproctitle

(3)IndexError: list index out of range

解决方案:修改GPU编号为0号GPU

(4)No modulw named siftflow_layers

解决方案:疯了,干错把根目录下边的所有.py文件全拷贝到siftflow-fcn32s里边去吧。

好了,现在可以开始训练了!看看训练过程:

由于损失loss很大,我也不知道什么时候能收敛,所以先放一放,等跑出结果来我再过来更新!

-------------------------------------------------------------2017.1.12更新----------------------------------------------------------------------

经过半个月的折腾和讨论,现在可以确定原先的参考文章是有问题的,这个网络没有办法收敛。下面更正几条:

1. 一般情况下不要直接修改test.prototxt和trainval.prototxt,而是执行net.py这个脚本,执行完成后也不要test.prototxttrainval.prototxt中的fc6fc7替换为其他名称.

2. 这是重点,没有收敛的根源在这里!修改solve.py:

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

可以对比一下之前的solve.py,发现区别在这:

红色框出来的是原先的内容,被我注释掉了,换成了下面四行!为什么要这样做呢?我们来看看这个transplant函数的定义吧:

所以,原先的方法仅仅是从vgg-16模型中拷贝参数,但是并没有改造原先的网络,这才是不收敛的根源啊!

3.修改solver.prototxt:

 1 train_net: "trainval.prototxt"
 2 test_net: "test.prototxt"
 3 test_iter: 200
 4 # make test net, but don't invoke it from the solver itself
 5 test_interval: 999999999
 6 display: 20
 7 average_loss: 20
 8 lr_policy: "fixed"
 9 # lr for unnormalized softmax
10 base_lr: 1e-10
11 # high momentum
12 momentum: 0.99
13 # no gradient accumulation
14 iter_size: 1
15 max_iter: 300000
16 weight_decay: 0.0005
17 snapshot:4000
18 snapshot_prefix:"snapshot/train"
19 test_initialization: false

这里我们增加了 snapshot:4000 snapshot_prefix:"snapshot/train" ,每4000次我们会在当前目录下的snapshot下保存一下模型(需要提前建立snapshot目录)。
4. 有的人可能会出现out of memory错误。这里有两种判断:(1)根本没法迭代,那么你就要把batchsize设置小一点了。默认是 iter_size: 1 (solver.prototxt),另外在siftflow_layers.py中 top[0].reshape(1, *self.data.shape) 这里默认也是1,batchsize = iter_size* 1。如果已经是最小了,即这两个地方都是1了,如果你还是out of memory,那么要么更换好的硬件(GPU),要么resize 数据集到更小的尺寸。(2)如果先提示“Begin seg tests”,然后out of memory,那么是在执行score.py时内存溢出了,这时还是上面的两种解决方案。

好了,上面是我这段时间研究后的补充,感谢小伙伴@踏雪霏鸿 ,最初是他发现了这里的错误,最终帮助大家解决了问题。下面我们就可以重新开始训练模型了!

1 python solve.py

这一次收敛速度会非常快,而且loss会降到很可观的数字。

这里我没有一直跑下去,因为我准备用voc数据集,所以跑了一会就去跑voc数据集了。但是,这次是有小伙伴做过测试的,效果可以,所以基本上siftflow32s的训练步骤就是这些了!需要训练siftflow-fcn32s的朋友可以按这个走,然后用训练得到的32s的模型去训练16s的模型,最后用16s的模型去训练8s的。

5. 最后,由于从32s->16s和16s->8s不需要重新构造卷积层,所以上面第二点提到的注释和替换的那部分就不需要了,直接用solver.net.copy_from(weights)就可以了!

其二,deploy.prototxt的第一层(input层),维度要和输入图片大小对应,如下图:

因为siftflow数据集是256*256的,要一一对应。如果发现要训练的模型下没有deploy.prototxt这个文件,可以从test.prototxt或者trainval.prototxt复制,然后删除最后一层loss层:

再添加一层输入层,这个输入层可以从voc-fcn8s这个文件夹里的deploy.protottx里边复制,内容如下(注意根据输入图片的尺寸修改):

其三,很多人要用自己的数据集训练fcn,那怎么做呢?

是这样的,我们可以先用fcn32s的模型(已经训练好的)和自己的数据集再训练一遍得到新的fcn32s,这其实有专业术语——fine-tune.

然后用上面训练好的fcn32s和自己的数据集,训练出fcn16s。最后,再用上一步的fcn16s和自己的数据集训练出fcn8s。

-------------------------------------------------------结束语--------------------------------------------------------------------------

虽然这样一篇博客看上去好像也没有多少东西,但是却凝结了我和很多人长时间努力的汗水,昼夜奋战搞出来的。我相信,在看过我这篇文章之前,应该是没有多少中文资料的,要么只言片语,要么误导性的。后面也许会有一些博客陆续出来,那基本上也是的小伙伴们写的,但是基本上比较简单,言简意赅,不会像我这么细致写出来。

为什么要做这样一件工作呢?辛苦搞出来的东西,就这样送人了,而且还要再花时间写这么长的博文,打这么多的字。我希望后来人能少走一些弯路,不像我这么痛苦;同时,我希望看过我博客的人也能秉承奉献的精神,把自己的工作公开出来,避免别人少走弯路,这既是对自己工作的总结和梳理,也是对后来人的极大帮助!搞学术不能闭门造车,希望我等共勉!

FCN网络的训练——以SIFT-Flow 数据集为例相关推荐

  1. FCN网络的训练——以SIFT-Flow 数据集为例(转)

    FCN网络的训练--以SIFT-Flow 数据集为例 参考文章: http://blog.csdn.net/u013059662/article/details/52770198 caffe的安装配置 ...

  2. FCN网络的训练——以燃气表数字识别为例

    原文http://blog.csdn.net/hduxiejun/article/details/54234766 FCN网络的训练--以燃气表数字识别为例 目录 用 [TOC]来生成目录: FCN网 ...

  3. caffe FCN网络的训练——以SIFT-Flow 数据集为例

    原文:http://www.cnblogs.com/xuanxufeng/p/6243342.html 我在练习中根据操作稍微修改了一些内容, caffe fcn学习资料收集: 可以参考这个训练: h ...

  4. 贝叶斯网络python实战(以泰坦尼克号数据集为例,pgmpy库)

    文章目录 贝叶斯网络简介 贝叶斯推断思路 贝叶斯网络 贝叶斯网络的实现 应用步骤 泰坦尼克数据集背景介绍 模型结构搭建 模型参数构建 贝叶斯估计器 推理 自动设计网络结构->使用结构学习方法 模 ...

  5. Win10下搭建旷视YOLOX(新一代anchor-free目标检测网络)并训练自定义CoCo格式数据集

    注意:原始的YOLOX只支持乌班图系统,因此以下所有操作均需要依赖博主自己的安装包.链接:https://pan.baidu.com/s/1CoQa8WjJ89gNfexK59Ewrw 提取码:qhi ...

  6. FCN网络训练训练——从零开始

    FCN网络训练训练--从零开始 一 数据集准备 在/fcn.berkeleyvision.org/data/下新建文件夹 sbdd trianval: http://www.eecs.berkeley ...

  7. 不一样的显卡,在Pytorch中跑相同的网络,配置文件、参数、数据集完全相同,为什么训练结果相差特别多?

    gtx1070和gtx660,两个显卡,分别在caffe中跑相同的网络,配置文件.参数.数据集完全相同,为什么训练结果相差特别多,1070的训练损失特大,准确率与瞎猜差不多,反而是660的老显卡准确率 ...

  8. 【21】FCN网络训练及理解

    准备工作 代码地址:https://github.com/bat67/pytorch-FCN-easiest-demo 论文参考:全卷积网络 FCN 详解 FCN详解与pytorch简单实现(附详细代 ...

  9. ResNet网络的训练和预测

    ResNet网络的训练和预测 简介 Introduction 图像分类与CNN 图像分类 是指将图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法,是计算机视觉中其他任务,比如目标检测 ...

最新文章

  1. php成绩管理前段模板,php学生成绩管理系统(模板).doc
  2. 【集训队作业2018】喂鸽子
  3. java定时线程池_java 定时器线程池(ScheduledThreadPoolExecutor)的实现
  4. ACM001 Quicksum
  5. MapReduce编程中常用的字符操作
  6. 关于运行jar包时的一个错误
  7. java autorun_〔批处理〕右键添加命令,让Autorun.inf见鬼去吧
  8. 程序员很少加班?得全栈开发者得天下?撕开标签的技术圈真实模样
  9. java jasper 生成xlsx_JasperReports导出到xlsx,而不是xls
  10. git 客户端_GEE 学习笔记 3: 客户端连接远程服务器的 Jupyter ( git 作为本地工具)
  11. Atitit.论图片类型 垃圾文件的识别与清理  流程与设计原则 与api概要设计 v2 pbj
  12. 梯度累加是什么意思-详解
  13. 加壳软件测试,VMProtect2.04加壳程序从入门到精通
  14. matlab入门教程五 ----- 绘制空间图形
  15. 雪峰磁针石博客]渗透测试简介2入侵工具
  16. 大话数据结构笔记-图
  17. Linux内核配置(16)
  18. 从新手到老鸟的脱变过程之《如何做手游项目》
  19. 翻译工作必备,英文标点符号使用规则
  20. STC89C52烧录不了

热门文章

  1. boost::safe_numerics模块测试 constexpr 转换
  2. boost::intrusive::splaytree_algorithms用法的测试程序
  3. boost::coroutine2模块实现协程的测试程序
  4. GDCM:gdcm::PrivateTag的测试程序
  5. boost的chrono模块线程时钟的测试程序
  6. boost::callable_traits添加volatile成员的测试程序
  7. Boost:简单的双图bimap的测试程序
  8. ITK:创建前向差异内核
  9. VTK:PolyData之ResampleAppendedPolyData
  10. VTK:模型之ExtractLargestIsosurface