mmdetection最小復(fù)刻版(三):數(shù)據(jù)分析神兵利器
AI編輯:深度眸
? ? 本文主要說(shuō)明mmdetection-mini到目前為止已經(jīng)新增的一些好用的工具,原理方面會(huì)稍微提一句,主要是說(shuō)明使用方法,這些工具是用來(lái)分析數(shù)據(jù),分析模型,分析模型預(yù)測(cè)質(zhì)量的,在實(shí)際項(xiàng)目中針對(duì)自己的數(shù)據(jù)進(jìn)行可視化分析非常有用,例如感受野計(jì)算、特征圖分析、loss函數(shù)分析、推理時(shí)間分析等等。
? ? 這里寫(xiě)的是到目前為止,后面也會(huì)新增新的,歡迎各位客官提出新的想法!
github:?
https://github.com/hhaAndroid/mmdetection-mini?
歡迎star
1 數(shù)據(jù)瀏覽browse_dataset
? ? 給你一個(gè)新的目標(biāo)檢測(cè)項(xiàng)目,轉(zhuǎn)化為coco格式,設(shè)置好cfg后,難道不需要看下label和bbox是否正確?不需要看下數(shù)據(jù)增強(qiáng)策略是否合適?我想作為一個(gè)有經(jīng)驗(yàn)的工程師必然少不了這個(gè)步驟。?故browse_dataset可以對(duì)datasets吐出的數(shù)據(jù)進(jìn)行可視化檢查,看下是否有錯(cuò)誤。這個(gè)工具我是直接從mmdetection里面copy過(guò)來(lái)的,并修復(fù)了在voc那種數(shù)據(jù)的配置上面出錯(cuò)的bug。?
? ? 用法非常簡(jiǎn)單,只需要傳入cfg文件即可,以coco數(shù)據(jù)為例,如下所示?

可視化效果看起來(lái)比較難看,不過(guò)我懶得改了。
2 coco數(shù)據(jù)可視化visualize_coco
? ? 上面的可視化效果有點(diǎn)糟糕,既然是coco,那可以調(diào)用coco里面的api進(jìn)行可視化。我對(duì)其進(jìn)行了擴(kuò)展,可以?xún)H僅顯示bbox,為啥要擴(kuò)展?因?yàn)樵赾oco格式中如果沒(méi)有mask數(shù)據(jù)是無(wú)法顯示的,但是例如voc數(shù)據(jù)即使轉(zhuǎn)化為coco格式,也是不存儲(chǔ)mask的,此時(shí)用coco api進(jìn)行顯示,是啥都沒(méi)有的。
其核心參數(shù)有兩個(gè):
only_bbox為T(mén)rue表示僅僅可視化bbox,其余l(xiāng)abel不顯示
show_all為T(mén)ure表示所有類(lèi)別都顯示,否則通過(guò)指定category_name來(lái)確定顯示類(lèi)別
用法在main函數(shù)里面。以coco為例, only_bbox=False,也就是coco默認(rèn)的顯示格式:?

only_bbox=True,也就是擴(kuò)展模式:?

這個(gè)顯示就酷炫很多了。
如果show_all=Fasle,且category_name='bicycle'(一共有多少類(lèi)別會(huì)同時(shí)打印出來(lái),你就可以直接copy了)

