【实验记录】FCN(Caffe)

写在前面,由于 FCN 是基于 Caffe 的,所以准备工作是先配置好 Caffe ~

配置 Caffe 参考Ubuntu 16.04下Caffe的配置过程
这是 Caffe 的主程序,里面包含了各种网络层以及函数的实现。下载好之后,编译运行,跑通 mnist,证明你已经装好caffe。

下面主要介绍的是:

  1. 用训练好的 model 进行测试,看看 FCN 的效果;
  2. 重新训练 model 后进行测试,与论文中的实验指标进行比较;

这里是官方已经训练好的 model,可以直接进行测试看看效果:http://dl.caffe.berkeleyvision.org/


FCN 项目文件说明

下载 FCN:fcn.berkeleyvision.org,并将 fcn-master 放在 caffe 的主目录下。
在这里插入图片描述
fcn-master 整个项目文件如下:
在这里插入图片描述
FCN 包括以下几种模型:

  • PASCAL VOC models
  • NYUDv2 models
  • SIFT Flow models
  • PASCAL-Context models

1. 用训练好的模型进行语义分割

下载 voc-fcn32s、voc-fcn16s、voc-fcn8s 的 caffemodel(在对应文件夹下的 caffemodel-url 里下载)

添加python接口

由于 fcn-master 和 caffe 是两个独立的文件夹,所以要将 caffe 的 python 接口添加到 path 中。

第一种方法:在所有代码中出现import caffe 之前,加入

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

第二种方法:在 bashrc 中将接口加入到 PYTHONPATH

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

在这里插入图片描述
明显第二种方法更简单哈。

修改测试文件

根据自己的实际情况修改 infer.py,这里就不改了,因为 demo 里就包含了测试图片,可以直接运行。
在这里插入图片描述

  • im = Image.open('demo/image.jpg') 是将要测试的图片的路径及名称
  • net = caffe.Net('voc-fcn8s/deploy.prototxt', 'voc-fcn8s/fcn8s-heavy-pascal.caffemodel', caffe.TEST) 是 voc-fcn8s 文件夹下的部署文件和训练好的模型
  • out_im.save('demo/output.png') 将分割结果 output.png 保存在 demo 文件夹中
  • masked_im.save('demo/visualization.jpg') 将可视化结果 visualization.jpg 保存在 demo 文件夹中

执行测试

cd fcn-master/
python infer.py

********************** 第一次报错 ***********************在这里插入图片描述
参考: https://blog.csdn.net/weixin_41803041/article/details/79495617

解决: 原来是重新 make all 之后忘记 make pycaffe,太傻了。

********************** 第二次报错 ***********************

但是在 make pycaffe 时,又报了一个新的错误:
在这里插入图片描述
参考: http://blog.sina.com.cn/s/blog_1852c2ba601030woa.html

解决: 在环境变量里添加 anaconda python2.7 的路径

vi ~/.bashrc
export PYTHONPATH="$PYTHONPATH:/data/zyy/usr/local/anaconda/envs/caffe27/include/python2.7"
source ~/.bashrc

注意: 添加环境变量时,第二个要加上 $PYTHONPATH,否则会覆盖前一个 PYTHONPATH。
在这里插入图片描述
添加完环境变量可以来看看是否成功了:

echo $PYTHONPATH

输出如下:
在这里插入图片描述
这里修改好以后,再次执行测试命令就成功了~

测试结果

通过运行 python infer.py,测试结果输出如下:output 和 visualization
output 和 visualization
下面是 demo 里本来就有的原图和标签:
在这里插入图片描述
说明: 这里测试使用的网络是 voc-fcn8s,如果想要使用其他网络进行测试,只需要在 infer.py 里的 net 处进行修改即可。


2. 训练模型(一)

选择一个想要测试的模型,比如这里用 voc-fcn8s,打开文件夹:
在这里插入图片描述

  • caffemodel-url:是该网络预训练好的模型参数,打开这个文件可以看到一个下载地址,复制到浏览器就可以下载对应的模型
  • deploy.prototxt:是训练好模型以后,进行预测的网络模型
  • net.py 是生成网络模型的文件,暂时用不到
  • solve.pysolver.prototxt 是训练网络的一些数据路径和参数设置
  • train.prototxtval.prototxt 就是训练模型和验证模型

