亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

Faster RCNN代碼理解(Python) ---訓練過程

2019-11-06 07:50:06
字體:
來源:轉載
供稿:網友

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

目錄

目錄第一步準備第二步Stage 1 RPN init from ImageNet model在config參數的基礎上改動參數以適合當前任務主要有初始化化caffe準備roidb和imdb設置輸出路徑output_dir get_output_dirimdb函數在config中用來保存中間生成的caffemodule等正式開始訓練保存最后得到的權重參數第三步Stage 1 RPN generate PRoposals關注rpn_generate函數保存得到的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代碼文件夾說明toolsRPNnms參考原文地址

第一步,準備

從train_faster_rcnn_alt_opt.py入:

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

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


第二步,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()123456789101112123456789101112

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

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

cfg.TRAIN.HAS_RPN = Truecfg.TRAIN.BBOX_REG = False  # applies only to Fast R-CNN bbox regressioncfg.TRAIN.PROPOSAL_METHOD = 'gt'123123

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

2. 初始化化caffe

3. 準備roidb和imdb

主要涉及到的函數get_roidb 在get_roidb函數中調用factory中的get_imdb根據__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:(…)_如果想要訓練自己的數據,需要修改這里_    class _to _ind:{…} _一個將類名轉換成下標的字典 _  建立索引0,1,2....    image _ext:’.jpg’    image _index: [‘000001’,’000003’,……]_根據trainval.txt獲取到的image索引_    roidb _handler: <Method gt_roidb >    salt:  <Object uuid >    comp _id:’comp4’    config:{…}}12345678910111213141234567891011121314

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

imdb.set_proposal_method(cfg.TRAIN.PROPOSAL_METHOD)11

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

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

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

return roidb,imdb11

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

5.正式開始訓練

model_paths = train_net(solver, roidb, output_dir,                        pretrained_model=init_model,                        max_iters=max_iters)123123

