文章目录
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
- Git的安装及使用:
https://blog.csdn.net/qq_44747572/article/details/121006841 - 克隆Code:
pytorch1.0.0版源码: https://github.com/jwyang/faster-rcnn.pytorch/tree/pytorch-1.0
下载zip,在指定文件夹内进行解压:
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