视频检测
Faster R-CNN运行及实时性DEMO测试
http://cdn2.jianshu.io/p/eb8491b79d3e
https://github.com/manutdzou/KITTI_FRC_detection
本项目以VGG_CNN_M_1024为例,训练数据为KITTI
本项目所有路径为/home/bsl/KITTI_FRC_detection,在不同电脑上需要修改路径
1. 网络模型
网络模型在/models/VGG_CNN_M_1024/faster_rcnn_alt_opt中,4个training stage,运行draw_net.sh可以画出每个步骤的网络图,需要在draw_net.py中添加正确的pycaffe路径
2. 数据
下载KITTI数据,解压到data中,数据目录为data/training/image_2/...
ImageList_Version_S_AddData.txt为所有数据列表,ImageList_Version_S_GT_AddData.txt为所有数据的不同类别的groundtruth,格式为 "image_path object_num class1_num coordinates class2_num coordinates..." 如果某一类数量为0则class_num为0,coordinates空缺,例如"training/image_2/000240.png 1 1 567.32 177.55 609.97 215.63 0 0" 表示000240.png一共有一个物体,第一类物体一个x_left,y_left,x_right,y_right为"567.32 177.55 609.97 215.63",第二类和第三类没有物体。
data/format_KITTI.py可以用来生成对应格式的list列表和真值,需要修改部分参数和路径。
所有数据标签做好以后生成train和val数据集,利用Matlab的split_data.m生成KITTI_train_list.txt,KITTI_gt_train.txt和KITTI_val_list.txt,KITTI_gt_val.txt,选用70%作为训练数据,30%作为测试数据。
3. 模型
在imagenet_models下载fine_tune的模型VGG_CNN_M_1024.v2.caffemodel,下载命令/scripts/fetch_imagenet_models.sh. 在lib/rpn/generate_anchors.py中设置7个ratios和10个scales共70个anchors,所以模型文件中rpn_cls_score的num_output为140, 2(bg/fg) * 70(anchors),rpn_bbox_pred的num_output为280, 4 * 70(anchors).需要注意test过程中rpn_cls_prob_reshape层的channels应该设为和rpn_cls_score的num_output一致。
4. 生成数据库
数据库接口在lib/datasets/中,注意修改绝对路径。不同于原有的VOC数据格式接口读取xml,该数据接口实现将txt的图片路径和图片真值框列表读入.pkl
5. 算法评估工具
算法评估工具在VOCdevkit-matlab-wrapper中,写了一个KITTI的评估工具,衡量标准为AP值,该工具集成到了python程序中由Python调用matlab.也可以单独由检测生成的/data/results/中的./txt利用main.m直接产生结果(需要自己填写参数)。在data/results中可以生成对应类别的所有检测结果图片,TP和FP的结果图片以供分析。
detection_eval.m为算法评估主程序,这里定义了三个类classes={'car','person','bike'},minoverlap=0.2,建议在一般情况下将读写图片注释掉,因为读写过程比较慢。
6. tools里自己写的工具说明
demo_location.py主要将检测结果记录在txt里,这个接口是为我们的私有数据写的,在这里没有使用。
demo_show.py主要实现将检测结果和真值框同时显示在图片上并将图片保存到data/results/show里面。由于show文件夹没有写成自动建立,需要自建(实在没时间做程序优化啊,见谅啊)。
demo_for_video.py主要实现将视频帧存储的连续图片检测然后做成视频格式,视频格式可自选,默认格式大小最适合。
demo_video_for_video.py顾名思义是读视频然后检测写入视频咯,注意需要将视频放在申明的位置。
train_debug.py和test_net_debug.py主要为了在pycharm中调试使用,此时需要将参数全部写入。
7. 参数设置
参数设置主要在lib/fast_rcnn/config.py中__C.TRAIN.SCALES = (370,300,250,200,150)表示训练多尺度的样本,__C.TRAIN.MAX_SIZE = 1250表示样本最大边长,其他batch_size,IOU等都可以在这里设置。
8. 训练
可以直接在终端运行train.sh调用experiments/scripts/faster_rcnn_alt_opt.sh训练网络,经过4个80000次训练获得网络模型和测试结果。你将最终获得APs: Car:88.6, Person:73.0, Bike: 69.5
另外在model中增加了VGG-16的网络模型
If you have any problems or find some bugs, please contact with manutdzou@126.com and feel free. Thank you again for your observation.
http://blog.csdn.net/u010402786/article/details/72675831
一 工程目录
在github上clone下来的代码,可以看到根目录下有以下几个文件夹,其中output为训练完之后才会有的文件夹。
-
caffe-fast-rcnn ,这里是caffe框架目录;
-
data,用来存放pretrained模型,比如imagenet上的,以及读取文件的cache缓存;
-
experiments,存放配置文件以及运行的log文件,另外这个目录下有scripts可以用end2end或者alt_opt两种方式训练;
-
lib,用来存放一些python接口文件,如其下的datasets主要负责数据库读取,config负责cnn一些训练的配置选项;
-
models,里面存放了三个模型文件,小型网络的ZF,大型网络VGG16,中型网络VGG_CNN_M_1024。推荐使用VGG16,如果使用端到端的approximate joint training方法,开启CuDNN,只需要3G的显存即;
-
output,这里存放的是训练完成后的输出目录,默认会在faster_rcnn_end2end文件夹下;
-
tools,里面存放的是训练和测试的Python文件。
二 训练方式
- Alternative training(alt-opt)
-
Approximate joint training(end-to-end)
推荐使用第二种,因为第二种使用的显存更小,而且训练会更快,同时准确率差不多,两种方式需要修改的代码是不一样的,同时faster rcnn提供了三种训练模型,小型的ZFmodel,中型的VGG_CNN_M_1024和大型的VGG16,论文中说VGG16效果比其他两个好,但是同时占用更大的GPU显存(~11GB)
三 训练代码
cd py-faster-rcnn
./experiments/scripts/faster_rcnn_alt_opt.sh 0 VGG16 pascal_voc
# 第一块GPU(0) 模型是VGG16 数据集时pascal_voc
cd $FRCN_ROOT
./experiments/scripts/faster_rcnn_end2end.sh [GPU_ID] [NET] [--set ...]
python ./tools/train_net.py --gpu 1 --solver models/pascal_voc/VGG_CNN_M_1024/faster_rcnn_end2end/solver.prototxt --weights data/imagenet_models/VGG_CNN_M_1024.v2.caffemodel --imdb voc_2012_trainval --iters 70000 --cfg experiments/cfgs/faster_rcnn_end2end.yml
问题1:如何在同一张图像中画出不同种类对应颜色的目标框?
修改demo.py中的代码,代码如下:
`# Visualize detections for each class
CONF_THRESH = 0.7
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, :]
#draw
#vis_detections(im, cls, dets, thresh=CONF_THRESH)
font = cv2.FONT_HERSHEY_SIMPLEX
color = (0,0,0)
if cls_ind == 1: #motorbike
color = (0, 0, 255)
elif cls_ind == 2: #car
color = (0, 255, 0)
elif cls_ind == 3: #bus
color = (255, 0, 0)
else: #truck
color = (255, 255, 255)
inds = np.where(dets[:, -1] >= CONF_THRESH)[0]
if len(inds) > 0:
for i in inds:
bbox = dets[i, :4]
score = dets[i, -1]
cv2.rectangle(im,(bbox[0], bbox[1]), (bbox[2], bbox[3]), color, 2)
cv2.putText(im,'{:s} {:.3f}'.format(cls, score),(bbox[0], (int)((bbox[1]- 2))), font, 0.5, (0,255,0), 1)
# Display the resulting frame
cv2.imshow('{:s}'.format(image_name),im)`
四 场景应用
问题1:如果想检测小的物体,应该怎么办?
解答:改变anchor_target_layer 和proposal_layer层的参数,[链接在此]
scales: decrease these values to account for smaller boxes
ratios: adjust them depending on the shape of your grount-truth boxes
feat_stride : supposedly this can be modified to improve accuracy of the generated anchors
问题2:如何实时的进行视频的检测?(#578)
解答: 需要修改原代码demo.py,代码如下
while True:
demo_video(net,cv2.VideoCapture(videoFilePath))
def demo_video(net, videoFile):
global frameRate
# Load the demo image
ret, im = videoFile.read()
# 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])
frameRate = 1.0/timer.total_time
print "fps: " + str(frameRate)
# Visualize detections for each class
CONF_THRESH = 0.65
NMS_THRESH = 0.2
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, :]
im=vis_detections_video(im, cls, dets, thresh=CONF_THRESH)
cv2.putText(im,'{:s} {:.2f}'.format("FPS:", frameRate(1750,50),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255))
cv2.imshow(videoFilePath.split('/')[len(videoFilePath.split('/'))-1],im)
cv2.waitKey(20)
问题3:如何针对小的目标检测?(#443)
针对一个大图像中的小目标进行检测,需要修改anchor的参数,具体的文件:generate_anchors.py
from this:
def generate_anchors(base_size=16, ratios=[0.5, 1, 2], scales=2**np.arange(3, 6)):
To this:
def generate_anchors(base_size=16, ratios=[0.3, 0.75, 1], scales=2**np.arange(3, 6)):
五 训练问题
问题1:训练完成的模型,但是使用原图却检测不到任何结果?
原因:很有可能标注的时候的label超出了图像的边界。推荐两个验证标注的方式:[check the boxes] 和最新版本的LabelImg。
问题2:如何去训练一个RPN模型(#364)
首先需要知道alt_opt是如何工作的:
- Train RPN
- Write down the RPN
- Train Fast-RCNN using the generated RPNs
- Repeat 1-3 again for optimising weights for RPN & Fast-RCNN
然后,只需做1-2步即可生成proposals. 可视化这些proposals可以将
lib/rpn/generate.py中的visualisation置为1。
问题3:faster-rcnn如何使用多GPU进行训练
首先答案是否定的,python不支持多GPU训练。但也有相关的解决方案:
1. https://github.com/315386775/py-R-FCN-multiGPU 这个分支支持多GPU
2. mxnet可以支持多GPU训练
0526更新
问题4:训练时出现bbox_loss为0的问题
问题对应的链接如下:[loss为0的问题]
六 训练日志
在$FRCNN_ROOT的experiments/script中有脚本可以查看:faster_rcnn_end2end.sh
LOG="experiments/logs/faster_rcnn_end2end_${NET}_${EXTRA_ARGS_SLUG}.txt.`date +'%Y-%m-%d_%H-%M-%S'`"
浙公网安备 33010602011771号