調用train中的train_net函數,其中,首先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。在這里,就需要去實例化每個層,在這個階段,首先就會實現ROIlayer,詳細參考layer中的setup,在訓練時roilayer的forward函數,在第一個層,只需要進行數據拷貝,在不同的階段根據prototxt文件定義的網絡結構拷貝數據,blobs = self._get_next_minibatch()這個函數讀取圖片數據(調用get_minibatch函數,這個函數在minibatch中,主要作用是為faster rcnn做實際的數據準備,在讀取數據的時候,分出了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’,這些數據準備都在minibatch中。至此后數據便在caffe中流動了,直到訓練結束。畫出網絡的結構 這里只截取了一部分:這里寫圖片描述 值得注意的是在rpn-data層使用的是AnchorTargetLayer,該層使用Python實現的,往后再介紹。

6.保存最后得到的權重參數

rpn_stage1_out = mp_queue.get()11

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


第三步,Stage 1 RPN, generate proposals

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

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()1234567891012345678910

1.關注rpn_generate函數

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

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

至此,得到imdb proposal

2.保存得到的proposal文件

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

至此,Stage 1 RPN, generate proposals結束


第四步,Stage 1 Fast R-CNN using RPN proposals, 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[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()1234567891011121312345678910111213

這一步,用上一步生成的proposal,以及imagenet模型M0來訓練fast-rcnn模型M2。 關注train_fast_rcnn 同樣地,會設置參數,這里注意cfg.TRAIN.PROPOSAL_METHOD = ‘rpn’ 不同于前面,后面調用的將是rpn_roidb。cfg.TRAIN.IMS_PER_BATCH = 2,每個mini-batch包含兩張圖片,以及它們proposal的roi區域。且在這一步是有rpn_file的(后面和rpn_roidb函數使用有關)。其他的和前面差不多。提一下,這里在train_net的時候,會調用add_bbox_regression_targets位于roidb中,主要是添加bbox回歸目標,即添加roidb的‘bbox_targets’屬性,同時根據cfg中的參數設定,求取bbox_targets的mean和std,因為需要訓練class-specific regressors在這里就會涉及到bbox_overlaps函數,放在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的靜態方法【這里不太懂,需要再學習下】,把rpn_roidb和gt_roidb歸并為一個roidb,在這里,需要具體去了解合并的基本原理。這里寫圖片描述


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

參數:

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()1234567891012345678910

這部分就是利用模型M2練rpn網絡,這一次與stage1的rpn網絡不通,這一次conv層的參數都是不動的,只做前向計算,訓練得到模型M3,這屬于微調了rpn網絡。這里寫圖片描述


第六步,Stage 2 RPN, generate proposals

參數:

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()1234567891012345678910

這一步,基于上一步得到的M3模型,產生proposal P2,網絡結構和前面產生proposal P1的一樣。 這里寫圖片描述


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

參數:

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()1234567891011121312345678910111213

這一步基于模型M3和P2訓練fast rcnn得到最終模型M4,這一步,conv層和rpn都是參數固定,只是訓練了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)12345671234567

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


AnchorTargetLayer和ProposalLayer

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

class AnchorTargetLayer(caffe.Layer)11

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

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

調用generate_anchors方法生成最初始的9個anchor該函數位于generate_anchors.py 主要功能是生成多尺度,多寬高比的anchors,8,16,32其實就是scales:[2^3 2^4 2^5],base_size為16,具體是怎么實現的可以查閱源代碼。_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,如下圖所示:這里寫圖片描述 另外一個函數就是forward()。 在faster rcnn中會根據不同圖的輸入,得到不同的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,在這里,你會發現,例如你得到的fm是H=61,W=36,然后你乘以16,得到的圖形大概就是1000*600,其實這個16大概就是網絡的縮放比例。接下來就是生成anchor,以及對anchor做一定的篩選,詳見代碼。

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

# 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)12345678910111234567891011

在這個函數中會引用NMS方法。


代碼文件夾說明

[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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九精品在线播放| 欧美大片在线看免费观看| 国产乱肥老妇国产一区二| 欧美日韩国产成人高清视频| 国产亚洲欧美另类中文| 日韩电影中文字幕一区| 国产欧美精品一区二区三区-老狼| 久久精品国产亚洲精品2020| 欧美日韩精品二区| 欧美成人免费在线视频| 欧美在线一级视频| 成人高h视频在线| 亚洲精品自在久久| 午夜美女久久久久爽久久| 成人精品一区二区三区| 成人国产精品一区| 久久久久久伊人| 欧美亚洲成人精品| 国产精品成人一区二区| 国产91精品久久久久久| 欧美黑人xxxⅹ高潮交| 国产免费一区二区三区香蕉精| 69av在线视频| 国产精品入口尤物| 亚洲性日韩精品一区二区| 国产91免费看片| 久久激情视频免费观看| 国产精品吊钟奶在线| 久久精品国产久精国产一老狼| 操91在线视频| 久久久久久中文字幕| 不卡av在线播放| 欧美精品福利在线| 日韩中文字幕在线免费观看| 91精品啪在线观看麻豆免费| 欧美成人网在线| 久久青草福利网站| 亚洲午夜激情免费视频| 国产综合色香蕉精品| 欧美精品aaa| 最好看的2019年中文视频| 日本一区二区在线免费播放| 亚洲男人的天堂网站| 91sa在线看| 日韩午夜在线视频| 欧美激情亚洲视频| 亚洲变态欧美另类捆绑| 国产精品r级在线| 97国产一区二区精品久久呦| 国产欧美最新羞羞视频在线观看| 久久97精品久久久久久久不卡| 97精品国产97久久久久久| 主播福利视频一区| 亚洲理论在线a中文字幕| 91av视频在线观看| 国产伊人精品在线| 91久热免费在线视频| 欧美专区在线观看| 国产精品久久久久福利| 91性高湖久久久久久久久_久久99| 国内成人精品一区| 亚洲一区二区久久久| 欧美精品性视频| 久久99精品国产99久久6尤物| 福利视频一区二区| 亚洲性线免费观看视频成熟| 国产欧美久久一区二区| 国产精品欧美一区二区三区奶水| 亚洲在线免费看| 热草久综合在线| 欧美色欧美亚洲高清在线视频| 中文字幕日韩在线播放| 日韩在线观看免费全集电视剧网站| 91国产美女视频| 亚洲国产天堂久久综合网| 日韩免费看的电影电视剧大全| 欧美国产日产韩国视频| 96pao国产成视频永久免费| 久久精品中文字幕| 亚洲欧美中文字幕| 欧日韩在线观看| 国产91在线视频| 91sao在线观看国产| 91国产精品91| 久久最新资源网| 国产成人一区二| 中文字幕精品www乱入免费视频| 日韩美女视频免费在线观看| 精品调教chinesegay| 亚洲精品电影网站| 日韩精品在线观看一区二区| 国语自产精品视频在线看| 蜜臀久久99精品久久久无需会员| 国产精品视频最多的网站| 国内精品久久久| 日韩精品日韩在线观看| 91九色蝌蚪国产| 日韩精品极品在线观看播放免费视频| 国产精品日日做人人爱| 爱福利视频一区| 精品久久久久人成| 97精品久久久中文字幕免费| 欧美高清第一页| 中国日韩欧美久久久久久久久| 久久久久久久久久久av| 亚洲国产精品va在线观看黑人| 国产精品久久久久久婷婷天堂| 伦理中文字幕亚洲| 91精品在线观| 欧美黑人视频一区| 国产精品久久久久久久久影视| 亚洲精品国产精品自产a区红杏吧| 91精品国产自产在线观看永久| 国产91av在线| 国产精品视频在线播放| 精品国产乱码久久久久久天美| 国产精品午夜国产小视频| 久久久国产精品一区| 日韩成人中文字幕在线观看| 欧美国产精品va在线观看| 亚洲免费伊人电影在线观看av| 欧美亚洲免费电影| 成人综合国产精品| 日韩大片免费观看视频播放| 91福利视频网| 国产一区香蕉久久| 色中色综合影院手机版在线观看| 成人a免费视频| 中日韩美女免费视频网址在线观看| 中文字幕亚洲第一| 亚洲电影免费观看高清| 亚洲综合成人婷婷小说| 亚洲男人天堂视频| 日本中文字幕不卡免费| 亚洲成人黄色网址| 亚洲欧美日韩成人| 欧美日韩成人网| 国产69精品久久久久9999| 精品激情国产视频| 国产精品中文久久久久久久| 久久人人爽人人爽人人片亚洲| 久久韩剧网电视剧| 欧美乱大交做爰xxxⅹ性3| 精品久久久久久中文字幕大豆网| 91久久精品国产91性色| 精品亚洲一区二区三区在线播放| 亚洲精品自产拍| 亚洲欧美999| 97视频在线免费观看| 亚洲一品av免费观看| 国产精品久久久久久av下载红粉| 国产精品久久久久久久久粉嫩av| 久久久精品在线观看| 亚洲第一黄色网| 国产精品精品国产| 91精品久久久久久综合乱菊| 国产精品欧美日韩久久| 97视频免费看| 欧美重口另类videos人妖| 成人羞羞国产免费| 亚洲精品欧美日韩专区| 97免费中文视频在线观看| 91精品久久久久久久久久久| 亚洲国产精品嫩草影院久久|