1抵窒、從train_faster_rcnn_alt_opt.py文件開(kāi)始路克,入口函數(shù)if __name__ =='__main__':
(1)首先状土,通過(guò)args = parse_args()函數(shù)從命令行讀取參數(shù)瘤缩,然后判斷命令行參數(shù)cfg_file(配置文件),如果cfg_file是一個(gè)文件牢硅,那么利用cfg_from_file函數(shù)將cfg_file里面的數(shù)據(jù)合并到cofig.py文件中蹬耘,實(shí)際上就是用cfg_file更新cofig.py里面的變量的默認(rèn)值,如果cfg_file是一個(gè)列表减余,那么使用cfg_from_list函數(shù)去更新cofig.py
(2)創(chuàng)建一個(gè)進(jìn)程综苔,然后使用get_solvers(args.net_name)函數(shù)得到四部訓(xùn)練過(guò)程中的參數(shù)值prototxt文件、迭代次數(shù)位岔、rpn_test.pt的絕對(duì)路徑如筛。
2、下面開(kāi)始第一個(gè)階段的訓(xùn)練:Stage 1 RPN, init from ImageNet model(假設(shè)使用的是voc2007數(shù)據(jù)集抒抬,基礎(chǔ)網(wǎng)絡(luò)是ZF網(wǎng)絡(luò))
配置訓(xùn)練函數(shù)train_rpn所需要的參數(shù)杨刨,然后將train_rpn放入進(jìn)程中,下面來(lái)看train_rpn函數(shù):
首先設(shè)置參數(shù)擦剑,其中cfg.TRAIN.PROPOSAL_METHOD ='gt'妖胀,這個(gè)參數(shù)先注意一下,馬上就可以用到:通過(guò)get_roidb(imdb_name)惠勒,函數(shù)獲取roidb和 imdb赚抡,下面進(jìn)入get_roidb(imdb_name)函數(shù)看一下內(nèi)部結(jié)構(gòu):
假設(shè)imdb_name為:voc_2007_trainval,進(jìn)入get_imdb函數(shù)函數(shù)纠屋,發(fā)現(xiàn)get_imdb函數(shù)的返回值imdb是一個(gè)pascal_voc類涂臣,而且pascal_voc類是imdb類的一個(gè)子類,然后執(zhí)行imdb的函數(shù)set_proposal_method巾遭,這里要注意:cfg.TRAIN.PROPOSAL_METHOD ='gt'肉康,進(jìn)入set_proposal_method函數(shù):發(fā)現(xiàn)這個(gè)函數(shù)最終的結(jié)果是:
self._roidb_handler =?self.gt_roidb闯估,而且self.gt_roidb也是一個(gè)函數(shù)灼舍,進(jìn)入self.gt_roidb函數(shù),發(fā)現(xiàn)這個(gè)函數(shù)做了兩件事情:
第一涨薪,返回了gt_roidb骑素,而且gt_roidb是一個(gè)列表,列表的長(zhǎng)度是讀取的圖片的個(gè)數(shù)刚夺,列表中的每一個(gè)元素都是一個(gè)字典献丑,字典的內(nèi)容包括:'boxes' (num_objs行4列的矩陣,num_objs是圖片中的物體數(shù)量侠姑,4列是每個(gè)物體左上角和右下角的坐標(biāo))创橄,'gt_classes'(包含num_objs個(gè)元素的一維矩陣,矩陣中每個(gè)元素的取值表示:物體所對(duì)應(yīng)的類別號(hào))莽红,'gt_overlaps'(num_objs行21列的矩陣妥畏,這個(gè)矩陣表示的是:每個(gè)物體的box和gt_box的IOU邦邦,由于這里本來(lái)就只有g(shù)t_box,所以IOU為1醉蚁,因此這個(gè)矩陣的每一行中燃辖,只有這個(gè)物體所對(duì)應(yīng)的類別號(hào)所在的列元素為1,其余都為0)网棍,'flipped'(有沒(méi)有翻轉(zhuǎn)黔龟,默認(rèn)沒(méi)有,所以取值為:False)滥玷,'seg_areas'(包含num_objs個(gè)元素的一維矩陣氏身,矩陣中每個(gè)元素的取值表示:這個(gè)物體的gt_box的面積)
第二,將得到的gt_roidb寫入'voc_2007_trainval_gt_roidb.pkl'文件中罗捎。
這樣观谦,初步得到了roidb(即為:gt_roidb),下面通過(guò)get_training_roidb函數(shù)對(duì)剛才得到roidb做進(jìn)一步的處理桨菜,下面進(jìn)入get_training_roidb函數(shù):
首先看到豁状,這個(gè)函數(shù)的傳入變量是我們上面得到的pascal_voc類,而且cfg.TRAIN.USE_FLIPPED的取值為:True倒得,那么執(zhí)行imdb.append_flipped_images()函數(shù)泻红,這個(gè)函數(shù)做三件事:
第一,將roidb列表做一個(gè)copy霞掺,然后對(duì)copy的元素進(jìn)行操作:(1)修改'boxes'的值(對(duì)圖片做翻轉(zhuǎn)谊路,那么gt_box的坐標(biāo)必然會(huì)發(fā)生變化)(2)修改'flipped'的值為:True(代表這張圖片是經(jīng)過(guò)翻轉(zhuǎn)之后的圖片)
第二,將修改后的copy數(shù)據(jù)添加到原來(lái)的roidb列表中菩彬,這樣列表的長(zhǎng)度翻倍
第三缠劝,將self._image_index(是一個(gè)列表,保存的是圖片的名稱)復(fù)制一份骗灶,并和原來(lái)的列表拼接在一塊惨恭,這樣self._image_index的長(zhǎng)度也翻倍
然后,執(zhí)行prepare_roidb(imdb)函數(shù)耙旦,這個(gè)函數(shù)主要是往roidb列表的每一個(gè)字典元素中增加更多的key和value:
roidb[i]['image']:每張圖片的絕對(duì)路徑
roidb[i]['width']:每張圖片的寬度
roidb[i]['height']:每張圖片的高度
roidb[i]['max_classes'] =gt_overlaps.argmax(axis=1):每張圖片中包含的物體的類別號(hào)(是一個(gè):一維向量)
roidb[i]['max_overlaps'] =gt_overlaps.max(axis=1):# 按照行求最大值脱羡,對(duì)于gt_box來(lái)說(shuō)結(jié)果為np.ones(物體個(gè)數(shù)),是一個(gè):一維向量免都,這里因?yàn)橹挥術(shù)t_box锉罐,所以取值為1
最后,返回get_roidb函數(shù)中绕娘,到這里脓规,關(guān)于圖片的原始數(shù)據(jù)的準(zhǔn)備工作就結(jié)束了:roidb(gt_box)和imdb(pascal_voc類)。
這里總結(jié)一下roidb险领,roidb是一個(gè)列表侨舆,列表的長(zhǎng)度是讀取的圖片文件個(gè)數(shù)的兩倍(注意升酣,經(jīng)過(guò)了圖片翻轉(zhuǎn)),列表中的每一個(gè)元素都是一個(gè)字典态罪,而且字典的key包括:'boxes' 噩茄、'gt_classes'、'gt_overlaps'复颈、'flipped'(原始圖片取值為:False绩聘,翻轉(zhuǎn)之后的圖片取值為:True)、'image'耗啦、'width'凿菩、'height'、'max_classes'帜讲、'max_overlaps'衅谷。
有個(gè)地方需要注意一下:對(duì)于gt_box來(lái)說(shuō),'gt_classes'和'max_classes'的取值是一樣的似将。