数据集下载

benchmark 数据集:

将 benchmark 解压到 fcn-master/data/sbdd 目录下,如果没有 sbdd 文件夹就自己新建一个。

voc2012 数据集:https://pjreddie.com/projects/pascal-voc-dataset-mirror/

将 voc2012 解压到 fcn-master/data/pascal 目录下。

说明: 在 FCN 中 VOC 数据集的训练需要 benchmark 和 voc,benchmark 中的 dataset 用来存放训练时的数据,voc2012 存放测试时的数据。

配置相关文件

修改 voc-fcn8s 文件夹下的配置文件:
在这里插入图片描述

1. 修改配置文件 solve.py

在这里插入图片描述
根据自己的实际路径做出如下修改:
(1)序号 1 处加载 python 与 caffe 的接口路径,填写 caffe 工程目录下的 python 文件夹所在目录。
(2)序号 2 处是下载的训练前的网络模型,我的就直接放在了 fcn8s 的文件夹下。
(3)序号 3 处是模型对应的 solver.prototxt 的路径。
(4)序号 4 处是训练数据 data 里的 segvalid11.txt 文件

另外,如果不想用已有的 model 进行 fine-tuning,注释掉 solver.net.copy_from(weights)

2. 修改配置文件 solver.prototxt

solver.prototxt 是 caffe 的配置文件,里面定义了网络训练时候的各种参数,比如学习率、权重衰减、迭代次数等等。
在这里插入图片描述
根据自己的实际路径做出如下修改:
(1)序号 1 和 2 分别是训练和验证所用到的 prototxt 文件的路径
(2)序号 3 是训练时保存的模型地址

我修改后的文件如下:
在这里插入图片描述
prototxt 中各参数的具体含义参考:caffe中网络结构参数详解

3. 修改配置文件 train.prototxt

将画线部分修改为训练集 dataset 的路径,就是刚才下载的 benchmark
在这里插入图片描述
param_str 有 4 个参数:sbdd_dirseedsplitmean

  • sbdd_dir:数据集的存放路径

4. 修改配置文件 val.prototxt

将画线部分修改为 voc2012 的路径
在这里插入图片描述

开始训练

修改好了各配置文件以后,进入到 caffe 根目录下,运行

sudo python fcn-master/voc-fcn8s/solve.py

即可开始训练。

测试

训练完的模型要进行测试,测试代码在 fcn-master/infer.py


3. 训练模型(二)

训练数据集: SIFT-Flow
预训练模型: VGG-16

准备数据

下载 SIFT-Flow 数据集:SiftFlowDataset.zip

将 zip 解压到 ~/fcn-master/data/ 目录下,由于该目录下已经有了一个文件叫 sift-flow,可以直接把下载的 SiftFlowDataset 中的四个文件放在 sift-flow 里。

这里是下载的四个文件:
SiftFlowDataset
放进 sift-flow 文件夹中:
sift-flow

下载预训练模型

下载 VGG-16 预训练模型:https://pan.baidu.com/s/1qYJeFfQ

将模型放在 fcn-master 工程目录中的 ilsvrc-nets 文件夹下

修改配置文件

将 fcn-master 工程根目录下的相关 .py 文件复制到 siftflow-fcn32s 文件夹中,包括:infer.pyscore.pysiftflow_layer.pysurgery.pyvis.py
在这里插入图片描述
(1)修改 solver.prototxt 文件:
在这里插入图片描述

  • snapshot:10000 表示训练 10000 次就保存一次模型;
  • snapshot_prefix:XXX 为训练得到的模型的存放路径;
  • display 表示每 200 次迭代就打印一下当前的结果;
  • max_iter 表示最大迭代次数,这里是 300,000 次;

(2)修改 solve.py 文件:

由于这里训练的是 fcn32s 的网络模型,必须修改 solve.py 文件,利用 transplant 的方式获取 vgg-16 的网络权重。

