将迁移学习用到Cascade RCNN模型开发说明书

Cascade RCNN.

选择Cascade RCNN来进行下面的将迁移学习用到目标检测任务中的实验, 即将新的检测任务融合到原始的检测任务中.

Cascade RCNN模型目前有几大实现项目, 具体可见https://github.com/zhaoweicai/Detectron-Cascade-RCNN. 但是mmdetection和tensorpack都是很多检测模型的融合, 这和Tensorflow Detection API类似, 因此暂不使用.

1. 数据集

准备数据集时, 可以借助cascade-rcnn_Pytorch的Data Preparation流程.

2. 安装

cd lib
sh make.sh
根据作者项目介绍, Pytorch版本使用的是0.2.0, 如果版本大于0.4.0, 那么会报错: ImportError: torch.utils.ffi is deprecated. Please use cpp extensions instead.

可以安装pytorch0.3.0, 支持CUDA9.0, 需要

export C_INCLUDE_PATH=/usr/local/cuda-9.0/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/usr/local/cuda-9.0/include:$CPLUS_INCLUDE_PATH

安装Pytorch 0.2.0, 仅支持CUDA 8, 新建pyt tmux.

export PATH=/home/ly/cuda-8.0/bin:$PATH
export LD_LIBRARY_PATH=/home/ly/cuda-8.0/lib64:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/home/ly/cuda-8.0/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/home/ly/cuda-8.0/include:$CPLUS_INCLUDE_PATH

https://pytorch.org/get-started/previous-versions/ 下载历史版本.

3. 利用Cascade RCNN来做迁移学习.

  1. 该项目训练集使用的是PASCAL VOC2007+2012. 只可以做20类的目标检测. 虽然效果可能不好, 但是可以先实验一下. 按照方法(1)的思路, 修改模型相应的代码已经完成.

  2. 准备所需的数据集格式. cascade_rcnn_Pytorch项目, 数据集的准备可以参考PASCAL VOC2007/2012或COCO数据集的样子进行准备即可. 只要数据集和的准备的形式和PASCAL VOC2007/2012或者COCO数据集的类似即可.
    目前迁移数据, 即新任务的检测数据集使用WIDER FACE数据集, 根据/home/ly/git/Transfer_Learning_Object_Detection/scripts/data-to-pascal-xml.py代码, 准备好的xml文件和PASCAL VOC2007/2012的标注xml文件是一致的. 因此, 将/home/ly/git/Transfer_Learning_Object_Detection/datasets的tf_wider_train按照PASCAL VOC2007/2012的目录结构安排即可.

  3. 将/home/ly/git/Transfer_Learning_Object_Detection/datasets的tf_wider_train拷贝到./datasets下, 并按照PASCAL VOC目录格式准备.

  4. 修改/home/ly/git/Cascade_RCNN_Pytorch/lib/datasets下的factory.py, 加进WIDER FACE数据集的支持.
    copy pascal_voc.py为wider_face.py, 并修改一些东西.

  5. 修改trainval_net.py. 开始训练.
    python trainval_net.py --exp_name object_face_detection --dataset wider_face --net detnet59 --bs 2 --nw 4 --lr 1e-3 --epochs 5 --save_dir weights --cuda --cag --cascade --r True --checkepoch 3 --checkpoint 7389
    1> 训练时出现的问题: mismatch between the batch size of input (254) and that of target (256)
    解决方案:
    (1) 将bbox的值都加一个固定的小数, 如0.01, 解决mismatch问题. Deprecated!!! 不是根本原因.
    (2) 根本原因出在fpn.py下面: roi_level = torch.log(torch.sqrt(h * w) / 224.0) / np.log(2), 开方的数据可能出现负数, 因此出现了nan, 因此就会出现mismatch问题. 可以将开方设置成正数即可.

  6. 修改demo.py. 开始测试.
    原始检测任务demo: python demo.py --net detnet59 --cuda --cag --image_dir demo_images --cascade --result_dir vis_cascade/cascade_rcnn
    迁移学习检测demo: python trans_demo.py --net detnet59 --cuda --cag --image_dir demo_images --cascade --result_dir vis_cascade/trans

4. 当用迁移学习训练完之后, 在测试的过程中. 会对原有的检测模型造成损坏. 通过检查后发现:

  1. 原有的Cascade RCNN模型中layer的参数和迁移学习训练后相同layer的参数是一样的, 这就证明原有模型的layer没有学习.
  2. 造成破坏的原因应该在这: 对于模型中存在Dropout, BatchNorm层时, 由于在训练和测试阶段的操作是不一样的. 在测试时会调用到训练中的一些数值, 如在训练中保存的均值方差等. 但是在做迁移学习训练时, 并没有将Dropout, BatchNorm层的mode设置为eval!!!
    在做迁移学习的训练时, 按照原有代码的设置的mode进行设置!!!
    按照原有代码进行设置layer的mode后, 貌似训练过程也比之前好了!!! 果然是这个问题!!!
    设置成原有的mode之后, 不仅精度提升了, 而且速度也得到了大幅提升!!!

这个问题已经解决了. 当在训练或测试时, 要调用的全局变量设置在./cfg/*.yml中, .yml会再次设置./lib/model/utils/config.py下的变量. 例如对于cfg.POOLING_MODE, 使用的就是"align". 因为在.yml中, 已经定义了POOLING_MODE.

你可能感兴趣的:(迁移学习,深度学习)