Caffe學(xué)習(xí)筆記8:Faster R-CNN運(yùn)行及實(shí)時(shí)性DEMO測(cè)試

faster-rcnn:Fast Region-based Convolutional Neural Networks基于區(qū)域的卷積神經(jīng)網(wǎng)絡(luò)

http://blog.csdn.net/column/details/ym-alanyannick.html

先感謝敖川學(xué)長給我提供練手的電腦在岂!
前面都學(xué)習(xí)CNN在圖像分類上的巨大優(yōu)勢(shì)和應(yīng)用,但是要把CNN用作目標(biāo)檢測(cè)改怎么實(shí)現(xiàn)蔽午,困擾了我很久。學(xué)了幾天先作個(gè)筆記及老。
在Faster R-CNN之前還有R-CNN和Fast R-CNN。既然Faster R-CNN是前面的改進(jìn)写半,我就先學(xué)Faster R-CNN尉咕。

如有錯(cuò)誤請(qǐng)指正叠蝇!

理論部分

在學(xué)習(xí)目標(biāo)檢測(cè)之前,我就想象CNN怎么用作目標(biāo)檢測(cè)年缎。第一想法是將圖像切割送入網(wǎng)絡(luò)中。RCNN就是類是滑動(dòng)窗的東西進(jìn)行操作:
1.提取建議區(qū)域
2.利用CNN對(duì)建議區(qū)域進(jìn)行分類

  • 提取建議區(qū)域方法的發(fā)展:1.滑動(dòng)窗口 2.select search/edge box 3.rpn(Region Proposal Network)
  • 其他深度學(xué)習(xí)檢測(cè)策略,利用CNN強(qiáng)大表述能力直接對(duì)目標(biāo)位置進(jìn)行回歸,例如YOLO

R-CNN、Fast R-CNN瘾腰、Faster R-CNN三者關(guān)系


image.png
SPP Net

一般CNNs后解full-connect layer或者classifier费薄,他們都需要固定的輸入尺寸硝全。因此不得不對(duì)輸入數(shù)據(jù)進(jìn)行crop(修剪)或warp(彎曲),這些預(yù)處理會(huì)造成數(shù)據(jù)丟失或幾何學(xué)上的失真楞抡。SPP Net的第一個(gè)貢獻(xiàn)是將空間金字塔的思想加入到CNNs中伟众,實(shí)現(xiàn)了數(shù)據(jù)的多尺度輸入。

image.png

如圖拌倍,在卷積層和全連接層之間加入SPP layer赂鲤。此時(shí)網(wǎng)絡(luò)的輸入可以是任意尺寸,在SPP layer中每一個(gè)pooling的filter會(huì)根據(jù)輸入調(diào)整大小柱恤,而SPP的輸出尺寸始終是固定的数初。
在R-CNN中,每個(gè)proposed region先rescale成統(tǒng)一大小梗顺,然后分別作為CNNs的輸入泡孩,這樣是很低效的。
在SPP Net中寺谤,只對(duì)原圖進(jìn)行一次卷積得到整張圖的feature map仑鸥,然后找到每個(gè)proposed region在feature map上的映射patch,將此patch作為每個(gè)proposed region的卷積特征輸入到SPP layer和之后的層变屁。節(jié)省了大量的計(jì)算時(shí)間眼俊,比R-CNN有一百倍左右的加速。

Fast R-CNN整體結(jié)構(gòu)
image.png

如圖粟关,F(xiàn)ast R-CNN的網(wǎng)絡(luò)有兩個(gè)輸出層疮胖,一個(gè)softmax,一個(gè)bbox regressor(相對(duì)的R-CNN,SPP Net中分類和回歸是兩個(gè)部分闷板,這里集成在了同一個(gè)網(wǎng)絡(luò)中)澎灸。而且加入了一個(gè)RoI pooling layer(類似于一個(gè)尺度的SPP layer)。注意:Fast R-CNN提取建議區(qū)域的方法依然是select search遮晚。

  • RoI pooling layer
    這是SPP pooling的一個(gè)簡化版本性昭,可以看做是只有一個(gè)尺度 filter的‘金字塔’。輸入是N個(gè)整幅圖的feature map和一組R個(gè)RoI(proposed region)县遣。每個(gè)特征映射都是HWC糜颠,每個(gè)RoI是一個(gè)元組(n,r萧求,c括蝠,h,w)饭聚,n是特征映射的索引忌警,r,c,h法绵,w分別是RoI的左上角坐標(biāo)和高與寬箕速。輸出是max-pooling過得特征映射H’xW’xC,如上圖中紅色框線朋譬。
