日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Faster RCNN代码理解(Python) ---训练过程

發(fā)布時間:2024/9/21 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Faster RCNN代码理解(Python) ---训练过程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近開始學習深度學習,看了下Faster RCNN的代碼,在學習的過程中也查閱了很多其他人寫的博客,得到了很大的幫助,所以也打算把自己一些粗淺的理解記錄下來,一是記錄下自己的菜鳥學習之路,方便自己過后查閱,二來可以回饋網(wǎng)絡。目前編程能力有限,且是第一次寫博客,中間可能會有一些錯誤。

目錄

  • 目錄
      • 第一步準備
      • 第二步Stage 1 RPN init from ImageNet model
        • 在config參數(shù)的基礎上改動參數(shù)以適合當前任務主要有
        • 初始化化caffe
        • 準備roidb和imdb
        • 設置輸出路徑output_dir get_output_dirimdb函數(shù)在config中用來保存中間生成的caffemodule等
        • 正式開始訓練
        • 保存最后得到的權重參數(shù)
      • 第三步Stage 1 RPN generate proposals
        • 關注rpn_generate函數(shù)
        • 保存得到的proposal文件
      • 第四步Stage 1 Fast R-CNN using RPN proposals init from ImageNet model
      • 第五步Stage 2 RPN init from stage 1 Fast R-CNN model
      • 第六步Stage 2 RPN generate proposals
      • 第七步Stage 2 Fast R-CNN init from stage 2 RPN R-CNN model
      • 第八步輸出最后模型
      • AnchorTargetLayer和ProposalLayer
      • 代碼文件夾說明
        • tools
        • RPN
        • nms
      • 參考
      • 原文地址

第一步,準備

