一、 Faster-RCNN代码解释

先看看代码结构:

Data:

This directory holds (after you download them):

  • Caffe models pre-trained on ImageNet
  • Faster R-CNN models
  • Symlinks to datasets
  • demo 5张图片
  • scripts 下载模型的脚本

Experiments:

  • logs
  • scripts/faster_rcnn_alt_opt.sh
  • cfgs/faster_rcnn_alt_opt.yml

存放配置文件以及运行的log文件,另外这个目录下有scripts可以用end2end或者alt_opt两种方式训练。

Lib

用来存放一些python接口文件,如其下的datasets主要负责数据库读取,config负责cnn一些训练的配置选项。

lib/rpn

这就是RPN的核心代码部分,有生成proposals和anchor的方法

generate_anchors.py
生成多尺度和多比例的锚点。这里由generate_anthors函数主要完成,可以看到,使用了 3 个尺度( 128, 256,
and 512)以及 3 个比例(1:1,1:2,2:1)。一个锚点由w, h, x_ctr, y_ctr固定,也就是宽、高、x center和y center固定。

proposal_layer.py
这个函数是用来将RPN的输出转变为object
proposals的。作者新增了ProposalLayer类,这个类中,重新了set_up和forward函数,其中forward实现了:生成锚点box、对于每个锚点提供box的参数细节、将预测框切成图像、删除宽、高小于阈值的框、将所有的(proposal, score) 对排序、获取 pre_nms_topN proposals、获取NMS 、获取 after_nms_topN proposals。(注:NMS,nonmaximum suppression,非极大值抑制)

anchor_target_layer.py
生成每个锚点的训练目标和标签,将其分类为1
(object), 0 (not object) , -1 (ignore).当label>0,也就是有object时,将会进行box的回归。其中,forward函数功能:在每一个cell中,生成9个锚点,提供这9个锚点的细节信息,过滤掉超过图像的锚点,测量同GT的overlap。

proposal_target_layer.py
对于每一个object proposal 生成训练的目标和标签,分类标签从0-k,对于标签>0的box进行回归。(注意,同anchor_target_layer.py不同,两者一个是生成anchor,一个是生成proposal)

generate.py
使用一个rpn生成object proposals。
lib/nms文件夹

做非极大抑制的部分,有gpu和cpu两种实现方式
py_cpu_nms.py
核心函数

lib/datasets文件夹
在这里修改读写数据的接口主要是datasets目录下
(1)factory.py
(2)imdb.py
(3)pascal_voc.py
(4)voc_eval.py

lib/fast_rcnn文件夹
主要存放的是python的训练和测试脚本,以及训练的配置文件config.py
(1)config.py
(2)nms_wrapper.py
(3)test.py
(4)train.py

lib/roi_data_layer文件夹
主要是一些ROI处理操作
(1)layer.py
(2)minibatch.py
(3)roidb.py

lib/utils文件夹
(1)blob.py
(2)timer.py

lib/transform文件夹

Models

里面存放了三个模型文件,小型网络的ZF,大型网络VGG16,中型网络VGG_CNN_M_1024。推荐使用VGG16,如果使用端到端的approximate joint training方法,开启CuDNN,只需要3G的显存即可。(1)fast_rcnn_test.pt
(2)rpn_test.pt
(3)stage1_rpn_train.pt
(4)stage1_fast_rcnn_train.pt
(5)stage2_rpn_train.pt
(6)stage2_fast_rcnn_train.pt

Tools

里面存放的是训练和测试的Python文件。

_init_paths.py
用来初始化路径的,也就是之后的路径会join(path,*)

compress_net.py
用来压缩参数的,使用了SVD来进行压缩,这里可以发现,作者对于fc6层和fc7层进行了压缩,也就是两个全连接层。

demo.py
通常,我们会直接调用这个函数,如果要测试自己的模型和数据,这里需要修改。这里调用了fast_rcnn中的test、config、nums_wrapper函数。vis_detections用来做检测,parse_args用来进行参数设置,以及damo和主函数。

eval_recall.py
评估函数

reval.py
re-evaluate,这里调用了fast_rcnn以及dataset中的函数。其中,from_mats函数和from_dets函数分别loadmat文件和pkl文件。

rpn_genetate.py
这个函数调用了rpn中的genetate函数,之后我们会对rpn层做具体的介绍。这里,主要是一个封装调用的过程,我们在这里调用配置的参数、设置rpn的test参数,以及输入输出等操作。

test_net.py
测试fast rcnn网络。主要就是一些参数配置。