如果仅仅是 copy vgg-16 模型参数,并没有改变网络,训练会无法收敛。

solve.py 文件需要修改以下三个地方:
在这里插入图片描述
修改后如下:
在这里插入图片描述
其中 VGG_ILSVRC_16_layers_deploy.prototxt 可能没有,需要另外下载(可以自己搜,或者私信我发给你)。

开始训练模型

cd siftflow-fcn32s
# 注意,如果想要绘制loss曲线,先别急着用这句指令训练,后面会介绍怎么生成log文件
python solve.py

将 siftflow-fcn32s 训练好以后,就可以 copy 训练好的 fcn32s 的模型权重用来训练 siftflow-fcn16s:solver.net.copy_from(weights),也就是不再需要修改 solve.py。

同理,直接 copy 训练好的 fcn16s 的模型权重来训练 siftflow-fcn8s,不需要修改 solve.py。

第一波训练4、5个小时就 ok 了~
在这里插入图片描述

绘制训练过程中的 loss 曲线

修改训练命令为:

python solve.py 2>&1 | tee out.log
  • 2>&1 是 Linux 的信息流输出控制语句,可以将输出信息保存在 out.log 文件中,同时不再在命令窗口中实时显示训练信息;
  • tee out.log 将在窗口中显示训练信息,如果不需要显示,可以不用加 | tee out.log

用 Caffe 自带的脚本绘制 loss 曲线:

~/caffe/tools/extra 目录下的 plot_training_log.py.exampleextract_seconds.pyparse_log.shparse_log.py 复制到保存 log 文件的目录下,再将 plot_training_log.py.example 复制一份并命名为 plot_training_log.py

cp plot_training_log.py.example plot_training_log.py 

注意:这些脚本用的是 python2.7,如果用 python3 环境执行会报错

执行绘制曲线命令:

python plot_training_log.py 6 loss.png out.log

第一个参数 6 是指要绘制哪个指标的曲线图,第二个参数 loss.png 是输出曲线图的保存路径,第三个参数 out.log 是日志文件的路径。

第一个参数具体代表什么可以通过执行 python plot_training_log.py print_help 来查看,这里也告诉我们如何传入参数。
在这里插入图片描述
!!但是执行上面的命令时报了这个错:
在这里插入图片描述
参考:https://blog.csdn.net/u014520797/article/details/80382792
解决:权限不够,给复制过来的三个文件都添加权限

chmod 777 parse_log.sh
chmod 777 parse_log.py
chmod 777 extract_seconds.py
chmod 777 plot_training_log.py

!!再次执行,又报新的错误:
在这里插入图片描述
由于在网上根本没找到能够解决的方案,所以我直接看了 extract_seconds.pyparse_log.sh 源代码。

报错信息显示 assert start_datetime, 'Start time not found',那 start_datetime 肯定是为 False 或 None 了,说明在 for 循环内所有的 if 判断语句都不成立,即 line.find('Solving') 全都是 -1,说明在 line 里压根没找到 Solving,而 lines 又是针对日志文件 out.log 的,那就应该去 out.log 里看看这个 Solving 是什么?我觉得问题就在这里了。

回到训练产生的日志 out.log 里,发现并没有 Solving 这个词,可能是我的日志文件有问题?碰巧看到这篇博客:绘制loss曲线,里面也提到了同样的问题,于是按照他的方法,在第一次迭代开始之前人为加上了 I0507 10:55:51.039144 17590 solver.cpp:239] Solving FCN问题解决~
在这里插入图片描述
因为这样在 extract_seconds.py 中执行下面这个 if 判断时,就不会出现找不到 Solving 的情况而将 start_datetime 置为 None 啦~
在这里插入图片描述
在这里插入图片描述
assert 会判断 start_datetime 是否为 False,根据这两个函数的调用关系可知,只要解决了 Solving 缺失的问题,后面也就不会有问题了。