如果不想bbox內(nèi)部填充,可以is_filling設(shè)置為False即可
3 任意格式轉(zhuǎn)化為coco格式工具CocoCreator
? ? 對(duì)于目標(biāo)檢測(cè),我都推薦大家轉(zhuǎn)化為coco格式進(jìn)行分析和訓(xùn)練。故咋能沒(méi)有任意數(shù)據(jù)轉(zhuǎn)化為coco的工具呢??這個(gè)工具核心類(lèi)在mmdet/cv_core/utils/coco_creator.py,其中嵌入了github上面的pycococreatortools函數(shù),我進(jìn)行了修改使其能夠適用多種情況。?
? ? 但是考慮到場(chǎng)景實(shí)在是太多了,不知道你的格式長(zhǎng)啥樣子,所以我這個(gè)工具其實(shí)有點(diǎn)名不副實(shí),用起來(lái)需要掌握點(diǎn)東西才行。慢慢完善吧,我個(gè)人精力有限,我自己用還蠻習(xí)慣的,大家湊合用吧。?
? ? 以我提供的tools/convert/widerface2coco.py為例說(shuō)明用法,要生成coco格式數(shù)據(jù)需要三個(gè)步驟,分別對(duì)應(yīng)CocoCreator的三個(gè)api,我仔細(xì)說(shuō)下。
1 準(zhǔn)備categories字段?
? ? 首先你需要手動(dòng)寫(xiě)categories,里面存儲(chǔ)的是類(lèi)名,例如:
[{'id': 1, # 類(lèi)別1'name': 'power','supercategory': 'object',}{'id': 2, # 類(lèi)別2'name': 'circle','supercategory': 'shape',}]
上面顯示的是兩個(gè)類(lèi)的寫(xiě)法。如果多個(gè)類(lèi),自己追加List就行。但是這種寫(xiě)法有個(gè)弊端:當(dāng)類(lèi)別很多時(shí)候,會(huì)累死人的!改進(jìn)辦法應(yīng)該是通過(guò)讀取標(biāo)注文件,然后追加,類(lèi)似voc2coco腳本一樣。
2 遍歷圖片和label?
? ?如何遍歷,那就是你自己的事情了,我在cv_core里面提供了遍歷函數(shù)traverse_file_paths,很好用。
3 處理數(shù)據(jù)?
? ? 第一個(gè)核心api是coco_creater.create_image_info(image_id, imFilename, image.size)
image_id是用來(lái)表示圖片編號(hào)的,你可以簡(jiǎn)單從1開(kāi)始累加,也可以像coco一樣直接采用文件名然后Int即可,因?yàn)橛行﹫D片命名格式無(wú)法變成image_id,故我需要你自己傳入。class_id是類(lèi)別id,你自己從categories里面取就行
? ? ?第二個(gè)核心api是coco_creater.create_annotation_info,他可以傳入bbox格式,也可以傳入二值mask。傳入mask時(shí)候就不需要傳入bbox了,因?yàn)榛趍ask會(huì)自動(dòng)計(jì)算出Bbox。?同樣的,對(duì)于一張圖片中有多個(gè)物體的場(chǎng)景,需要遍歷各個(gè)實(shí)例,并且通過(guò)segmentation_id來(lái)區(qū)分,所以這個(gè)字段也是你自己累加就行。
4 保存?
? ? 在所有圖片遍歷完成后,直接coco_creater.dump()就可以保存為json輸出了。
5 可視化?
? ? ?為了檢查生成的json文件是否正確,可以用上一個(gè)小節(jié)的coco可視化工具進(jìn)行檢查。
以wider face為例,轉(zhuǎn)化后可視化如下:

4 anchor分析工具anchor_analyze
? ? 這個(gè)工具其實(shí)意義不是很大,只能提供一些直觀的感覺(jué)。這個(gè)工具的作用是對(duì)AnchorGenerator生成的anchor進(jìn)行可視化,主要是可以分析出anchor分布、anchor大小和anchor比例等等。
其用法非常簡(jiǎn)單,只需要填入anchor相關(guān)配置即可,例如yolov3:
stride = [32, 16, 8]anchor_generator_cfg = dict(type='YOLOAnchorGenerator',base_sizes=[[(116, 90), (156, 198), (373, 326)],61), (62, 45), (59, 119)],13), (16, 30), (33, 23)]],strides=stride)

如果覺(jué)得顯示的過(guò)多不好看,可以自己設(shè)置顯示個(gè)數(shù)。
5 數(shù)據(jù)分析工具dataset_analyze
? ? 數(shù)據(jù)分析工具目前支持三個(gè):wh比例分析;wh尺寸分析和kmean算法。本來(lái)可以直接對(duì)coco的json文件進(jìn)行分析的,但是基于以下幾點(diǎn)考慮,最終采用了dataloader:
網(wǎng)絡(luò)真正運(yùn)行的圖片size不是原始coco文件里面的size,肯定會(huì)進(jìn)行前處理
訓(xùn)練過(guò)程中會(huì)進(jìn)行圖片增強(qiáng),考慮增強(qiáng)后的圖片和label才是合理的
dataloader可以利用work num加速,比單純讀取json文件遍歷快很多
基于以上幾點(diǎn)考慮,我這里分析的wh是dataloader輸出的圖片bbox的寬高。先通過(guò)dataloader進(jìn)行遍歷,收集所有bbox的wh,并進(jìn)行后續(xù)分析。k考慮到跑一遍dataloader要很久,故自動(dòng)會(huì)保存wh矩陣,下一次統(tǒng)計(jì)數(shù)據(jù)時(shí)候就不需要經(jīng)過(guò)dataloader了。
1. wh比例分析?
? ? wh寬高比例分析是指對(duì)所有g(shù)t bbox的wh進(jìn)行高寬比例統(tǒng)計(jì),分成兩個(gè)部分,分別是h/w>=1和h/w<1兩個(gè),效果如下:
? ? 以coco數(shù)據(jù)集,配置文件為retinanet_r50_fpn_coco.py,其核心參數(shù)img_scale=(600, 800)為例進(jìn)行分析:?