Faster-RCNN整體框架
image.png

Faster R-CNN的主要貢獻(xiàn)是設(shè)計(jì)了提取建議區(qū)域的網(wǎng)絡(luò)Region Proposal Network(RPN)盐茎。代替了費(fèi)時(shí)的select search,使檢測(cè)速度大為提高徙赢。下圖為Faster R-CNN的結(jié)構(gòu)圖字柠,黃色部分為RPN,可以看出除了RPN狡赐,其它部分繼承了FR-CNN的結(jié)構(gòu)

RPN整體結(jié)構(gòu)
image.png

RPN的網(wǎng)絡(luò)結(jié)構(gòu)類似于FR-CNN窑业,連接與最后卷基層輸出的feature map,有一個(gè)RoI層枕屉,兩個(gè)輸出層常柄,一個(gè)輸出滑窗為建議區(qū)域的概率,另一個(gè)輸出bbox回歸的offset搀擂。其訓(xùn)練方式也類似于FR-CNN西潘。注意:RPN與FR-CNN共用卷積層。

image.png

RPN通過一個(gè)滑動(dòng)窗口(圖中紅色框)連接在最后一個(gè)卷積層輸出的feature map上哨颂,然后通過全連接層調(diào)整到256-d的向量喷市,作為輸出層的輸入。同時(shí)每個(gè)滑動(dòng)窗對(duì)應(yīng)k個(gè)anchor boxes威恼,在論文中使用3個(gè)尺寸和3個(gè)比例的3*3=9個(gè)anchor品姓。每個(gè)anchor對(duì)應(yīng)原圖上一個(gè)感受野,通過這種方法提高scale-invariant沃测。

Multi-task loss
image.png

FR-CNN的有兩個(gè)網(wǎng)絡(luò)輸出層,將原來與網(wǎng)絡(luò)分開的bbox regression的操作整合在了網(wǎng)絡(luò)中食茎。并設(shè)計(jì)了一個(gè)同時(shí)優(yōu)化兩個(gè)輸出層的loss函數(shù)蒂破。

image.png
RoI-centric sampling與Image-centric sampling
  • RoI-centric sampling:從所有圖片的所有RoI中隨機(jī)均勻取樣,這樣每個(gè)SGD的mini-batch中包含了不同圖像中的樣本(SPP Net采用)别渔。SPP Net的反向傳播沒有到SPP pooling之前的層附迷,因?yàn)榉聪騻鞑バ枰?jì)算每一個(gè)RoI感受野的卷基層,通常會(huì)覆蓋整幅圖像哎媚,又慢又耗內(nèi)存喇伯。FR-CNN想要解決這個(gè)限制。
  • Image-centric sampling:mini-batch采用分層采樣拨与,先對(duì)圖像采樣稻据,再對(duì)RoI采樣。將采樣的RoI限定在個(gè)別圖像內(nèi)买喧,這樣同一圖像的RoI共享計(jì)算和內(nèi)存捻悯。通過這種策略匆赃,實(shí)現(xiàn)了端到端的反向傳播,可以fine-tuning整個(gè)網(wǎng)絡(luò)今缚。

為了使共用的卷積層在訓(xùn)練RPN和FR-CNN時(shí)都會(huì)收斂算柳,論文里設(shè)計(jì)了一個(gè)四步訓(xùn)練的策略:

  • (1):對(duì)RPN進(jìn)行end-to-end的訓(xùn)練,這里網(wǎng)絡(luò)使用ImageNet pre-trained model進(jìn)行初始化姓言。
  • (2):使用第一步RPN生成的建議區(qū)域訓(xùn)練FR-CNN瞬项,這里也使用ImageNet pre-trained model進(jìn)行初始化。
  • (3):使用上一步FR-CNN的參數(shù)初始化RPN何荚,固定卷基層囱淋,只fine-tune RPN獨(dú)有的層。(在此步已共享卷積層)
  • (4):固定卷基層兽泣,只fine-tune FR-CNN獨(dú)有的層绎橘。
訓(xùn)練時(shí)采用的一些策略與參數(shù)設(shè)置

訓(xùn)練樣本選擇方法與其參數(shù)設(shè)置