而且在 parse_log.sh 里,也有用到 Solving,如果不手动添加那句话的话,生成的 aux3.txt 就为空。而 aux4.txt 又是 aux3.txt 生成的,所以一个 Solving 可以同时解决这三个错误。 Linux指令:grep
在这里插入图片描述
最后就是 out.log 文件本身的问题,因为它把训练过程中的所有信息都保存下来了,所以会有一些训练信息之外的提示信息,这些信息会影响到提取 out.log.train 文件,比如下面在迭代第 8000 次的时候进行了验证,所以在 8000 次开始,提取的信息就少了一列,导致 learning rate 那一列跑到了 loss 列下,所以做出的 loss 曲线图后面全为 0 了。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另外看看这个 out.log.test,内容是空的,肯定也是不对的。
在这里插入图片描述
【所以要怎样直接从 out.log 解析出 out.log.trainout.log.test??还没有研究要怎么搞】

out.log 重命名为 out_org.log(表示最初的log文件),复制一份命名为 out.log,将开始迭代后的无关信息删掉,这样就成功了。

# 迭代次数-训练loss
python plot_training_log.py 6 loss_vs_iters.png out.log

在这里插入图片描述

# 时间-训练loss
python plot_training_log.py 7 loss_vs_seconds.png out.log

在这里插入图片描述

顺便把看代码过程中不了解的东西记录以下,都很简单~
Python中 sys.argv[] 的用法简明解释
os._exit() 和 sys.exit()
断言 ( assert ) 的用法
Python find()方法
Python split()方法
Python rfind()方法
datetime是Python处理日期和时间的标准库
Python File readlines() 方法
if __name__ == ‘__main__’ 如何正确理解
Linux grep命令

测试

修改 fcn-master 根目录下的 infer.py

net = caffe.Net('deploy.prototxt', 'siftflow-fcn32s/train_iter_100000.caffemodel', caffe.TEST)
  • train_iter_100000.caffemodel 就是训练得到的模型

附:caffe 参数介绍

iteration 数据进行一次前向 + 后向的训练
batchsize 每次迭代时训练图像的数量
epoch 所有的训练图像都通过网络训练一次是一个epoch

举例:
训练集中共 1280000 张图像,若设置 batchsize = 256,那么就需要 1280000 / 256 = 5000 个 iteration 才能将所有图片训练一遍,即一个 epoch 是 5000 个 iteration。

若设置 max_iteration = 450000,那么就是最多训练 450000 / 5000 = 90 个 epoch。

learning_rate 衰减与 stepsize 和 gamma 有关,stepsize 决定了 lr 什么时候衰减(衰减步长),gamma 决定了 lr 一次衰减多少(衰减系数)。若设置 stepsize = 500,base_lr = 0.01,gamma = 0.1,那么迭代到第一个 500 次时,lr 进行第一次衰减 lr = lr * gamma = 0.01 * 0.1 = 0.001,下一个 500 次再重复该过程。

训练过程中,每到一定的迭代次数都会进行 test(其实是校验而不是测试),至于迭代次数则是由 test_interval 决定的,若设 test_interval = 1000,则每迭代 1000 次就会测试一遍当前的网络。test_size 决定了在 test 时每次迭代输入图片的数量(类似于训练过程中的 batchsize),test_iter 是 test 所有测试图像的迭代次数。


FCN 项目官方说明文档:

Fully Convolutional Networks for Semantic Segmentation

This is the reference implementation of the models and code for the fully convolutional networks (FCNs) in the PAMI FCN and CVPR FCN papers:

Fully Convolutional Models for Semantic Segmentation
Evan Shelhamer*, Jonathan Long*, Trevor Darrell
PAMI 2016
arXiv:1605.06211

Fully Convolutional Models for Semantic Segmentation
Jonathan Long*, Evan Shelhamer*, Trevor Darrell
CVPR 2015
arXiv:1411.4038

Note that this is a work in progress and the final, reference version is coming soon.
Please ask Caffe and FCN usage questions on the caffe-users mailing list.

Refer to these slides for a summary of the approach.

These models are compatible with BVLC/caffe:master.
Compatibility has held since master@8c66fa5 with the merge of PRs #3613 and #3570.
The code and models here are available under the same license as Caffe (BSD-2) and the Caffe-bundled models (that is, unrestricted use; see the BVLC model license).

