mmdetection源码笔记(二):创建网络模型之registry.py和builder.py解读(上)
引言:
在上篇文章中,講了train.py訓練文件,主要是讀取命令行函數和主函數main。main主要先做了一些config,work_dir以及log等操作(這些操作都是從命令行獲得的,或者從命令行帶有的文件里得到的參數等。)。最主要的三個步驟就是調用build_detector()來創建模型,然后同樣調用build_dataset()對數據集創建模型,然后在訓練檢測器train_detector()。
注:build_dataset()和build_detector()不在同一個builder.py中實現,所以以下的builder.py實現的是build_detector(),是在mmdet/model/下的py文件。
具體詳情看
- mmdetection源碼筆記(一):train.py解讀
本篇文章主要就是講一下,搭建模型的思路,以及registry.py和builder.py中各個函數塊的作用。
注:builder.py是在mmdet/model文件夾下,是用來創建BACKBONES、NECKS、ROI_EXTRACTORS、SHARED_HEADS、HEADS、LOSSES、DETECTORS的模型的。而關于build_dataset()(在mmdet/datasets/builder.py中),在后面講到數據集的時候再來講它。
在mmdet/utils文件夾下的registry.py為主要的實現過程,后面詳細講解。
先來看在mmdet/models文件夾下的registry.py,較簡單,代碼如下:
舉個例子:DETECTORS為注冊表Registry的實例化對象,DETECTORS .name = 'detector',Registry類的定義在mmdet/utils/文件中。
所以,根據上面代碼,我們就應該知道了,不止一個名為DETECTORS的注冊表Registry,后面還會有名為NECKS、ROI_EXTRACTORS 、SHARED_HEADS 、HEADS 、LOSSES 的注冊表,這些注冊表下的_module_dict屬性,則是用來存對應的相同類對象的,舉個例子:比如DETECTORS的_module_dict下就有可能有:Faster R-CNN、Cascade R-CNN、FPN、HTC等常見的檢測器。到這或許你就明白了注冊表的作用咯
而在mmdet/utils/Registry.py中,有一個類Registry的定義和一個方法:build_from_cfg()的實現。
build_from_cfg()方法的作用是從 congfig/py配置文件中獲取字典數據,創建module(其實也就是一個class類),然后將這個module添加到之前創建的注冊表Registry的屬性_module_dict中(這是一個字典,key為類名,value為具體的類),返回值是一個實例化后的類對象。
所以,可以這樣理解,從config/py配置文件中,將字典提取出來,然后為其映射成一個類,放進Registry對象的_module_dict屬性中。(具體看下面的代碼)
Registry.py文件
以下代碼分三部分
Part one:
inspect模塊是針對模塊,類,方法,功能等對象提供些有用的方法。例如可以幫助我們檢查類的內容,檢查方法的代碼,提取和格式化方法的參數等。
# -*- coding: utf-8 -*- import inspect import mmcvPart two:
通過前面第一段的代碼段,我們知道DETECTORS = Registry('detector')
detector是干什么的 ???
其實,DETECTORS = Registry('detector') 只是注冊了一個對象名為DETECTORS ,屬性name為detector的對象。然后用屬性_module_dict 來保存config配置文件中的對應的字典數據所對應的class類(看第三部分代碼)。請看如下類Registry的定義代碼:
note:
@的含義:
Python當解釋器讀到@的這樣的修飾符之后,會先解析@后的內容,直接就把@下一行的函數或者類作為@后邊的函數的參數,然后將返回值賦值給下一行修飾的函數對象。
在網上看到一個這樣的例子:
python會按照自下而上的順序把各自的函數結果作為下一個函數(上面的函數)的形參輸入,也就是a(b(c()))。
Part three:
以下我們通過配置文件cascade_rcnn_r50_fpn_1x.py進行講解 build 模型的過程。
在train中,最先執行Registry的是DETECTORS,傳入的參數是配置文件中的model字典。
所以,后面出現的參數cfg,指的就是配置文件中的model字典。下面是model字典的部分截圖。
我們繼續往下看
先看build_from_cfg()方法的參數:
Args:
-
cfg (dict): Config dict. It should at least contain the key “type”.
這個cfg就是py配置文件中的字典。在py配置文件中,基本上dict都會有一個key為"type",當然也有不是的,不是的,這一步就不會執行,也就不會為他創建module。也就是這邊創建成module的dict,都必須有key為"type"才可以創建(這里,我們主要講的是注冊表DETECTORS,所以此時cfg對應的是配置文件中的model字典,看上面截圖)。
舉個例子:比如type='CascadeRCNN',后面我們會知道,這個value為"CascadeRCNN"的,其實就是models文件夾中某py文件中的類名,他們通過@DETECTORS.register_module,將類名當做形參,傳入register_module。并保存下來。 -
registry (:obj:Registry): The registry to search the type from.
-
default_args (dict, optional): Default initialization arguments.
obj_type(**args),* *args是將字典unpack得到各個元素,分別與形參匹配送入函數中;看上面model的截圖,所以這邊,其實就是將除了’type’的所有字段,當做形參,送入了名為CascadeRCNN()的類中(type = ’CascadeRCNN‘)。所以字典里的key就是類中的屬性?繼續看下面。
根據Cascade R-CNN的例子,我們在models/detectors找cascade_rcnn的py文件
參考里面的參數時,直接打開對應的cascade_rcnn配置文件,在init中,里面的參數則
對應了配置文件中的字典名。下面兩個截圖分別是配置文件cascade_rcnn.py和model/detectors/cascade_rcnn.py中的類定義。
注意的是,在py配置文件中,好多py文件中都有type = ‘CascadeRCNN’,所以有些參數和屬性對不上很正常(畢竟已經設置為None了),因為這個參數可能是其他的cascade R-CNN里面的字典。
所以,我們在訓練時,測試時,就要給出配置文件,配置文件可以不同,但相同type的
detector等文件是相同的,畢竟已經將數據和實現完全的分離了。
注意:無論訓練/檢測,都會build DETECTORS;
builder.py文件
builder文件較為簡單,因為train.py中,只出現了build_detector(),所以我們先記住里面的兩個方法:build_detector和build()。
- build_detector:是創建一個detector,方法里調用了build()方法(所有的build_xx都是直接調用build方法,所以看懂這一個也就看懂所有了)。
- build():則是調用的Registry.py文件中的build_from_cfg()方法,這個方法我們已經在上面講過了。
import:
# -*- coding: utf-8 -*- from torch import nn from mmdet.utils import build_from_cfg #此處不會在執行registry而是直接進行sys.modules查詢得到 from .registry import (BACKBONES, NECKS, ROI_EXTRACTORS, SHARED_HEADS, HEADS,LOSSES, DETECTORS) #上面的registry是在models文件夾下,registry類的具體實現是在mmdet/utils文件夾下只需要看一下build()的兩個參數:cfg, registry
build_detector()在train.py中的調用,我們就可以知道,cfg是py配置文件中的字典, 以registry是DETECTORS為例,cfg就是model字典 (后面注冊表為BACKBONES、NECKS等時,就是配置文件中的其他的字典了,不是model) 。
build()方法中,主干是一個判斷結構,其實就是判斷傳進來的cfg是字典列表還是單獨的字典,來分情況處理。(以注冊表DETECTORS為例,是一個單獨的字典)
- 字典列表的話:挨個調用build_from_cfg(),將其加到注冊表******的_module_dict中,然后再返回return nn.Sequential(*modules),這個地方的作用,有待博主繼續研究一下下???
- 字典的話:直接調用build_from_cfg(),將其添加到注冊表DETECTORS中(以DETECTORS為例)。
后面的幾個build_XXXXX()的方法也就跟build_detector()相同咯。
還是以注冊表DETECTORS為例,配置文件為cascade_rcnn_r50_fpn_1x.py來講解:在model文件夾下的cascade_rcnn.py文件中,有類Cascade_RCNN()的定義,在配置文件中,對應的key被傳入類中當做屬性,這些屬性被初始化的時候,調用對應的build_XXXXX(),由此創建它們對應的注冊表。
再以NECK為例,調用build_neck(cfg);然后執行build(cfg, NECKS),這一步,形參用到NECKS,所以在Registry中,又多了一個名為NECKS的注冊表了。然后將配置文件中,字典名為neck的,然后生成一個類(類名是neck字典中的type的值,該類在model/necks文件夾下),同時將該類添加到了注冊表NECKS的_module_dict中。
到這,NECK的注冊和數據讀入,相信大家已經很清楚了,其他的注冊表也是類似的。
總結:
搭建模型思路:
- 首先,創建一個名為DETECTORS的注冊表Registry。這個注冊表有屬性name='detector',和屬性_module_dict。_module_dict 是一個字典,專門用來存各個對象名和對應的對象。
- 其次,讀取py配置文件,py配置文件是個字典,(字典里還有字典,這里面的字典,也是后面來創建模型的,道理是一樣的)。根據key為’type’的字典,創建module,對于的value為其module名,然后再model文件夾下中,已經存在了這些module的類。將字典中的其他數據,作為形參,實例化這些類。并保存這些module到屬性_module_dict中。
- 到這,配置文件的數據,里面的字典(含有type的字典)對應著一個類,type為類名,其他字段則為其屬性(其他字段也可能是個字典,后面也有可能要再為它們搭建模型哦)。由此完成模型的搭建。
這是搭建模型的一個思路,雖然講得篇幅很大,有點亂亂的感覺,但是看懂后,就會發現很簡單。
mmdetection搭建模型用途:
mmdetection將配置文件中,字典名為:backbone、neck、roi_extractor、shared_head、head、loss、detector的字典,全部實例化成注冊表(Registry),然后這些字典里的type,都被實例化成對應的類(module),并添加到注冊表的屬性_module_dict中,其他的字段,則為這個類的屬性,由此完成模型的建立,實際上,就是將配置文件的字典數據保存到類(module)中,以便后面讀取數據,加載數據。
接下來,請看博主的下面的文章:
- mmdetection源碼筆記(一):train.py解讀
- mmdetection源碼筆記(二):創建網絡模型之cascade_rcnn.py的解讀(中)
- mmdetection源碼筆記(二):cascade_rcnn.py搭建模型過程中各個module的forward()的代碼解讀(下)(待完成)
- mmdetection源碼筆記(三):創建數據集模型之datasets/coco.py的解讀(上)
- mmdetection源碼筆記(三):創建數據集模型之datasets/custom.py的解讀(下)
- mmdetection源碼筆記(四):訓練模型之train_detector()的解讀
- mmdetection源碼筆記(五):測試之test()部分的解讀
注:因為有好幾個py文件,博主也是按照自己的理解,盡量講得通俗易懂,如果有不理解的地方,底下評論。如果有錯誤的地方,還請指出學習,感激不盡。
更新2021.10.13
有大半年沒有更新博客了,這段時間一直準備春招,實習,秋招,到今天基本上可以結束坐等開獎了;
目前手里有近10個CV算法工程師意向書:字節,商湯,百度,順豐,華為,小紅書,拼多多,小馬智行,海康威視,騰訊等。
接下來會花很多時間在小紅書上整理這一過程所有的經驗以及技巧,包括:豐富簡歷內容,如何打比賽(大佬止步),如何刷題,刷什么題,刷到什么程度,面試技巧,面經整理,hr面技巧,如何反問面試官,如何argue薪資等等等,大家有需要可以關注一波哈,內容保證豐富!助力大家秋招收割offer到手軟!
小紅書號:371845174(Activewaste,博客同名)
后面也會在小紅書分享好用工具,插件,裝逼神器等,手把手教學,大家關注起來哈!
另外我比較少上csdn,大家給我私信要聯系方式或者評論問問題有時沒看到(一個月沒上,200+的通知),大家直接去小紅書私信提問,或者催我撒!
總結
以上是生活随笔為你收集整理的mmdetection源码笔记(二):创建网络模型之registry.py和builder.py解读(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大学生 计算机 毕业设计 xx管理系统
- 下一篇: xml文件解析出现[xX][mM][lL