CPU 跑 Faster RCNN Demo

自己的电脑 GPU 太老了,Theano 都给提示说不支持。

那好,下面记录一下如何使用 CPU 来跑 Faster RCNN。

编译

过程比较坎坷:

  1. 代码里面带的 Caffe 版本比较老,所以我们需要将它 升级为新版

  2. 原始版本里面有两个东西是没有 CPU 实现的。我们需要自己来写或者补这部分的实现。这里有几个版本: 第一个版本(推荐,不会出错) / 第二个版本(好像有点问题)

  3. $/FRCN_ROOT/lib/setup.py 中,注释掉 CUDA = locate_cuda()self.set_executable('compiler_so', CUDA['nvcc']),并注释掉 ext_modules 中的 nms.gpu_nms 段。

  4. $FRCN_ROOT/lib/fast_rcnn/config.py 中 205 行的 __C.USE_GPU_NMS = True 改成 __C.USE_GPU_NMS = False

  5. $FRCN_ROOT/lib/fast_rcnn/nms_wrapper.py 中的第 9 行 from nms.gpu_nms import gpu_nms 注释掉

  6. $/FRCN_ROOT/libmake 一下。

然后 配置 Makefile.conf 并进行编译

这里需要说一下:编译过程中不管用不用 GPU 好像都需要配置 CUDA。CUDA8.0 编译不通过,CUDA7.5/8.0 编译 Test 均通不过。不要使用 Python3。

跑测试 Demo

首先去下载训练好的模型:

之后是直接调用模型进行训练:

应该可以看到效果。

跑训练 Demo

前面都是在 “跑测试”。如果 “跑训练” 的话,修改的代码会更多(因为人家压根没想让你用 CPU 训练):

$/FRCN_ROOT/tool/train_faster_rcnn_alt_opt.py$/FRCN_ROOT/tool/test_net.py 中注释掉 caffe.set_mode_gpu()caffe.set_device(cfg.GPU_ID),并替换为 caffe.set_mode_cpu(),或者用其他相似的办法(比如,GPU_ID 小于 0 那么就用 CPU)。

$/FRCN_ROOT/lib/fast-rcnn/train.py 中,加入 import google.protobuf.text_format

然后,按照官方 Readme 获取所有训练数据和进行 Train 了。

loss 是负无穷,说明根本没收敛啊。但是,你不觉得,作为官方 Demo,应该任何地方都不用动就能达到文档中的效果才对么?

也查了一些资料。今天早上突然眼尖发现了几个有用的。

首先是 这里 ,说道 “如果出现 NaN,需要降低学习率”,但是有人反应说,把学习率降到 0 仍然出现 NaN。

然后是 这里 ,这个博主也是拿 CPU 训练的。 把 /home/wjx/py-faster-rcnn/models/pascal_voc/ZF/faster_rcnn_alt_opt 文件夹下将四个 solver 文件里面的 base_lr 由 0.001 调小一点

最后是 这里 。由于博文比较短,就直接搬运过来:

caffe 在 cifar10 的 example 上给出了两个模型,一个是 quick 模式,一个是 full 模式,训练 full 模式时会出现 loss=nan 的错误(当然不会报错,不过出现这个结果就是 bug)
自己 google 了一下,在 github 上找到了原因跟解决方案,原来是作者把用在 cuda-convnet 的模型照搬过来了,在 caffe 上的模型应该去掉 LRN 层,所以解决的方法很简单:将网络结构中所有的归一化层全部去掉,并修改下一层的 bottom 参数,然后就不会出现 loss=nan 的错误了。
当然,如果自己做实验时出现 loss=nan 的问题时,我的一个解决办法是修改学习率,改的小一点就不会出现错误了。实在不行,就把里面的 relu 函数变为 sigmoid 试一试,代价就是训练速度会非常非常慢。
还有一个要检查的点就是要看一下网络的结构是否合理,我在网上下载的 network in network 的网络结构,最后一层竟然没有一层全连接把输出变为类别数,这让训练陷入了要么出现 nan 要么结果一直不变的 bug 境地。

自己尝试了将 base_lr 从 0.001 降到了 0.0001,效果不明显。原来是 20 轮出现 NaN,现在是 40 轮出现 NaN。按照这个形式发展下去,是不是得把学习率降到 1e-1000000 左右才能完整跑完训练?

然后又试着把 base_le 降到 0.00001(1e-5),好像正常了。目前跑了 100 多轮,没有 NaN。

一个监视脚本

由于没有装可视化的东西,只能自己进行可视化的工作。好在输出的 Log 里面有足够的信息。

下面是可视化的效果: 横坐标是迭代的轮数,纵坐标是 Loss。

可视化效果

对应的代码(很暴力):

后记

Caffe 版本太多了…… 官方版。nlp caffe,这里还有个 caffe-rcnn …… 个人魔改的版本都是 “改了之后就弃坑”,每个版本的错误都不一样……

心累

更心累的是,没有 GPU……

另:求解释为什么 bbox 的 loss 一直是震荡的?

更新: 使用 GPU 跑 Demo 的失败例子在这里 ,倒不是因为方法失败了,而是因为显卡不给力。不过这个文章里面记录了如何升级 caffe、如何解决 make test 失败的方法。

《CPU 跑 Faster RCNN Demo》上有4条评论

  1. 博主, 请问我用 FASTER RCNN CPU 下训练自己的数据, 3000 多张, 迭代次数大概要改成多少呢

    py-faster-rcnn/tools/train_faster_rcnn_alt_opt.py

    max_iters = [80000, 40000, 80000, 40000]

    1. 你确定要用 CPU 来跑么……

      我这里设置的大概是 10~15 个 epoch,单 GTX1060 大概用时 8h 左右(有点记不清了)

      如果是 3000 多张的话,大概是 [60000, 30000, 60000, 30000],估计用不了 1 年就能跑完了…… /手动捂脸

  2. 楼主,您好,我最近在跑 py-fater-crnn 的时候,下载了训练好的 faster_rcnn_models(VGG16_faster_rcnn_final.caffemodel&ZF_faster_rcnn_final.caffemodel),其中运行 ./demo.py --net zf --cpu 出现了 reshape_layer.cpp:80] Check failed: 0 == bottom[0]->count() % explicit_count (0 vs. 180) bottom count (450) must be divisible by the product of the specified dimensions (270), 像你的教程示例好像是默认的 vgg16,我要使用 zf 模型,请问有解决办法吗?因为我训练最近的数据使用 vgg16 时候,一直是出现-nan,按照你的示例教程修改了还是一样,不知道什么回事,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注