PASCAL VOC models: trained online with high momentum for a ~5 point boost in mean intersection-over-union over the original models.
These models are trained using extra data from Hariharan et al., but excluding SBD val.
FCN-32s is fine-tuned from the ILSVRC-trained VGG-16 model, and the finer strides are then fine-tuned in turn.
The “at-once” FCN-8s is fine-tuned from VGG-16 all-at-once by scaling the skip connections to better condition optimization.

  • FCN-32s PASCAL: single stream, 32 pixel prediction stride net, scoring 63.6 mIU on seg11valid
  • FCN-16s PASCAL: two stream, 16 pixel prediction stride net, scoring 65.0 mIU on seg11valid
  • FCN-8s PASCAL: three stream, 8 pixel prediction stride net, scoring 65.5 mIU on seg11valid and 67.2 mIU on seg12test
  • FCN-8s PASCAL at-once: all-at-once, three stream, 8 pixel prediction stride net, scoring 65.4 mIU on seg11valid

FCN-AlexNet PASCAL: AlexNet (CaffeNet) architecture, single stream, 32 pixel prediction stride net, scoring 48.0 mIU on seg11valid.
Unlike the FCN-32/16/8s models, this network is trained with gradient accumulation, normalized loss, and standard momentum.
(Note: when both FCN-32s/FCN-VGG16 and FCN-AlexNet are trained in this same way FCN-VGG16 is far better; see Table 1 of the paper.)

To reproduce the validation scores, use the seg11valid split defined by the paper in footnote 7. Since SBD train and PASCAL VOC 2011 segval intersect, we only evaluate on the non-intersecting set for validation purposes.

NYUDv2 models: trained online with high momentum on color, depth, and HHA features (from Gupta et al. https://github.com/s-gupta/rcnn-depth).
These models demonstrate FCNs for multi-modal input.

SIFT Flow models: trained online with high momentum for joint semantic class and geometric class segmentation.
These models demonstrate FCNs for multi-task output.

Note: in this release, the evaluation of the semantic classes is not quite right at the moment due to an issue with missing classes.
This will be corrected soon.
The evaluation of the geometric classes is fine.

PASCAL-Context models: trained online with high momentum on an object and scene labeling of PASCAL VOC.

Frequently Asked Questions

Is learning the interpolation necessary? In our original experiments the interpolation layers were initialized to bilinear kernels and then learned.
In follow-up experiments, and this reference implementation, the bilinear kernels are fixed.
There is no significant difference in accuracy in our experiments, and fixing these parameters gives a slight speed-up.
Note that in our networks there is only one interpolation kernel per output class, and results may differ for higher-dimensional and non-linear interpolation, for which learning may help further.

Why pad the input?: The 100 pixel input padding guarantees that the network output can be aligned to the input for any input size in the given datasets, for instance PASCAL VOC.
The alignment is handled automatically by net specification and the crop layer.
It is possible, though less convenient, to calculate the exact offsets necessary and do away with this amount of padding.

Why are all the outputs/gradients/parameters zero?: This is almost universally due to not initializing the weights as needed.
To reproduce our FCN training, or train your own FCNs, it is crucial to transplant the weights from the corresponding ILSVRC net such as VGG16.
The included surgery.transplant() method can help with this.

What about FCN-GoogLeNet?: a reference FCN-GoogLeNet for PASCAL VOC is coming soon.


参考文章

https://www.cnblogs.com/xuanxufeng/p/6243342.html
https://blog.csdn.net/wangkun1340378/article/details/70238290
https://blog.csdn.net/weixin_42795611/article/details/85945649
https://www.cnblogs.com/deeeplearnxl/p/6228457.html
https://blog.csdn.net/raby_gyl/article/details/65633400
https://blog.csdn.net/auto1993/article/details/71297151
https://blog.csdn.net/weixin_42795611/article/details/85945649
https://blog.csdn.net/a8039974/article/details/78603017

另外,发现一个Caffe 网络可视化工具:http://ethereon.github.io/netscope/quickstart.html

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃饭就会放大招

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值