Fast-RCNN中參數(shù)的設(shè)置
    ims_per_batch 1或2
    batch_size 128
    每個(gè)batch中正樣本占得比率。  fg_fraction 0.25
    與GT的IOU大于閾值0.6的ROI作為正樣本唠倦。  fg_thresh=0.6
    與GT的IOU在閾值0.1到0.5之間的ROI作為負(fù)樣本称鳞。bg_thresh_hi=0.5、bg_thresh_lo=0.1

實(shí)現(xiàn)部分

參考:http://blog.csdn.net/u012177034/article/details/52288835

1.下載py-faster-RCNN源碼
git clone --recursive https://github.com/rbgirshick/py-faster-rcnn
2.編譯lib庫
cd $FRCN_ROOT/lib
make
3.編譯caffe

這部分巨惡心稠鼻,由于py-faster-rcnn編寫時(shí)的caffe版本很老無法直接編譯,可以直接下載我提供的連接鏈接: https://pan.baidu.com/s/1pLkIFDx 密碼: sj9y冈止。我的配置為:GTX1070,CUDA8.0候齿,cuDNN6.5熙暴,i7

cd caffe-fast-rcnn  
git remote add caffe https://github.com/BVLC/caffe.git  
git fetch caffe  
git merge caffe/master
4.運(yùn)行demo
cd $FRCN_ROOT
./tools/demo.py
4.修改為視頻流demo

faster-rcnn的確實(shí)不能滿足實(shí)時(shí)性要求,fps在這配置下為8慌盯,延遲為0.5s左右
由于原代碼使用了matplotlib繪圖模塊周霉,每次顯示需要手動(dòng)關(guān)閉。如果要處理視頻還是使用opencv亚皂,但是opencv的參數(shù)與matplotlib不同需注意俱箱。
demo_vedio.py
需要改的地方在vis_detections()這個(gè)函數(shù)里
我直接把整個(gè)代碼貼上來

#!/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
from fast_rcnn.config import cfg
from fast_rcnn.test import im_detect
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

    for i in inds:
        bbox = dets[i, :4]
        score = dets[i, -1]
  
    font=cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(im, '{}>= {:.1f}'.format(class_name,thresh), (int(bbox[0]), int(bbox[3])), font, 1, (0,255,0), 2)
    cv2.rectangle(im,(int(bbox[0]), int(bbox[3])),(int(bbox[2]), int(bbox[1])),(0,255,0),5)
    cv2.imshow("im",im)
    
def demo(net, im):
    """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()

    prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
                            'faster_rcnn_alt_opt', 'faster_rcnn_test.pt')
    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)
        cfg.GPU_ID = args.gpu_id
    net = caffe.Net(prototxt, caffemodel, caffe.TEST)

    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)

    videoCapture = cv2.VideoCapture('/home/noneland/PycharmProjects/Train0707/BR2.avi') 
    success, im = videoCapture.read()
    while success :
        demo(net, im)
        success, im = videoCapture.read() 
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    videoCapture.release()
    cv2.destroyAllWindows()

很好的一張?jiān)韴D:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灭必,隨后出現(xiàn)的幾起案子狞谱,更是在濱河造成了極大的恐慌,老刑警劉巖禁漓,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跟衅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡播歼,警方通過查閱死者的電腦和手機(jī)伶跷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人撩穿,你說我怎么就攤上這事磷支。” “怎么了食寡?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵雾狈,是天一觀的道長。 經(jīng)常有香客問我抵皱,道長善榛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任呻畸,我火速辦了婚禮移盆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伤为。我一直安慰自己咒循,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布绞愚。 她就那樣靜靜地躺著叙甸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪位衩。 梳的紋絲不亂的頭發(fā)上裆蒸,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音糖驴,去河邊找鬼僚祷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贮缕,可吹牛的內(nèi)容都是我干的辙谜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼感昼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼装哆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抑诸,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤烂琴,失蹤者是張志新(化名)和其女友劉穎爹殊,沒想到半個(gè)月后蜕乡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梗夸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年层玲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辛块,死狀恐怖畔派,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情润绵,我是刑警寧澤线椰,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站尘盼,受9級(jí)特大地震影響憨愉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卿捎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一配紫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧午阵,春花似錦躺孝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至戚啥,卻和暖如春奋单,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猫十。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工览濒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拖云。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓贷笛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宙项。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乏苦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容