從train_faster_rcnn_alt_opt.py入:

  • 初始化參數(shù):args = parse_args() 采用的是Python的argparse?
    主要有–net_name,–gpu,–cfg等(在cfg中只是修改了幾個參數(shù),其他大部分參數(shù)在congig.py中,涉及到訓練整個網(wǎng)絡)。
  • cfg_from_file(args.cfg_file) 這里便是代用config中的函數(shù)cfg_from_file來讀取前面cfg文件中的參數(shù),同時調用_merge_a_into_b函數(shù)把所有的參數(shù)整合,其中__C = edict() cfg = __C cfg是一個詞典(edict)數(shù)據(jù)結構。
  • faster rcnn采用的是多進程,mp_queue是進程間用于通訊的數(shù)據(jù)結構
  • import multiprocessing as mp mp_queue = mp.Queue()
    • 1
    • 2
    • 1
    • 2

    同時solvers, max_iters, rpn_test_prototxt = get_solvers(args.net_name)得到solver參數(shù)
    接下來便進入了訓練的各個階段。


    第二步,Stage 1 RPN, init from ImageNet model

    cfg.TRAIN.SNAPSHOT_INFIX = 'stage1' mp_kwargs = dict(queue=mp_queue,imdb_name=args.imdb_name,init_model=args.pretrained_model,solver=solvers[0],max_iters=max_iters[0],cfg=cfg) p = mp.Process(target=train_rpn, kwargs=mp_kwargs) p.start() rpn_stage1_out = mp_queue.get() p.join()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    可以看到第一個步驟是用ImageNet的模型M0來Finetuning RPN網(wǎng)絡得到模型M1。以訓練為例,這里的args參數(shù)都在腳本 experiments/scrips/faster_rcnn_alt_opt.sh中找到。主要關注train_rpn函數(shù)。
    對于train_rpn函數(shù),主要分一下幾步:

    1.在config參數(shù)的基礎上改動參數(shù),以適合當前任務,主要有

    cfg.TRAIN.HAS_RPN = True cfg.TRAIN.BBOX_REG = False # applies only to Fast R-CNN bbox regression cfg.TRAIN.PROPOSAL_METHOD = 'gt'
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    這里,關注proposal method 使用的是gt,后面會使用到gt_roidb函數(shù),重要。

    2. 初始化化caffe

    3. 準備roidb和imdb

    主要涉及到的函數(shù)get_roidb?
    在get_roidb函數(shù)中調用factory中的get_imdb根據(jù)__sets[name]中的key(一個lambda表達式)轉到pascol_voc類。class pascal_voc(imdb)在初始化自己的時候,先調用父類的初始化方法,例如:

    {year:’2007’image _set:’trainval’devkit _path:’data/VOCdevkit2007’data _path:’data /VOCdevkit2007/VOC2007’classes:(…)_如果想要訓練自己的數(shù)據(jù),需要修改這里_class _to _ind:{…} _一個將類名轉換成下標的字典 _ 建立索引0,1,2....image _ext:’.jpg’image _index: [‘000001’,’000003’,……]_根據(jù)trainval.txt獲取到的image索引_roidb _handler: <Method gt_roidb >salt: <Object uuid >comp _id:’comp4’config:{…} }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意,在這里,并沒有讀入任何數(shù)據(jù),只是建立了圖片的索引。

    imdb.set_proposal_method(cfg.TRAIN.PROPOSAL_METHOD)
    • 1
    • 1

    設置proposal方法,接上面,設置為gt,這里只是設置了生成的方法,第一次調用發(fā)生在下一句,roidb = get_training_roidb(imdb) –> append_flipped_images()時的這行代碼:“boxes = self.roidb[i][‘boxes’].copy()”,其中get_training_roidb位于train.py,主要實現(xiàn)圖片的水平翻轉,并添加回去。實際是該函數(shù)調用了imdb. append_flipped_images也就是在這個函數(shù),調用了pascal_voc中的gt_roidb,轉而調用了同一個文件中的_load_pascal_annotation,該函數(shù)根據(jù)圖片的索引,到Annotations這個文件夾下去找相應的xml標注數(shù)據(jù),然后加載所有的bounding box對象,xml的解析到此結束,接下來是roidb中的幾個類成員的賦值:

    • boxes 一個二維數(shù)組,每一行存儲 xmin ymin xmax ymax
    • gt _classes存儲了每個box所對應的類索引(類數(shù)組在初始化函數(shù)中聲明)
    • gt _overlap是一個二維數(shù)組,共有num _classes(即類的個數(shù))行,每一行對應的box的類索引處值為1,其余皆為0,后來被轉成了稀疏矩陣
    • seg _areas存儲著某個box的面積
    • flipped 為false 代表該圖片還未被翻轉(后來在train.py里會將翻轉的圖片加進去,用該變量用于區(qū)分

    最后將這些成員變量組裝成roidb返回。?
    在get_training_roidb函數(shù)中還調用了roidb中的prepare_roidb函數(shù),這個函數(shù)就是用來準備imdb 的roidb,給roidb中的字典添加一些屬性,比如image(圖像的索引),width,height,通過前面的gt _overla屬性,得到max_classes和max_overlaps.
    至此,

    return roidb,imdb
    • 1
    • 1

    4. 設置輸出路徑,output_dir = get_output_dir(imdb),函數(shù)在config中,用來保存中間生成的caffemodule等

    5.正式開始訓練

    model_paths = train_net(solver, roidb, output_dir,pretrained_model=init_model,max_iters=max_iters)
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    調用train中的train_net函數(shù),其中,首先filter_roidb,判斷roidb中的每個entry是否合理,合理定義為至少有一個前景box或背景box,roidb全是groudtruth時,因為box與對應的類的重合度(overlaps)顯然為1,也就是說roidb起碼要有一個標記類。如果roidb包含了一些proposal,overlaps在[BG_THRESH_LO, BG_THRESH_HI]之間的都將被認為是背景,大于FG_THRESH才被認為是前景,roidb 至少要有一個前景或背景,否則將被過濾掉。將沒用的roidb過濾掉以后,返回的就是filtered_roidb。在train文件中,需要關注的是SolverWrapper類。詳細見train.py,在這個類里面,引入了caffe SGDSlover,最后一句self.solver.NET.layers[0].set_roidb(roidb)將roidb設置進layer(0)(在這里就是ROILayer)調用ayer.py中的set_roidb方法,為layer(0)設置roidb,同時打亂順序。最后train_model。在這里,就需要去實例化每個層,在這個階段,首先就會實現(xiàn)ROIlayer,詳細參考layer中的setup,在訓練時roilayer的forward函數(shù),在第一個層,只需要進行數(shù)據(jù)拷貝,在不同的階段根據(jù)prototxt文件定義的網(wǎng)絡結構拷貝數(shù)據(jù),blobs = self._get_next_minibatch()這個函數(shù)讀取圖片數(shù)據(jù)(調用get_minibatch函數(shù),這個函數(shù)在minibatch中,主要作用是為faster rcnn做實際的數(shù)據(jù)準備,在讀取數(shù)據(jù)的時候,分出了boxes,gt_boxes,im_info(寬高縮放)等)。
    第一個層,對于stage1_rpn_train.pt文件中,該layer只有3個top blob:’data’、’im_info’、’gt_boxes’。?
    對于stage1_fast_rcnn_train.pt文件中,該layer有6個top blob:top: ‘data’、’rois’、’labels’、’bbox_targets’、’bbox_inside_weights’、’bbox_outside_weights’,這些數(shù)據(jù)準備都在minibatch中。至此后數(shù)據(jù)便在caffe中流動了,直到訓練結束。
    畫出網(wǎng)絡的結構?這里只截取了一部分:
    ?
    值得注意的是在rpn-data層使用的是AnchorTargetLayer,該層使用Python實現(xiàn)的,往后再介紹。

    6.保存最后得到的權重參數(shù)

    rpn_stage1_out = mp_queue.get()
    • 1
    • 1

    至此,第一階段完成,在后面的任務開始時,如果有需要,會在這個輸出的地址找這一階段得到的權重文件。


    第三步,Stage 1 RPN, generate proposals

    這一步就是調用上一步訓練得到的模型M1來生成proposal P1,在這一步只產生proposal,參數(shù):

    mp_kwargs = dict(queue=mp_queue,imdb_name=args.imdb_name,rpn_model_path=str(rpn_stage1_out['model_path']),cfg=cfg,rpn_test_prototxt=rpn_test_prototxt) p = mp.Process(target=rpn_generate, kwargs=mp_kwargs) p.start() rpn_stage1_out['proposal_path'] = mp_queue.get()['proposal_path'] p.join()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.關注rpn_generate函數(shù)

    前面和上面講到的train_rpn基本相同,從rpn_proposals = imdb_proposals(rpn_net, imdb)開始,imdb_proposals函數(shù)在rpn.generate.py文件中,rpn_proposals是一個列表的列表,每個子列表。對于imdb_proposals,使用im = cv2.imread(imdb.image_path_at(i))讀入圖片數(shù)據(jù),調用 im_proposals生成單張圖片的rpn proposals,以及得分。這里,im_proposals函數(shù)會調用網(wǎng)絡的forward,從而得到想要的boxes和scores,這里需要好好理解blobs_out = net.forward(data,im_info)中net forward和layer forward間的調用關系。?
    ?
    在這里,也會有proposal,同樣會使用Python實現(xiàn)的ProposalLayer,這個函數(shù)也在rpn文件夾內,后面再補充。

    boxes = blobs_out['rois'][:, 1:].copy() / scale scores = blobs_out['scores'].copy() return boxes, scores
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    至此,得到imdb proposal

    2.保存得到的proposal文件

    queue.put({'proposal_path': rpn_proposals_path}) rpn_stage1_out['proposal_path'] = mp_queue.get()['proposal_path']
    • 1
    • 2
    • 1
    • 2

    至此,Stage 1 RPN, generate proposals結束


    第四步,Stage 1 Fast R-CNN using RPN proposals, init from ImageNet model

    參數(shù):

    cfg.TRAIN.SNAPSHOT_INFIX = 'stage1' mp_kwargs = dict(queue=mp_queue,imdb_name=args.imdb_name,init_model=args.pretrained_model,solver=solvers[1],max_iters=max_iters[1],cfg=cfg,rpn_file=rpn_stage1_out['proposal_path']) p = mp.Process(target=train_fast_rcnn, kwargs=mp_kwargs) p.start() fast_rcnn_stage1_out = mp_queue.get() p.join()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    這一步,用上一步生成的proposal,以及imagenet模型M0來訓練fast-rcnn模型M2。?
    關注train_fast_rcnn?
    同樣地,會設置參數(shù),這里注意cfg.TRAIN.PROPOSAL_METHOD = ‘rpn’ 不同于前面,后面調用的將是rpn_roidb。cfg.TRAIN.IMS_PER_BATCH = 2,每個mini-batch包含兩張圖片,以及它們proposal的roi區(qū)域。且在這一步是有rpn_file的(后面和rpn_roidb函數(shù)使用有關)。其他的和前面差不多。提一下,這里在train_net的時候,會調用add_bbox_regression_targets位于roidb中,主要是添加bbox回歸目標,即添加roidb的‘bbox_targets’屬性,同時根據(jù)cfg中的參數(shù)設定,求取bbox_targets的mean和std,因為需要訓練class-specific regressors在這里就會涉及到bbox_overlaps函數(shù),放在util.bbox中。?
    要注意的是在這一步get_roidb時,如前所說,使用的是rpn_roidb,會調用imdb. create_roidb_from_box_list該方法功能是從box_list中讀取每張圖的boxes,而這個box_list就是從上一步保存的proposal文件中讀取出來的,然后做一定的處理,詳細見代碼,重點是在最后會返回roidb,rpn_roidb中的gt_overlaps是rpn_file中的box與gt_roidb中box的gt_overlaps等計算IoU等處理后得到的,而不像gt_roidb()方法生成的gt_roidb中的gt_overlaps全部為1.0。同時使用了imdb.merge_roidb,類imdb的靜態(tài)方法【這里不太懂,需要再學習下】,把rpn_roidb和gt_roidb歸并為一個roidb,在這里,需要具體去了解合并的基本原理。


    第五步,Stage 2 RPN, init from stage 1 Fast R-CNN model

    參數(shù):

    cfg.TRAIN.SNAPSHOT_INFIX = 'stage2' mp_kwargs = dict(queue=mp_queue,imdb_name=args.imdb_name,init_model=str(fast_rcnn_stage1_out['model_path']),solver=solvers[2],max_iters=max_iters[2],cfg=cfg) p = mp.Process(target=train_rpn, kwargs=mp_kwargs) rpn_stage2_out = mp_queue.get()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    這部分就是利用模型M2練rpn網(wǎng)絡,這一次與stage1的rpn網(wǎng)絡不通,這一次conv層的參數(shù)都是不動的,只做前向計算,訓練得到模型M3,這屬于微調了rpn網(wǎng)絡。


    第六步,Stage 2 RPN, generate proposals

    參數(shù):

    mp_kwargs = dict(queue=mp_queue,imdb_name=args.imdb_name,rpn_model_path=str(rpn_stage2_out['model_path']),cfg=cfg,rpn_test_prototxt=rpn_test_prototxt) p = mp.Process(target=rpn_generate, kwargs=mp_kwargs) p.start() rpn_stage2_out['proposal_path'] = mp_queue.get()['proposal_path'] p.join()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    這一步,基于上一步得到的M3模型,產生proposal P2,網(wǎng)絡結構和前面產生proposal P1的一樣。?


    第七步,Stage 2 Fast R-CNN, init from stage 2 RPN R-CNN model

    參數(shù):

    cfg.TRAIN.SNAPSHOT_INFIX = 'stage2' mp_kwargs = dict(queue=mp_queue,imdb_name=args.imdb_name,init_model=str(rpn_stage2_out['model_path']),solver=solvers[3],max_iters=max_iters[3],cfg=cfg,rpn_file=rpn_stage2_out['proposal_path']) p = mp.Process(target=train_fast_rcnn, kwargs=mp_kwargs) p.start() fast_rcnn_stage2_out = mp_queue.get() p.join()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    這一步基于模型M3和P2訓練fast rcnn得到最終模型M4,這一步,conv層和rpn都是參數(shù)固定,只是訓練了rcnn層(也就是全連接層),與stage1不同,stage1只是固定了rpn層,其他層還是有訓練。模型結構與stage1相同:


    第八步,輸出最后模型

    final_path = os.path.join(os.path.dirname(fast_rcnn_stage2_out['model_path']),args.net_name + '_faster_rcnn_final.caffemodel') print 'cp {} -> {}'.format(fast_rcnn_stage2_out['model_path'], final_path) shutil.copy(fast_rcnn_stage2_out['model_path'], final_path) print 'Final model: {}'.format(final_path)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    只是對上一步模型輸出的一個拷貝。?
    至此,整個faster-rcnn的訓練過程就結束了。


    AnchorTargetLayer和ProposalLayer

    前面說過還有這兩個層沒有說明,一個是anchortarget layer一個是proposal layer,下面逐一簡要分析。

    class AnchorTargetLayer(caffe.Layer)
    • 1
    • 1

    首先是讀取參數(shù),在prototxt,實際上只讀取了param_str: “‘feat_stride’: 16”,這是個很重要的參數(shù),目前我的理解是滑塊滑動的大小,對于識別物體的大小很有用,比如小物體的識別,需要把這個參數(shù)減小等。
    首先 setup部分,

    anchor_scales = layer_params.get('scales', (8, 16, 32)) self._anchors = generate_anchors(scales=np.array(anchor_scales))
    • 1
    • 2
    • 1
    • 2

    調用generate_anchors方法生成最初始的9個anchor該函數(shù)位于generate_anchors.py 主要功能是生成多尺度,多寬高比的anchors,8,16,32其實就是scales:[2^3 2^4 2^5],base_size為16,具體是怎么實現(xiàn)的可以查閱源代碼。_ratio_enum()部分生成三種寬高比 1:2,1:1,2:1的anchor如下圖所示:(以下參考另外一篇博客)
    ?
    _scale_enum()部分,生成三種尺寸的anchor,以_ratio_enum()部分生成的anchor[0 0 15 15]為例,擴展了三種尺度 128*128,256*256,512*512,如下圖所示:
    ?
    另外一個函數(shù)就是forward()。?
    在faster rcnn中會根據(jù)不同圖的輸入,得到不同的feature map,height, width = bottom[0].data.shape[-2:]首先得到conv5的高寬,以及gt box gt_boxes = bottom[1].data,圖片信息im_info = bottom[2].data[0, :],然后計算偏移量,shift_x = np.arange(0, width) * self._feat_stride,在這里,你會發(fā)現(xiàn),例如你得到的fm是H=61,W=36,然后你乘以16,得到的圖形大概就是1000*600,其實這個16大概就是網(wǎng)絡的縮放比例。接下來就是生成anchor,以及對anchor做一定的篩選,詳見代碼。

    另外一個需要理解的就是proposal layer,這個只是在測試的時候用,許多東西和AnchorTargetLayer類似,不詳細介紹,可以查看代碼。主要看看forward函數(shù),函數(shù)算法介紹在注釋部分寫的很詳細:

    # Algorithm: # for each (H, W) location i # generate A anchor boxes centered on cell i # apply predicted bbox deltas at cell i to each of the A anchors # clip predicted boxes to image # remove predicted boxes with either height or width < threshold # sort all (proposal, score) pairs by score from highest to lowest # take top pre_nms_topN proposals before NMS # apply NMS with threshold 0.7 to remaining proposals # take after_nms_topN proposals after NMS # return the top proposals (-> RoIs top, scores top)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在這個函數(shù)中會引用NMS方法。


    代碼文件夾說明

    轉載出處:另外一篇博客

    tools

    在tools文件夾中,是我們直接調用的最外層的封裝文件。其中主要包含的文件為:

    • _init_paths.py?:用來初始化路徑的,也就是之后的路徑會join(path,*)
    • compress_net.py:用來壓縮參數(shù)的,使用了SVD來進行壓縮,這里可以發(fā)現(xiàn),作者對于fc6層和fc7層進行了壓縮,也就是兩個全連接層。
    • demo.py?:通常,我們會直接調用這個函數(shù),如果要測試自己的模型和數(shù)據(jù),這里需要修改。這里調用了fast_rcnn中的test、config、nums_wrapper函數(shù)。vis_detections用來做檢測,parse_args用來進行參數(shù)設置,以及damo和主函數(shù)。
    • eval_recall.py:評估函數(shù)
    • reval.py:re-evaluate,這里調用了fast_rcnn以及dataset中的函數(shù)。其中,from_mats函數(shù)和from_dets函數(shù)分別loadmat文件和pkl文件。
    • rpn_genetate.py:這個函數(shù)調用了rpn中的genetate函數(shù),之后我們會對rpn層做具體的介紹。這里,主要是一個封裝調用的過程,我們在這里調用配置的參數(shù)、設置rpn的test參數(shù),以及輸入輸出等操作。
    • test_net.py:測試fast rcnn網(wǎng)絡。主要就是一些參數(shù)配置。
    • train_faster_rcnn_alt_opt.py:訓練faster rcnn網(wǎng)絡使用交替的訓練,這里就是根據(jù)faster rcnn文章中的具體實現(xiàn)。可以在主函數(shù)中看到,其包括的步驟為:
      • RPN 1,使用imagenet model進行初始化參數(shù),生成proposal,這里存儲在mp_kwargs
      • fast rcnn 1,使用 imagenet model 進行初始化參數(shù),使用剛剛生成的proposal進行fast rcnn的訓練
      • RPN 2使用 fast rcnn 中的參數(shù)進行初始化(這里要注意哦),并生成proposal
      • fast rcnn 2,使用RPN 2 中的 model進行初始化參數(shù)
      • 值得注意的是:在我們訓練時,我們可以在get_solvers中的max_iters中設置迭代次數(shù),在不確定網(wǎng)絡是否可以調通時,減少迭代次數(shù)可以減少測試時間。
      • 我們在訓練faster rcnn網(wǎng)絡時,就是調用這個文件訓練的
    • train_net.py:使用fast rcnn,訓練自己數(shù)據(jù)集的網(wǎng)絡模型
    • train_svms.py:使用最原始的RCNN網(wǎng)絡訓練post-hoc SVMs

    RPN

    這里我們主要看lib/rpn文件夾下的代碼。這里主要介紹了rpn的模型,其中,包含的主要文件如下:

    • generate_anchors.py: 生成多尺度和多比例的錨點。這里由generate_anthors函數(shù)主要完成,可以看到,使用了 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:這個函數(shù)是用來將RPN的輸出轉變?yōu)閛bject proposals的。作者新增了ProposalLayer類,這個類中,重新了set_up和forward函數(shù),其中forward實現(xiàn)了:生成錨點box、對于每個錨點提供box的參數(shù)細節(jié)、將預測框切成圖像、刪除寬、高小于閾值的框、將所有的(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函數(shù)功能:在每一個cell中,生成9個錨點,提供這9個錨點的細節(jié)信息,過濾掉超過圖像的錨點,測量同GT的overlap。
    • proposal_target_layer.py:對于每一個object proposal 生成訓練的目標和標簽,分類標簽從0-k,對于標簽>0的box進行回歸。(注意,同anchor_target_layer.py不同,兩者一個是生成anchor,一個是生成proposal)
    • generate.py:使用一個rpn生成object proposals。

    作者就是通過以上這些文件生成rpn的。

    nms

    lib/nms文件夾下是非極大值抑制,這部分大家應該已經非常熟悉了,其python版本的核心函數(shù)為py_cpu_nms.py,具體實現(xiàn)以及注釋如下:

    def py_cpu_nms(dets, thresh):"""Pure Python NMS baseline."""#x1、y1、x2、y2、以及score賦值x1 = dets[:, 0]y1 = dets[:, 1]x2 = dets[:, 2]y2 = dets[:, 3]scores = dets[:, 4]#每一個op的面積areas = (x2 - x1 + 1) * (y2 - y1 + 1)#order是按照score排序的order = scores.argsort()[::-1]keep = []while order.size > 0:i = order[0]keep.append(i)xx1 = np.maximum(x1[i], x1[order[1:]])yy1 = np.maximum(y1[i], y1[order[1:]])xx2 = np.minimum(x2[i], x2[order[1:]])yy2 = np.minimum(y2[i], y2[order[1:]])#計算相交的面積w = np.maximum(0.0, xx2 - xx1 + 1)h = np.maximum(0.0, yy2 - yy1 + 1)inter = w * h#計算:重疊面積/(面積1+面積2-重疊面積)ovr = inter / (areas[i] + areas[order[1:]] - inter)inds = np.where(ovr <= thresh)[0]order = order[inds + 1]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    參考

    在這里,沒有貼出代碼的注釋,只是梳理了下Faster RCNN訓練的流程,因為代碼的注釋網(wǎng)絡上已經有很多,需要看代碼的注釋可以參考下面幾個博客,我看代碼的時候也有參考:
    [1]?http://www.cnblogs.com/CarryPotMan/p/5390336.html
    [2]?http://blog.csdn.net/u010668907/article/category/6237110?
    [3]?http://blog.csdn.net/sunyiyou9/article/category/6269359?
    [4]?http://blog.csdn.net/bailufeiyan/article/details/50749694

    原文地址:

    http://blog.csdn.net/u011956147/article/details/53053381

    繼fasterrcnn后,又一個pva-fasterrcnn的配置教程,希望可以幫助大家。若不能配置成功,請與我聯(lián)系,郵箱:ahuljx@126.com

    注意:有些復制的終端命令如果不能在終端運行,請注意英文全角半角問題,可以將命令輸入終端,無須復制粘貼命令


    第一部分:下載并編譯pvanet
    1、終端輸入:
    Git?clone --recursive https://github.com/sanghoon/pva-faster-rcnn.git
    2、建立Cython模塊:
    這個地方很容易錯,缺什么下載什么就能解決啦,出現(xiàn)問題的小伙伴可以來群里討論哈,很多問題我當時沒有記錄,所以來群里討論討論就行啦,群號你懂得
    cd $pva-faster-rcnn/lib
    make –j16(為啥用16相信大家也很清楚啦)
    3、編譯caffe及pycaffe
    cd $pva-faster-rcnn/caffe-fast-rcnn
    cp Makefile.config.example Makefile.config
    修改Makefile.config文件:
    去掉cudnn前面#(我用cudnn4.0,僅供參考
    Opencv_version不用注釋(我用的2.4.10,3.0沒有測試過,所以不用注釋
    BLAS=atlas(我測試的庫,mkl沒有試過)(sudo apt-get install libatlas-base-dev即可安裝)
    去掉with_python_layer前面的#,注意一定要去掉,不然無法訓練數(shù)據(jù)(測試的時候不需要)

    修改后保存退出

    make –j16
    make pycaffe –j16


    第二部分:下載預訓練模型(外網(wǎng)真心慢啊
    為小伙伴們提供百度網(wǎng)盤下載鏈接:
    鏈接:http://pan.baidu.com/s/1kVRRPDd 密碼:1cdt
    1、打開文件將test.model放入$pva-faster-rcnn/models/pvanet/full/這個目錄下
    2、將test(1).model重命名為test.model放入$pva-faster-rcnn/models/pvanet/comp/目錄下
    其他的模型我就沒有去試驗啦,后續(xù)有時間就會更新這些模型的訓練方法的


    第三部分:下載voc07數(shù)據(jù)

    打開終端(任何目錄)輸入:
    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

    解壓(嚴格按照此順序):
    tar xvf VOCtrainval_06-Nov-2007.tar
    tar xvf VOCtest_06-Nov-2007.tar
    tar xvf VOCdevkit_08-Jun-2007.tar

    將生成的VOCdevkit文件夾更名為VOCdevkit2007移動至$pva-faster-rcnn/data/目錄下面


    第四部分:voc07測試預訓練模型

    終端輸入:
    cd $pva-faster-rcnn
    1、full/test.model測試:
    ./tools/test_net.py --gpu 0 --def models/pvanet/full/test.pt --net models/pvanet/full/test.model --cfg models/pvanet/cfgs/submit_160715.yml
    2、Comp/test.model測試:
    ./tools/test_net.py --gpu 0 --def models/pvanet/comp/test.pt --net models/pvanet/comp/test.model --cfg models/pvanet/cfgs/submit_160715.yml
    此測試會得到系列類別的AP值


    第五部分:預訓練model訓練并測試voc07數(shù)據(jù)
    終端輸入:
    1、訓練:
    cd $pva-faster-rcnn
    ./tools/train_net.py --gpu 0 --solver models/pvanet/example_finetune/solver.prototxt --weights models/pvanet/full/test.model –iters 100000 --cfg models/pvanet/cfgs/train.yml –imdb voc_2007_trainval(其他參數(shù)默認)
    訓練結果會在pva根目錄生成output文件夾,模型就在里面
    2、測試:
    ./tools/test_net.py --gpu 0 --def models/pvanet/example_finetune/test.prototxt --net output/faster_rcnn_pavnet/voc_2007_trainval/pvanet_frcnn_iter_100000.caffemodel --cfg models/pvanet/cfgs/submit_160715.yml?(其他參數(shù)默認)


    第六部分:預訓練model
    訓練并測試自己數(shù)據(jù)
    1、數(shù)據(jù)制作:
    還記得fasterrcnn數(shù)據(jù)如何制作的嗎?參考博客http://blog.csdn.NET/samylee/article/details/51201744
    Tips:參考voc07的數(shù)據(jù)格式,我們可發(fā)現(xiàn),生成的數(shù)據(jù)最后只需保留Annotations、ImageSets和JPEGImages三個文件夾即可,ImageSets/Main文件中用到的只有trainval.txt和test.txt這兩個文件(數(shù)據(jù)分布:trainval=train+val,all_data=trainval+test),多類別如果增加負樣本或模糊樣本可以考慮1、0及-1操作(其中1表示有目標,0表示模糊目標,-1表示沒有目標
    數(shù)據(jù)集制作完成后將這三個文件夾復制至一個文件夾(命名為VOC2007)當中,再移動至$pva-faster-rcnn/data/VOCdevkit2007中,替換原來的VOC2007

    2、類別設置:(有幾類設置幾類,類似fasterrcnn,我的數(shù)據(jù)集為1類行人數(shù)據(jù))

    1)打開文件/models/pvanet/example_finetune/train.prototxt

    num_classes:2(開頭處)(我實驗時一類)

    2)修改lib/datasets/pascal_voc.py

    self._classes = ('__background__', # always index 0
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??'people')(只有這一類)

    3)修改lib/datasets/imdb.py

    數(shù)據(jù)整理,在一行代碼為 ?boxes[:, 2] = widths[i] - oldx1 - 1 下加入代碼:
    ?for b in range(len(boxes)):

    ? ? ? if boxes[b][2]< boxes[b][0]:

    ? ? ? ? ?boxes[b][0] = 0

    4)修改完pascal_voc.py和imdb.py后進入lib/datasets目錄下刪除原來的pascal_voc.pyc和imdb.pyc文件,重新生成這兩個文件,因為這兩個文件是python編譯后的文件,系統(tǒng)會直接調用。

    終端進入lib/datasets文件目錄輸入:

    python(此處應出現(xiàn)python的版本)

    >>>import py_compile

    >>>py_compile.compile(r'imdb.py')

    >>>py_compile.compile(r'pascal_voc.py')

    3、訓練數(shù)據(jù):
    cd $pva-faster-rcnn
    ./tools/train_net.py --gpu 0 --solver models/pvanet/example_finetune/solver.prototxt --weights models/pvanet/full/test.model –iters 100000 --cfg models/pvanet/cfgs/train.yml –imdb voc_2007_trainval
    (其他參數(shù)默認)
    4、測試模型:
    ./tools/test_net.py --gpu 0 --def models/pvanet/example_finetune/test.prototxt --net output/faster_rcnn_pavnet/voc_2007_trainval/pvanet_frcnn_iter_100000.caffemodel --cfg models/pvanet/cfgs/submit_160715.yml?(其他參數(shù)默認)


    第七部分:實驗結果

    目前我訓練了10000左右,loss為0.1左右,其他四個參數(shù)分別在0.2、0.1、0.01、0.01左右
    后續(xù)工作可做demo演示程序,小伙伴們盡請期待!

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的Faster RCNN代码理解(Python) ---训练过程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。