技术综述万字长文详解Faster RCNN源代码Word文档下载推荐.docx
《技术综述万字长文详解Faster RCNN源代码Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《技术综述万字长文详解Faster RCNN源代码Word文档下载推荐.docx(30页珍藏版)》请在冰点文库上搜索。
本文包括两个局部
对经典算法FasterR-CNN的源代码进展详细的讲明选用的代码为caffe版本链接为s:
//github/rbgirshick/py-faster-rcnn。
基于该框架完成一个简单的理论。
在正式解读代码之前要先讲清楚两个重要概念rpn与roi
pooling。
1.2
roipooing
通常我们训练一次取多张图也就是一个batch一个batch中图大小一致这是为了从源头上把控进而获得固定维度的特征。
所以在早期进展目的检测会将候选的区域进展裁剪或者缩放到统一尺度如下列图红色框。
副作用很明显一次只选到了目的一局部或把目的变形了。
sppnet不从源头而是在最后一环的特征上做处理将任意尺度(大于4*4)大小的特征进展3种pooling串接起来得到固定的21维进而防止了固定尺寸输入的约束如下。
当然你用的时候不必要局限于4*42*21*1。
以前为了知足全连接层固定大小输入需要在输入图进展缩放然后提取特征。
如今既然已经可以在特征空间进展缩放了那么就不必要求输入一样大了。
原来的那些只是因为在原始空间中有了细微的位置或尺寸改变就要重新提取特征的大量重复操作就不需要了因为任意的原始图像中的输入是可以映射到特征图中的卷积只会改变空间分辨率不改变比例以及位置。
映射很简单等比例缩放即可实现时考虑好paddingstride等操作。
那这跟roipooling有什么关系呢
ROIpooling是一个简化的spp池化不需要这么复杂直接一次分块pooling就行了在经过了从原始空间到特征空间的映射之后设定好一个pooled_w一个pooled_h就是将W*H的输入pooling为pooled_w*pooled_h的特征图然后放入全连接层。
它完成的下面的输入输出的变换。
1.2RPN
regionproposalnetwork可知道这就是一个网络而且是一个小小的网络。
它解决了roipooling的输入问题就是怎样得到一系列的proposal也就是原图中的候选框。
图比拟难画就借用原文了如上而rpn网络的功能示意图如下。
最开场当我们想要去提取一些区域来做分类以及回归时那就穷举嘛搞不同大小不同比例的框在图像中从左到右从上到下滑动如上图一个就选了9种。
这样计算量很大所以selectivesearch利用语义信息改良防止了滑动但还是需要在原图中操作因为特征提取不能分享。
如今不是有了sppnet以及roipooling的框架把上面的这个在原图中进展穷举滑动的操作换到了比原图小很多的特征空间比方224*224--13*13还是搞滑动窗口就得到了rpn如下列图。
rpn实现了了上面的输入输出。
不同与简单滑窗的是网络会对这个经过进展学习得到更有效的框。
剩下的就是一些普通cnn的知识不用多讲有了上面的这些根底后我们开场解读代码。
02
py-faster-rcnn框架解读
FasterR-CNN源代码的熟悉几乎是所有从事目的检测的人员必须迈过的坎由于目录构造比拟复杂而且广泛为人所用涉及的东西非常多所以我们使用的时候维持该目录构造不变下面首先对它的目录构造进展完好的分析。
目录下包括caffe-fast-rcnndataexperimentslibmodelstools几大模块。
2.1caffe-fast-rcnn
这是rcnn系列框架的caffe因为目的检测中使用到了很多官方caffe中不包括的网络层所以必须进展定制。
这里需要注意的是caffe是以子模块的方式被包含在其中所以使用gitclone命令下载代码将得到空文件夹必需要加上递归参数-recursive详细做法如下
gitclone--recursives:
//github/rbgirshick/py-faster-rcnn.git
2.2data
该文件夹下包含两个子文件夹一个是scripts一个是demo。
其中demo就是用于存放测试的图像script存储着假设干脚本它用于获取一些预训练的模型。
比方运行fetch_imagenet_models.sh脚本会在当前的文件夹下建立imagenet_models目录并下载VGG_CNN_M_1024.v2.caffemodelVGG16.v2.caffemodelZF.v2.caffemodel模型这些是在ImageNet上预先训练好的模型将用于初始化我们的检测模型的训练。
另外还在该目录下建立数据集的软链接。
通常情况下对于一些通用的数据集我们会将它们放在公用的目录而不是某一个工程下所以这里通常需要建立通用数据集的软链接比方PASCALVOC的目录。
ln-s/your/path/to/VOC2021/VOCdevkitVOCdevkit2021
2.3
experiments
下面分为3个目录分别是logcfgsscripts。
cfgs存放的就是配置文件比方faster_rcnn_end2end的配置如下:
EXP_DIR:
faster_rcnn_end2end
TRAIN:
HAS_RPN:
True
IMS_PER_BATCH:
1
BBOX_NORMALIZE_TARGETS_PRECOMPUTED:
RPN_POSITIVE_OVERLAP:
0.7
RPN_BATCHSIZE:
256
PROPOSAL_METHOD:
gt
BG_THRESH_LO:
0.0
TEST:
其中比拟重要的包括HAS_RPNRPN_BATCHSIZE等。
Log目录就存放log日志。
scripts存放的就是bash训练脚本可以用end2end或alt_opt两种方式训练。
每一个训练脚本都包含两个步骤训练以及测试。
time./tools/train_net.py--gpu${GPU_ID}\
--solvermodels/${PT_DIR}/${NET}/faster_rcnn_end2end/solver.prototxt\
--weightsdata/imagenet_models/${NET}.v2.caffemodel\
--imdb${TRAIN_IMDB}\
--iters${ITERS}\
--cfgexperiments/cfgs/faster_rcnn_end2end.yml\
${EXTRA_ARGS}
如上就是训练局部代码对于默认的任务我们不需要修改这里的代码但是假如我们不想用预训练或相关的配置发生了变化比方yml格式的配置文件预训练模型的前缀格式需要配置自定义的数据集等等那么需要修改此处代码。
2.4Models目录
该目录下包含两个文件夹coco以及pascalvoc可知是两个通用数据集。
在各个数据集的子目录下存储了一系列模型构造的配置如models/pascal/VGG_CNN_M_1024/目录存储的就是用于训练coco数据集的VGG模型。
在该目录下有fast_rcnnfaster_rcnn_alt_optfaster_rcnn_end_to_end三套模型构造各自有所不同。
fast_rcnn即fast_rcnn方法它下面只包含了train.prototxttest.prototxtsolver.prototxt三个文件它对rcnn的改良主要在于重用了卷积特征没有regionproposal框架。
faster_rcnn_alt_optfaster_rcnn_end_to_end都是fasterrcnn框架包括了regionproposal模块。
在faster_rcnn_alt_opt目录下包含了4个训练文件以及对应的solver文件为
stage1_fast_rcnn_solver30k40k.ptstage1_fast_rcnn_train.ptstage1_rpn_solver60k80k.ptstage1_rpn_train.ptstage2_fast_rcnn_solver30k40k.ptstage2_fast_rcnn_train.pt
stage2_rpn_solver60k80k.ptstage2_rpn_train.pt。
其中stage1经过是分别采用了ImageNet分类任务上训练好的模型进展regionproposal的学习以及fasterrcnn检测的学习stage2那么是在stage1已经训练好的模型的根底上进展进一步的学习。
faster_rcnn_end_to_end就是端到端的训练方法使用起来更加简单所以我们这一小节会使用faster_rcnn_end_to_end方法目录下只包括了train.prototxttest.prototxtsolver.prototxt。
当要在我们自己的数据集上完成检测任务的时候就可以建立与pascal_voc以及coco平级的目录。
2.5Lib目录
lib目录下包含了非常多的子目录包括datasetsfast_rcnnnmspycocotoolsroi_data_layerrpntransformutils这是fasterrcnn框架中很多方法的实现目录下面对其进展详细解读。
(1)utils目录
这是最根底的一个目录主要就是blob.py以及bbox.pyx。
blob.py用于将图像进展预处理包括减去均值缩放等操作然后封装到caffe的blob中。
foriinxrange(num_images):
imims[i]
blob[i,0:
im.shape[0],0:
im.shape[1],:
]im
channel_swap(0,3,1,2)
blobblob.transpose(channel_swap)
封装的核心代码如上首先按照图像的存储格式(H,W,C)进展赋值然后调整通道以及高宽的顺序这在我们使用训练好的模型进展预测的时候是必要的操作。
而且有的时候采用RGB格式进展训练有的使用采用BGR格式进展训练也需要做对应的调整。
bbox.pyx用于计算两个box集合的overlaps即重叠度。
一个输入是(N,4)形状的真值boxes一个输入是(K,4)形状的查询boxes输出为(N,K)形状即逐个box互相匹配的结果。
(2)datasets目录
datasets目录下有目录VOCdevkit-matlab-wrappertools和脚本coco.pypascal_voc.pyvoc_eval.pyfactory.pyds_util.pyimdb.py。
我们按照调用关系来看首先是ds_util.py它包含了一些最根底的函数比方unique_boxes函数可以通过不同尺度因子的缩放从一系列的框中获取不重复框的数组指标用于过滤重复框。
详细实现采用了hash的方法代码如下
vnp.array([1,1e3,1e6,1e9])
hashesnp.round(boxes*scale).dot(v).astype(np.int)
box的4个坐标与上面的v进展外积后转换为一个数再进展判断。
xywh_to_xyxyxyxy_to_xywh函数分别是框的两种表达形式的互相转换前者采用一个顶点坐标以及长宽表示矩形后者采用两个顶点坐标表示矩形各有用处。
validata_boxes函数用于去除无效框即超出边界或左右上下不知足几何关系的点比方右边顶点的x坐标小于左边顶点。
filer_small_boxes用于去掉过小的检测框。
接下来看imdb.py这是数据集类imdb的定义脚本非常重要。
从它的初始化函数_init_可以看出类成员变量包括数据集的名字self._name检测的类别名字self._classes与详细的数量self._num_classes候选区域的选取方法self._obj_proposerroi数据集self._roidb与它的指针self._roidb_handler候选框提取默认采用了selective_search方法。
roidb是它最重要的数据构造它是一个数组。
数组中的每一个元素其实就是一张图的属性以字典的形式存储它的假设干属性共4个key为boxesgt_overlapsgt_classesflipped。
候选框boxes就是一个图像中的假设干的box每一个box是一个4维的向量包含左上角以及右下角的坐标。
类别信息gt_classes就是对应boxes中各个box的类别信息。
真值gt_overlaps它的维度大小为boxes的个数乘以类别的数量可知存储的就是输入box以及真实标注之间的重叠度。
另外假如设置了变量flipped还可以存储该图像的翻转版本这就是一个镜像操作是最常用的数据增强操作。
roidb的生成调用了create_roidb_from_box_list函数它将输入的box_list添加到roidb中。
假如没有gt_roidb的输入那么就是下面的逻辑可见就是将boxes存入数据库中并初始化gt_overlapsgt_classes等变量。
boxesbox_list[i]
num_boxesboxes.shape[0]
overlapsnp.zeros((num_boxes,self.num_classes),dtypenp.float32)
overlapsscipy.sparse.csr_matrix(overlaps)
roidb.append({
boxes:
boxes,
gt_classes:
np.zeros((num_boxes,),dtypenp.int32),
gt_overlaps:
overlaps,
flipped:
False,
seg_areas:
np.zeros((num_boxes,),dtypenp.float32),
})
假如输入gt_roidb非空那么需要将输入的box与其进展比对计算得到gt_overlaps代码如下
ifgt_roidbisnotNoneandgt_roidb[i][boxes].size0:
gt_boxesgt_roidb[i][boxes]
gt_classesgt_roidb[i][gt_classes]
gt_overlapsbbox_overlaps(boxes.astype(np.float),gt_boxes.astype(np.float))
argmaxesgt_overlaps.argmax(axis1)
maxesgt_overlaps.max(axis1)
Inp.where(maxes0)[0]
overlaps[I,gt_classes[argmaxes[I]]]maxes[I]
将输入的boxes与数据库中boxes进展比对调用了bbox_overlaps函数。
比对完之后结果存入overlaps。
bbox_overlaps的结果overlaps是一个二维矩阵第一维大小等于输入boxes中的框的数量第二维就是类别数目所存储的每一个值就是与真实标注进展最正确匹配的结果即重叠度。
但是最后存储的时候调用了overlapsscipy.sparse.csr_matrix(overlaps)进展稀疏压缩因为其中大局部的值其实是空的一张图包含的类别数目有限。
还有一个变量gt_classes在从该函数创立的时候并未赋值即等于0因为这个函数是用于将从rpn框架中返回的框添加到数据库中并非是真实的标注。
当gt_classes非零讲明是真实的标注这样的数据集就是train或val数据集它们在一开场就被创立反之那么是test数据集。
gt_classes非零的样本以及为零的样本在数据集中是连续存储的。
该脚本中另一个重要的函数就是evaluate_recall这就是用于计算averageiou的函数。
它的输入包括candidate_boxes即候选框。
假设没有输入那么评估时取该roidb中的非真值box。
threholds即IoU阈值假如没有输入那么默认从0.5到0.95按照0.05的步长迭代。
area用于评估的面积大小阈值默认覆盖0到1e10的尺度尺度是指框的面积。
还有一个limit用于限制评估的框的数量。
返回平均召回率averagerecall每一个IoU重合度阈值下的召回向量设定的IoU阈值向量和所有的真值标签。
当进展评估的时候首先要按照上面设计的面积大小阈值得到有效的index。
max_gt_overlapsself.roidb[i][gt_overlaps].toarray().max(axis1)
gt_indsnp.where((self.roidb[i][gt_classes]0)
(max_gt_overlaps1))[0]
首先获得需要评估的index
gt_boxesself.roidb[i][boxes][gt_inds,:
]
得到对应的boxes
gt_areasself.roidb[i][seg_areas][gt_inds]
valid_gt_indsnp.where((gt_areasarea_range[0])
(gt_areasarea_range[1]))[0]
得到符合面积约束的index
gt_boxesgt_boxes[valid_gt_inds,:
]
num_poslen(valid_gt_inds)
记录符合条件的框的个数
计算重叠度的经过是对每一个真值box进展遍历寻找到与其重叠度最大的候选框得到各个真值box的被重叠度。
挑选其中被重叠度最高的真值box然后找到对应的与其重叠度最高的box得到了一组匹配以及相应的重叠度。
标记这两个box后续的迭代不再使用然后循环计算直到所有的真值框被遍历完毕。
pascal_voc.py以及coco.py就是利用上面的几个脚本来创立对应这两个数据集的格式用于后续对模型的测试下面就是pascalvoc的数据库的创立经过。
def_load_pascal_annotation(self,index):
LoadimageandboundingboxesinfofromXMLfileinthePASCALVOC
format.
filenameos.path.join(self._data_path,Annotations,index.xml)
treeET.parse(filename)
objstree.findall(object)
ifnotself.config[use_diff]:
non_diff_objs[
objforobjinobjsifi