train_faster_rcnn_alt_opt.py
训练faster rcnn网络使用交替的训练,这里就是根据faster rcnn文章中的具体实现。可以在主函数中看到,其包括的步骤为:
RPN 1,使用imagenet model进行初始化参数,生成proposal,这里存储在mp_kwargs
fast rcnn 1,使用 imagenet model 进行初始化参数,使用刚刚生成的proposal进行fast rcnn的训练
RPN 2使用 fast rcnn 中的参数进行初始化(这里要注意哦),并生成proposal
fast rcnn 2,使用RPN 2 中的 model进行初始化参数,

train_net.py
使用fast rcnn,训练自己数据集的网络模型。

train_svms.py
使用最原始的RCNN网络训练post-hoc SVMs。

Outputs

这里存放的是训练完成后的输出目录,默认会在faster_rcnn_end2end文件夹下。

我们对照官方的代码分析一下工作流程:

主程序是root/py-faster-rcnn/tools/demo.py

#!/usr/bin/env python

# --------------------------------------------------------
# Faster R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# -------------------------------------------------------- """
Demo script showing detections in sample images.
See README.md for installation instructions before running.
""" import _init_paths ##把root/py-faster-rcnn/lib文件的路径添加到系统和
##root/py-faster-rcnn/caffe-fast-rcnn/python文件路径添加系统
from fast_rcnn.config import cfg ##导入config配置文件,配置文件里面以easydict形式来
##添加参数,分为三个部分(train,test,misc)
##比如添加阈值,设定图片大小,是否开启RPN
from fast_rcnn.test import im_detect ##对图片进行resize,换成blobs,返回scores和boxes
from fast_rcnn.nms_wrapper import nms
from utils.timer import Timer
import matplotlib.pyplot as plt
import numpy as np
import scipy.io as sio
import caffe, os, sys, cv2
import argparse CLASSES = ('__background__',
'aeroplane', 'bicycle', 'bird', 'boat',
'bottle', 'bus', 'car', 'cat', 'chair',
'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant',
'sheep', 'sofa', 'train', 'tvmonitor') NETS = {'vgg16': ('VGG16',
'VGG16_faster_rcnn_final.caffemodel'),
'zf': ('ZF',
'ZF_faster_rcnn_final.caffemodel')} def vis_detections(im, class_name, dets, thresh=0.5):
"""Draw detected bounding boxes."""
inds = np.where(dets[:, -1] >= thresh)[0]
if len(inds) == 0:
return im = im[:, :, (2, 1, 0)]
fig, ax = plt.subplots(figsize=(12, 12))
ax.imshow(im, aspect='equal')
for i in inds:
bbox = dets[i, :4]
score = dets[i, -1] ax.add_patch(
plt.Rectangle((bbox[0], bbox[1]),
bbox[2] - bbox[0],
bbox[3] - bbox[1], fill=False,
edgecolor='red', linewidth=3.5)
)
ax.text(bbox[0], bbox[1] - 2,
'{:s} {:.3f}'.format(class_name, score),
bbox=dict(facecolor='blue', alpha=0.5),
fontsize=14, color='white') ax.set_title(('{} detections with '
'p({} | box) >= {:.1f}').format(class_name, class_name,
thresh),
fontsize=14)
plt.axis('off')
plt.tight_layout()
plt.draw() def demo(net, image_name):
"""Detect object classes in an image using pre-computed object proposals.""" # Load the demo image
im_file = os.path.join(cfg.DATA_DIR, 'demo', image_name)
im = cv2.imread(im_file) # Detect all object classes and regress object bounds
timer = Timer()
timer.tic()
scores, boxes = im_detect(net, im)
timer.toc()
print ('Detection took {:.3f}s for '
'{:d} object proposals').format(timer.total_time, boxes.shape[0]) # Visualize detections for each class
CONF_THRESH = 0.8
NMS_THRESH = 0.3
for cls_ind, cls in enumerate(CLASSES[1:]):
cls_ind += 1 # because we skipped background
cls_boxes = boxes[:, 4*cls_ind:4*(cls_ind + 1)]
cls_scores = scores[:, cls_ind]
dets = np.hstack((cls_boxes,
cls_scores[:, np.newaxis])).astype(np.float32)
keep = nms(dets, NMS_THRESH)
dets = dets[keep, :]
vis_detections(im, cls, dets, thresh=CONF_THRESH) def parse_args():
"""Parse input arguments."""
parser = argparse.ArgumentParser(description='Faster R-CNN demo')
parser.add_argument('--gpu', dest='gpu_id', help='GPU device id to use [0]',
default=0, type=int)
parser.add_argument('--cpu', dest='cpu_mode',
help='Use CPU mode (overrides --gpu)',
action='store_true')
parser.add_argument('--net', dest='demo_net', help='Network to use [vgg16]',
choices=NETS.keys(), default='vgg16') args = parser.parse_args() return args if __name__ == '__main__':
cfg.TEST.HAS_RPN = True # Use RPN for proposals args = parse_args() ##返回命令参数行,默认使用gpu和vgg16
##添加.pt文件,就是faster-rcnn的结构图
prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
'faster_rcnn_alt_opt', 'faster_rcnn_test.pt')
##添加.caffemodel文件,就是训练好的VGG16模型
caffemodel = os.path.join(cfg.DATA_DIR, 'faster_rcnn_models',
NETS[args.demo_net][1]) if not os.path.isfile(caffemodel):
raise IOError(('{:s} not found.\nDid you run ./data/script/'
'fetch_faster_rcnn_models.sh?').format(caffemodel)) if args.cpu_mode:
caffe.set_mode_cpu()
else:
caffe.set_mode_gpu()
caffe.set_device(args.gpu_id) ##默认开启0设备号的gpu
cfg.GPU_ID = args.gpu_id
net = caffe.Net(prototxt, caffemodel, caffe.TEST) ##加载caffe网络 print '\n\nLoaded network {:s}'.format(caffemodel) # Warmup on a dummy image
im = 128 * np.ones((300, 500, 3), dtype=np.uint8)
for i in xrange(2):
_, _= im_detect(net, im) ##使用(300, 500, 3)全为1的dummy图片进行预检测,保留网络参数
##具体过程如下:
##对dummy图片去均值,转换数据类型,然后用线性插值法resize成im_scale=2倍的图片,注意图片大小
##不能超过(600,1000,3)的边界。接着把(600,1000,3)形式的图片或图片集
##转化成(1,600,1000,3)的blobs,这里blobs的初始格式是取图片集的最大宽和高,且只有一张图片。
##把blobs格式转换成(1,3,600,1000)的形式;到这里为止,_get_image_blob返回blob和im_scale_factors=2.0
##_get_blobs返回dict形式的blobs和im_scale_factors,注意此时该blobs = {'data' : blob, 'rois' : None}
##上面的blobs就是我们要操作的最终dict;
##对该blobs添加blobs['im_info']栏,(600,1000,2),2是im_scales[0];
##将caffe网络的data输入项(1,3,224,224)reshape成 blobs['data']的形状,即(1,3,600,1000)
##把dict形式的blobs(3栏)搬移到dict形式的forward_kwargs(2栏),去掉了rois栏
##然后把forward_kwargs送进net里面进行前向运行,输出blobs_out;
##将net.blobs['rois'].data,即将训练后rois层输出的数据保存到rois,
##rois(104,5),将rois后四列缩小2倍回原来的图片规格,即相当于映射前放大2倍,映射后缩小2倍
##对blobs_out['cls_prob']训练后数据保存到scores,blobs_out['cls_prob']是使用softmax层训练的结果;
##得到的是分类的概率。
##blobs_out['bbox_pred']训练后数据保存到box_deltas,然后对boxes相对box_deltas进行转换和裁剪;
##boxes是roi层前的特征,box_deltas是fast-rcnn最终层后的特征,一个输入(104,5)一个输出(104,84);
##这里涉及到bounding box regression原理,具体细节看另外一篇博客,其实就是Foreground Anchors和GT的拟合靠近;
##上面注意boxes的后四列是框的四个点,而我们要转化成中心坐标,因此损失函数为预测的中心坐标和实际的平方函数
##把预测的中心值转换回boxes的形式,重命名为pred_boxes
##对pre_boxes进行裁剪,具体为负值变0,越界取边界
##最后im_detect函数返回scores(104,21)和pred_boxes(104,84)
im_names = ['000456.jpg', '000542.jpg', '001150.jpg',
'001763.jpg', '004545.jpg']
for im_name in im_names:
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
print 'Demo for data/demo/{}'.format(im_name)
demo(net, im_name)
##根据路径加载要测试的图片1(375,500,3),利用cv读取图片1;
##利用timer进行计时,
##调用im_detect函数对图片1进行分类和定位,即返回scores和boxes;预处理时把(375,500,3)reshape(600,800,3)
##打印对300个建议框进行检测(分类和回归)花费的时间;
##将4列box和1列类合并成5列,命名为dets;
##对每一个类进行nms(非极大值抑制)操作,nms的阈值为0.3,返回keep(内含26个数据的list),即26个框;
##dets取这26个框,然后调用vis_detections函数来画图;
##首先取分类得分大于0.5的行,如果没有大于0.5的行则认为该图不是类1,直接退出并进行类2的检测;
##如果有大于0.5的行,则根据box的四个角画出框和在框上标注类别和得分,注意CONF_THRESH = 0.8得分以上才画出来;
##加载图片2重复相应内容;
plt.show()

Faster RCNN算法demo代码解析的更多相关文章

  1. Faster RCNN算法训练代码解析(3)

    四个层的forward函数分析: RoIDataLayer:读数据,随机打乱等 AnchorTargetLayer:输出所有anchors(这里分析这个) ProposalLayer:用产生的anch ...

  2. Faster RCNN算法训练代码解析(1)

    这周看完faster-rcnn后,应该对其源码进行一个解析,以便后面的使用. 那首先直接先主函数出发py-faster-rcnn/tools/train_faster_rcnn_alt_opt.py ...

  3. Faster RCNN算法训练代码解析(2)

    接着上篇的博客,我们获取imdb和roidb的数据后,就可以搭建网络进行训练了. 我们回到trian_rpn()函数里面,此时运行完了roidb, imdb = get_roidb(imdb_name ...

  4. 第三十一节,目标检测算法之 Faster R-CNN算法详解

    Ren, Shaoqing, et al. “Faster R-CNN: Towards real-time object detection with region proposal network ...

  5. 【目标检测】Faster RCNN算法详解

    Ren, Shaoqing, et al. “Faster R-CNN: Towards real-time object detection with region proposal network ...

  6. faster rcnn test demo ---repaired for video input and save the image, label, score et al. into .mat format

    faster rcnn test demo ---repaired for video input and save the image, label, score et al. into .mat ...

  7. faster RCNN(keras版本)代码讲解(3)-训练流程详情

    转载:https://blog.csdn.net/u011311291/article/details/81121519 https://blog.csdn.net/qq_34564612/artic ...

  8. faster rcnn算法及源码及论文解析相关博客

    1. 通过代码理解faster-RCNN中的RPN http://blog.csdn.net/happyflyy/article/details/54917514 2. faster rcnn详解 R ...

  9. 新人如何运行Faster RCNN的tensorflow代码

    0.目的 刚刚学习faster rcnn目标检测算法,在尝试跑通github上面Xinlei Chen的tensorflow版本的faster rcnn代码时候遇到很多问题(我真是太菜),代码地址如下 ...

随机推荐

  1. SpringCloud学习笔记(一):SpringCloudt相关面试题

    什么是微服务? 看笔记二 微服务之间是如何独立通讯的? 服务与服务间采⽤轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API) SpringCloud和Dubbo有什么区别? Du ...

  2. PAT甲级——A1076 Forwards on Weibo

    Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may ...

  3. linux操作mysql命令快速手记 — 让手指跟上思考的速度(二)

    这一篇是<mysql内建命令快速手记>的姐妹篇,废话不再赘述,直接上干货,跟老铁慢慢品 1.mysql -hlocalhost -uroot -proot,-h,-u,-p分别代表ip,u ...

  4. 【CF285E】Positions in Permutations

    题目 刷水题涨信心 显然这是个广义容斥,我们现在算一下至少有\(i\)个完美数的方案数就好了 这\(1000\)的数据范围显然在暗示\(n^2\)的dp 我们注意到这个条件大概就是\(P_i=i-1\ ...

  5. elasticsearch 过滤器的种类

    elasticsearch之查询过滤 elasticsearch elastic-search xixicat 2月13日发布 推荐 1 推荐 收藏 2 收藏,289 浏览 序 本文主要记录es的查询 ...

  6. hiveUDF的使用

    在此自己总结下UDF的用法 1.首先最简单的UDF(普通用java扩充函数的方式,大多数简便函数可以用这个函数来实现,返回单个字段),其加强版UDGF据说对map一类数据类型有更好兼容,实现上略复杂 ...

  7. Ubuntu 卸载nvidia驱动

    1.切换为集成显卡 如果没有,那么先切换到字符界面 2.卸载驱动 sudo apt-get --purge remove nvidia* sudo apt autoremove To remove C ...

  8. BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化

    我会告诉你我看了很久很久才把题目看懂吗???怀疑智商了 原来他给的l,r还有k个数字都是下标... 比如给了一个样例 l, r, k, x1,x2,x3...xk,代表的是一个数组num[l]~num ...

  9. JSOI 2016 扭动的字符串

    JSOI 2016 扭动的字符串 题面描述 给出两个长度为\(n\)的字符串\(A,B\) \(S(i,j,k)\)表示把\(A\)中的\([i,j]\)和\(B\)中的\([j,k]\)拼接起来的字 ...

  10. Kubernetes架构介绍

    目录 Kubernetes架构 k8s架构图 一.K8S Master节点 API Server Scheduler Controller Manager ETCD 二.K8S Node节点 Kube ...