上圖是h/w>=1,下圖是h/w<1,可以看出數(shù)據(jù)高寬分布主要是1.0、2.0、3.0、0.7、0.9這些,也就是說(shuō)其實(shí)大部分物體都是高大于寬的,實(shí)際上也很合理,因?yàn)榇蟛糠肿匀粓?chǎng)景下物體例如人都是高大于寬的。打印輸出:
# 按照num數(shù)從大到小排序輸出hw_ratio:(1.0, 2.0, 0.7, 3.0, 0.8, 0.9, 0.6, 0.5, 0.4, 0.3, 0.2, 4.0, 0.1, 5.0, 6.0, 7.0, 8.0)num:(27340, 11147, 4524, 4374, 4206, 4179, 4024, 3543, 3116, 2391, 1451, 1357, 591, 532,
通過(guò)這種圖啟發(fā)我們,其實(shí)在設(shè)置anchor的wh比例時(shí)候不一定要對(duì)稱(chēng)設(shè)置,例如常規(guī)的設(shè)置是(0.5,1.0,2.0),而是可以對(duì)于coco數(shù)據(jù)集設(shè)置為(0.5,0.7,1.0,2.0,3.0)或許更加合適。
2. wh尺寸分析?
? ? wh scale參數(shù)也很關(guān)鍵,但是不好意思,我目前沒(méi)有發(fā)現(xiàn)很好的可視化手段,什么叫做很好的可視化手段:換一個(gè)新數(shù)據(jù)集情況下,只需要運(yùn)行我的腳本生成幾個(gè)圖表,你立刻就能夠設(shè)置wh比例和wh尺度參數(shù)了。
但是目前我還沒(méi)有想到非常好的可視化手段,歡迎各位朋友提出改進(jìn)意見(jiàn)。

我只是簡(jiǎn)單繪制了w和h尺度的直方圖而已,不太直觀。
3. anchor計(jì)算?
? ? 這部分是為yolo系列算法設(shè)計(jì)的,通過(guò)本腳本可以直接生成指定數(shù)目的anchor。?
假設(shè)設(shè)置為9個(gè)anchor,那么在coco部分?jǐn)?shù)據(jù)集上打印如下:
Accuracy: 61.29%K anchors:[[8, 12], [19, 23], [26, 54], [54, 32], [54, 84], [136, 85], [88, 176], [207, 245], [468, 435]]
由于gt bbox的寬高變化比較大,故kmean后準(zhǔn)確率才61.29%。大家可以多運(yùn)行幾次,有可能會(huì)得到更好一點(diǎn)的結(jié)果。
總之,這個(gè)數(shù)據(jù)分析工具dataset_analyze還不太完善,歡迎大家提出想法。
6 推理時(shí)間計(jì)算工具infertime_analyze
? ? 當(dāng)我們?cè)O(shè)計(jì)了一個(gè)新網(wǎng)絡(luò)結(jié)構(gòu)的時(shí)候,首先第一個(gè)任務(wù)就是分析耗時(shí)。希望知道這個(gè)改進(jìn)對(duì)推理速度有多少影響?并且為了方便對(duì)mmdetection-mini里面的所有算法進(jìn)行公平時(shí)間對(duì)比,需要一個(gè)推理時(shí)間計(jì)算工具。?
? ? 該工具需要輸入配置cfg用來(lái)確定算法模型,還需要輸入圖片size。需要特別注意的是我們僅僅是為了計(jì)算前向推理時(shí)間,故需要采用forward重寫(xiě)方法實(shí)現(xiàn)。?
以yolov3,rtx1070ti硬件為例,腳本運(yùn)行后打印如下:
# input_shape = (4, 3, 320, 320)batch_avg_time=39.06158ms,one_avg_time==9.76539ms# input_shape = (8, 3, 320, 320)batch_avg_time=72.22127ms,one_avg_time==9.02766ms# input_shape = (1, 3, 320, 320)batch_avg_time=16.97711ms,one_avg_time==16.97711ms
可以看出,batch越大,耗時(shí)越短。有了這個(gè)工具你就可以在同一硬件情況下測(cè)試不同模型推理時(shí)間
7 loss分析工具loss_analyze
? ? loss分析工具的主要目的有兩個(gè):
檢查代碼是否有bug
理解別人寫(xiě)好的loss
目前這個(gè)工具還不完善,只指出focal loss。后續(xù)會(huì)寫(xiě)通用版本,可以指出mmdetection-mini里面的所有Loss,只需要傳入loss的cfg即可。focal loss分析如下:?

