【目标检测】Faster R-CNN的复现

Faster Rcnn

  • Faster Rcnn:
    1.Conv layers
    使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。
    2.Region Proposal Networks
    RPN网络用于生成region proposals。该层通过softmax判断anchors属于positive或者negative,再利用bounding box regression修正anchors获得精确的proposals。
    3.Roi Pooling
    该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
    4.Classification
    利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。
    在这里插入图片描述
    基于VGG16的网络:
    在这里插入图片描述

  • RPN: 生成anchors -> softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals
    RPN结构示意图:
    网络上层: 通过softmax分类anchors获得positive和negative分类。
    网络下层: 用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。
    Proposal: 综合positive anchors和对应bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。
    在这里插入图片描述
    在这里插入图片描述

anchors:
其中每行的4个值(x1, y1, x2, y2) 表矩形左上和右下角点坐标。9个矩形共有3种形状,长宽比为大约为(H:W, 1:1, 1:2, 2:1) 三种,实际上通过anchors就引入了检测中常用到的多尺度方法。
在这里插入图片描述 在这里插入图片描述
为每个feature maps上的点提供一个anchors。
每个点上有k个anchor(默认k=9),而每个anhcor要分positive和negative,所以每个点由256d feature转化为cls=2•k scores;而每个anchor都有(x, y, w, h)对应4个偏移量,所以reg=4•k coordinates。