上圖是loss曲線(xiàn),下圖是梯度曲線(xiàn)。
8 特征圖可視化工具featuremap_analyze
? ? 特征圖可視化工具的用途是用來(lái)可視化任意層的輸出特征圖,主要用途是:
查看任意層特征圖的預(yù)測(cè)情況,看下是否符合預(yù)期
查看新增的注意力模塊到底有沒(méi)有起作用
有待挖掘
? ? 需要特別說(shuō)明的是:這個(gè)工具非常通用,可以指出任何框架的模型,只需要傳入Model即可,不需要綁定mmdetection-mini框架也可以使用。
? ? 下面介紹用法。以yolov3 320尺寸,并且下載mmdetection已經(jīng)訓(xùn)練好的權(quán)重進(jìn)行分析。在配置好參數(shù)后,首先你需要指的想看哪一層特征圖,為了方便大家,在運(yùn)行前我會(huì)打印網(wǎng)絡(luò)層數(shù)(內(nèi)部采用torchsummaryX第三方庫(kù)),如下所示:

? ? 可以看出,yolov3的三個(gè)輸出層索引分別是 [218, 214, 210],特征圖從大到小,也就是說(shuō)這三個(gè)特征圖是用來(lái)檢測(cè)小物體、中等物體和大物體的。我可視化的這三個(gè)層都是255的通道輸出,然后全部resize到原圖大小進(jìn)行顯示。

效果還是可以的。
? ? 但是其實(shí)可以控制更加精細(xì),我們知道這三個(gè)其實(shí)都是yolov3的輸出層,輸出通道255都是有具體含義的,例如你可以直接把confidence通道切割出來(lái),然后可視化,效果應(yīng)該會(huì)更好。鑒于我目前代碼都是通用的,故你可以自己改改實(shí)現(xiàn)這個(gè)效果。
9 感受野計(jì)算工具receptive_analyze
? ? 感受野分析的作用性,我想大家都知道,在設(shè)計(jì)網(wǎng)絡(luò)模型時(shí)候非常關(guān)鍵。為了方便大家計(jì)算各種模型感受野,我提供了這個(gè)工具,和featuremap_analyze一樣,也是通用工具。用法和featuremap_analyze一樣。?
? ? 你也可以指定想看任意層的感受野,這里是通過(guò)梯度反向傳播、像素改變的最大范圍來(lái)計(jì)算的??梢园l(fā)現(xiàn)這里的感受野不是理論值,而是實(shí)際值。?
? ? 有一個(gè)細(xì)節(jié)需要說(shuō)明下:我們知道激活函數(shù)relu是非常常用的,但是其梯度僅僅計(jì)算大于0區(qū)域,這樣子的話(huà),算感受野的時(shí)候會(huì)偏小,所以為了避免計(jì)算不準(zhǔn)確,我會(huì)內(nèi)部自動(dòng)把relu替換為L(zhǎng)inear,同理,自動(dòng)把MaxPool2d替換為AvgPool2d,這樣子計(jì)算的感受野才是準(zhǔn)確的。但是目前我僅僅考慮了這兩個(gè)算子,如果有其他有相同效應(yīng)的算子也是同樣道理替換即可。?以yiny_yolov3為例,計(jì)算2個(gè)輸出層的感受野如下:
特征圖最大預(yù)測(cè)層感受野(42):w=286, h=286
特征圖最小預(yù)測(cè)層感受野(214):w=318, h=318
大家可以測(cè)試自己的模型,暫時(shí)不知道還有沒(méi)有bug,歡迎大家試用!
再次貼一下github:?
https://github.com/hhaAndroid/mmdetection-mini
歡迎star
整體來(lái)說(shuō),工具的作用就是為了減少出錯(cuò)次數(shù)和容易分析模型,目前這些工具有些比較通用,有些還有待完善,希望各位客官能夠給出指導(dǎo)意見(jiàn)!
推薦閱讀
mmdetection最小復(fù)刻版(二):RetinaNet和YoloV3分析
機(jī)器學(xué)習(xí)算法工程師
? ??? ? ? ? ? ? ? ? ? ? ? ??????????????????一個(gè)用心的公眾號(hào)
?