全部anchors拿去训练太多了,训练程序会在合适的anchors中随机选取128个postive anchors+128个negative anchors进行训练
在这里插入图片描述

  • Bounding Box Regression:
    绿色框为飞机的Ground Truth(GT),红色为提取的positive anchors,即便红色的框被分类器识别为飞机,但是由于红色的框定位不准,这张图相当于没有正确的检测出飞机。所以我们希望采用一种方法对红色的框进行微调,使得positive anchors和GT更加接近。
    在这里插入图片描述在这里插入图片描述
    红色的框A代表原始的positive Anchors,绿色的框G代表目标的GT,我们的目标是寻找一种关系,使得输入原始的anchor A经过映射得到一个跟真实窗口G更接近的回归窗口G’。即可以利用线性回归关系,使得A -> G’。

  • Anchor&Proposal layer: 获得精准的proposal
    执行流程:

    for each (H, W) location i
        1.在i位置生成A个anchor box
    	2.把预测的包围盒变量应用于每个位置的每个锚点
    	3.使用预测盒剪切图片
    	4.去掉宽和长小于阈值的包围盒
    	5.从高到低对所有proposal,score 序列排序
    	6.选择topN, 应用非极大值抑制, 使用0.7做阈值
    按照Batch返回TopN
    

    可理解为:

    0.输入之前RPN两条支路中所生成的
    	rpn_cls_prob_reshape,
    	(1 , H , W , Ax2)
    	rpn_bbox_pred,
    	(1 , H , W , Ax4)
    	以及原始图像的信息
    	[image_height, image_width, scale_ratios]
    1.基于feature map 尺寸,按照指定的长宽大小组合生成所有pixel位置的 anchor(shift base_anchors)
    2.对这些anchor做剪枝(clip,transfrom,filter,NMS),TopN备选
    3.把剪枝后的anchor包装为proposal
    
  • NMS(Non-Max Suppression,非极大值抑制):

     NMS算法一般是为了去掉模型预测后的多余框,其一般设有一个nms_threshold=0.5,具体的实现思路如下:
     
     选取这类box中scores最大的那一个,记为box_best,并保留它
     计算box_best与其余的box的IOU
     如果其IOU>0.5了,那么就舍弃这个box(由于可能这两个box表示同一目标,所以保留分数高的那一个)
     从最后剩余的boxes中,再找出最大scores的那一个,如此循环往复
     
     可以理解为:
     先假设有6个输出的矩形框(即proposal_clip_box),根据分类器类别分类概率做排序,从小到大分别属于车辆的概率(scores)
     分别为A、B、C、D、E、F。
     (1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;
    
     (2)假设B、D与F的重叠度(IOU)超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。
    
     (3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。
     
     就这样一直重复,找到所有被保留下来的矩形框。
    

    输入:
    在这里插入图片描述
    输出:
    在这里插入图片描述

  • ROI-Pooling:
    目标检测 two stage typical architecture 通常可以分为两个阶段:
    (1)region proposal: 给定一张输入image找出objects可能存在的所有位置。这一阶段的输出应该是一系列object可能位置的bounding box。(regions or ROIs)

    (2)final classification: 确定上一阶段的每个region proposal是否属于目标类别或者背景。

    ROI Pooling的目的就是使用MaxPooling针对不定尺寸的输入,产生指定尺寸的feature map。

    这个architecture存在的一些问题是:

    1,产生大量的region proposals 会导致性能问题,实时性能会大大降低
    2,在处理速度方面是suboptimal。
    3,无法做到端到端的训练

    由于这个步骤没有得到大多数神经网络库的支持,所以需要实现足够快的ROI Pooling操作,这就需要使用C来执行,在GPU条件下需要CUDA来执行

    ROI pooling具体操作如下:

    (1)根据输入image,将ROI映射到feature map对应位置;
    (2)将映射后的区域划分为相同大小的sections(sections数量与输出的维度相同);
    (3)对每个sections进行max pooling操作;

    这样我们就可以从不同大小的方框得到固定大小的相应 的feature maps。值得一提的是,输出的feature maps的大小不取决于ROI和卷积feature maps大小。ROI pooling 最大的好处就在于极大地提高了处理速度。
    如下图所示:

    在这里插入图片描述
    以下为一个 ROI pooling 的例子
    考虑一个8×8大小的feature map,一个ROI,以及输出大小为2×2.
    (1)输入的固定大小的 feature map
    (2)region proposal 投影之后位置(左上角,右下角坐标):(0,3),(7,0)。
    (3)将其划分为(2×2)个sections(因为输出大小为2×2)
    (4)对每个section做max pooling,可以得到:

    请添加图片描述

  • Classification:
    Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。

在这里插入图片描述
回归主要完成:
1.通过全连接和softmax对proposals进行分类,这实际上已经是识别的范畴了。
2.再次对proposals进行bounding box regression,获取更高精度的rect box。
全连接示意图:
在这里插入图片描述
公式:
在这里插入图片描述
其中W和bias B都是预先训练好的,即大小是固定的,当然输入X和输出Y也就是固定大小。所以,这也就印证了之前Roi Pooling的必要性。

Faster Rcnn代码导读: https://zhuanlan.zhihu.com/p/145842317

0. 利用Git下载Code

1. 数据准备

  • 切换路径到faster-rcnn.pytorch下,并在其目录下创建data文件夹:

     xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/$ cd faster-rcnn && mkdir data
    
  • 下载数据至data文件夹:
    切换路径到data下

    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python$ cd faster-rcnn
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ cd data
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/data$ 
    

    开始下载压缩文件,执行如下命令,下载VOV2007标准数据集的相关数据。

    wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
    wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
    wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
    

    执行下方命令解压缩数据到data/VOCdevkit

    tar xvf VOCtrainval_06-Nov-2007.tar
    tar xvf VOCtest_06-Nov-2007.tar
    tar xvf VOCdevkit_08-Jun-2007.tar
    

    cd 进入data文件夹下,创建软链接

    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/data$ pwd
    /home/xiaoxie/data/yx/python/faster-rcnn/data
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/data$ ln -s /home/xiaoxie/data/yx/python/faster-rcnn/data/VOCdevkit VOCdevkit2007
    

    数据集的详细解释:
    https://blog.csdn.net/qq_38273984/article/details/90749314
    https://blog.csdn.net/weixin_42782150/article/details/109820615

2. 模型加载

  • 下载预训练模型:
    首先,在/data/下创建子文件夹/data/pretrained_model;然后,下载预训练模型到/data/pretrained_model下,如VGG16,ResNet101等。

    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/data$ sudo mkdir pretrained_model
    

    VGG16: Dropbox VT Server
    ResNet101: Dropbox VT Server
    注: 下载结束后,将这两个模型都放进/data/pretrained_model/文件夹中。

  • 编译:
    使用pip安装所有python依赖包,cd 进入requirements.txt文件所在的路径下:

    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ pip install -r requirements.txt
    

    当使用pip下载不成功时,可以使用以下命令:

    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ pip install -r requirements.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
    

    编译CUDA依赖环境:
    这里为pytroch1.0的编译设置,编辑所需的cuda环境后,回到主目录。

    cd lib
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/lib$ sudo python setup.py build develop
    # 不要使用sh make.sh
    

3. 模型训练

在训练之前需要根据自己的环境将trainval_net.py和test_net.py中的两个参数save_dir和load_dir进行更改。

  • VGG16在pascal_voc上训练faster R-CNN使用如下命令(具体参数根据自己的需要修改):

     CUDA_VISIBLE_DEVICES=$GPU_ID python trainval_net.py \
                       --dataset pascal_voc --net vgg16 \
                       --bs $BATCH_SIZE --nw $WORKER_NUMBER \
                       --lr $LEARNING_RATE --lr_decay_step $DECAY_STEP \
                       --cuda
    
  • RES101训练命令行示例:

    CUDA_VISIBLE_DEVICES=0 python trainval_net.py --dataset pascal_voc --net res101 --bs 4 --nw 0 --lr 0.001 --lr_decay_step 5 --cuda
    

    或者

    CUDA_VISIBLE_DEVICES=0,1 python trainval_net.py --dataset pascal_voc --net res101 --cuda
    

    这里使用如下命令:

    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/lib$ cd ..
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ 
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ CUDA_VISIBLE_DEVICES=0 python trainval_net.py --dataset pascal_voc --net res101 --bs 4 --nw 0 --lr 0.001 --lr_decay_step 5 --cuda
    

    参数:

      - CUDA_VISIBLE_DEVICES:指gpu的id,这得看你实验室服务器哪块gpu是闲置的。
      - dataset:指训练数据集名称,此处以pascal-voc为例。
      - net:你要使用的预训练模型,可以换为resnet101。
      - bs:指的batch size。
      - epoch:指要训练的轮数。
      - nw:指的是worker number,取决于你的Gpu能力,我用的是Titan Xp
      - 12G,所以选择4。稍微差一些的gpu可以选小一点的值。
      - lr:指学习率
      - cuda:指的是使用gpu。
      - BATCH_SIZE 和 WORKER_NUMBER 可以根据你的GPU情况来设置。
      - 训好的model会存到models文件夹底下,此处暂时使用默认的训练参数。
    

    出现问题: ImportError: cannot import name '_mask'
    解决问题: https://blog.csdn.net/qq_44747572/article/details/121020895
    出现问题: ImportError: cannot import name 'imread'
    解决问题: xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ pip install scipy==1.2.1 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

4. 模型测试

评估res101预训练模型在pascal_voc测试集上的表现,使用如下命令:

python test_net.py --dataset pascal_voc --net res101 \
                   --checksession $SESSION --checkepoch $EPOCH --checkpoint $CHECKPOINT \
                   --cuda

设置示例:

python test_net.py --dataset pascal_voc --net res101 --checksession 1 --checkepoch 20 --checkpoint 2504 --cuda

注意,这里的三个check参数,是定义了训好的检测模型名称,我训好的名称为faster_rcnn_1_20_2504,代表了checksession = 1,checkepoch = 20, checkpoint = 2504,这样才可以读到模型“faster_rcnn_1_20_2504”。训练中,源码代码默认设置的epoch为20,所以checkepoch选择20,也就是选择最后那轮训好的模型,理论上应该是效果最好的。下图就是我20次epochs的模型。

测试时,出现 Segmentation fault (core dumped)
改用anaconda管理环境

  • 创建anaconda新环境
    https://blog.csdn.net/anpwu/article/details/110290310
    问题:CondaHTTPError: HTTP 000 CONNECTION FAILED
    解决:https://blog.csdn.net/anniaxie/article/details/107197513
    若不能解决尝试添加其他镜像源:https://blog.csdn.net/yst990102/article/details/106730382

  • 安装各种库
    requirements.txt包含项目所需要的库

    (TargetDetect) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ pip install -r requirements.txt
    

    编译CUDA依赖环境:
    这里为pytroch1.0的编译设置,编辑所需的cuda环境后,回到主目录。

    cd lib
    xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/lib$ sudo python setup.py build develop
    # 不要使用sh make.sh
    

    pytorch安装: https://blog.csdn.net/mao_hui_fei/article/details/112078113
    在这里插入图片描述 在这里插入图片描述
    安装指定版本的torch/torchvision (离线下载对应版本的torch/torchvision,保存到运行路径下,使用pip进行导入)
    torch/torchvision: https://download.pytorch.org/whl/torch_stable.html

    (yx_env) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ pip install torch-1.5.0+cu101-cp36-cp36m-linux_x86_64.whl
    (yx_env) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ pip install torchvision-0.6.0+cu101-cp36-cp36m-linux_x86_64.whl
    

    在这里插入图片描述

  • 运行faster rcnn程序

    (TargetDetect) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ python test_net.py --dataset pascal_voc --net res101 --checksession 1 --checkepoch 20 --checkpoint 2504 --cuda
    

    问题:

    ImportError: /home/xiaoxie/data/yx/python/faster-rcnn/lib/model/_C.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZN3c104cuda20getCurrentCUDAStreamEa
    

    解决:

    conda install pytorch==1.0.0 torchvision==0.2.1 cuda100 -c pytorch
    

    问题:

    ImportError: libtorch_cpu.so: cannot open shared object file: No such file or directory
    

    解决:

    (yx_env) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn$ cd lib
    (yx_env) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/lib$ rm -r build
    (yx_env) xiaoxie@xiaoxie-Z10PE-D8-WS:~/data/yx/python/faster-rcnn/lib$ python setup.py develop
    

    问题:

    TypeError: load() missing 1 required positional argument: 'Loader'
    

    解决:

    yaml_cfg = edict(yaml.load(f, Loader=yaml.FullLoader))
    

    问题:

    _pickle.UnpicklingError: A load persistent id instruction was encountered,
    but no persistent_load function was specified.
    

    解决:
    保存模型和合并模型时pytorch版本不一致。合并模型时切换为保存模型的pytorch版本即可。
    重新训练。(这里我选择了重新训练)

5. 运行demo.py

如果你想要运行预训练模型去检测新的test图片,要先下载预训练模型或者训练你自己模型,然后把图片放到工作目录下(示例路径:~/images)的images文件夹里,再运行如下命令:

python demo.py --net vgg16 \
               --checksession $SESSION --checkepoch $EPOCH --checkpoint $CHECKPOINT \
               --cuda --load_dir + 模型存放文件夹

示例:

python demo.py --net res101  --checksession 1  --checkepoch 20 --checkpoint 2504 --cuda --load_dir models

结果:
在这里插入图片描述

6. 训练自定义Images文件和对应XML文件的model

https://blog.csdn.net/weixin_42782150/article/details/109820615
(先码着,后面需要再学习)

参考:
https://zhuanlan.zhihu.com/p/31426458
https://blog.csdn.net/weixin_42782150/article/details/109820615
https://blog.csdn.net/ThunderF/article/details/100294913
https://blog.csdn.net/admintan/article/details/91366551

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

只搬烫手的砖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值