模組註冊機制基於註冊器和構建器,可以輕鬆地進行模組拓展,而不需要在原有框架程式碼中進行改動。使用註冊器管理字串到類的對映,其中支援註冊的模組型別包括但不限於模型結構、資料預處理模組、最佳化器。使用構建器可以將配置檔案轉換成對應的模組,其提供了靈活的構建方式,使得可以構建定製化的訓練流水線。模組註冊機制的另一特性是採用分層策略劃分模組的註冊域,不僅能夠避免跨專案間同名模組的衝突,也能夠支援跨專案間模組的相互呼叫。
技術說明
模組註冊和跨專案呼叫機制
開發演算法工具庫以解決人工智慧基礎理論知識與商用業務落地工程經驗間脫節的問題。OpenMMLab基於在學術研究和行業落地的經驗,對 AI演算法進行標準化模組工具開發,大大降低具體行業業務人員的演算法學習成本,將以工業化的人工智慧研究顛覆傳統手工作坊式的研究方式,提供先進的研發工具,使人工智慧研究進入快車道。
演算法核心元件作為開放演算法體系的基礎,為演算法提供公共的架構支援和模組實現。核心元件主要分為三個部分:基礎支援庫、通用運算元和訓練流程框架。基礎支援庫提供了友好的檔案讀寫介面、影象影片處理介面、基礎工具庫等,通用運算元提供了常用運算元的高效的 GPU 實現,訓練流程框架提供了通用的演算法訓練流程支援,使得體系內的演算法能夠在相同的架構中進行訓練。
在 OpenMMLab 開源演算法體系的整體架構中,突出兩個特點:模組化和簡潔化。模組化讓使用者可以更靈活地進行排列組合,以及開發新的方法和模組;簡潔化讓使用者不用過多關注和核心邏輯無關的事情,將輔助功能交由框架自行處理。
OpenMMLab 開源演算法體系透過配置檔案、註冊器和構建器實現模組化的基礎支援,然後在模組層面將資料、模型等進行拆解和抽象,進行模組化的實現,在最頂層透過執行器來實現流程的簡潔化。
註冊器提供了在不修改演算法框架核心程式碼的前提下進行模組拓展的能力。透過管理字串到類的對映,可以實現從配置檔案直接構建模組。在開放演算法體系中,不論是模型結構,資料預處理元件,還是最佳化器,甚至頂層的訓練流程,都是透過這種方式來構建的,給使用者提供了極大的拓展空間。
圖2-2 MMCV 中註冊器的構建機制
基於註冊器和構建器,可以輕鬆地進行模組拓展,而不需要在原有框架程式碼中進行改動,這也是OpenMMLab 推薦的進行演算法開發的流程。
在 OpenMMLab 中,Registry 類可以提供一種完全相似的對外裝飾函式來管理構建不同的元件,例如 backbones、head 和 necks 等等,Registry 類內部維護的是一個全域性 key-value 對。透過 Registry 類,使用者可以透過字串方式例項化任何想要的模組。例如在 Faster R-CNN 的 backbone 模組例項化時,可以採用如下配置:
backbone=dict(
type='ResNet', # 待例項化的類名
depth=50, # 後面的都是對於的類初始化引數
num_stages=4,
out_indices=(0, 1, 2, 3),
frozen_stages=1,
norm_cfg=dict(type='BN', requires_grad=True),
norm_eval=True,
style='pytorch'),
Registry 類最大好處是:解耦性強、可擴充套件性強,程式碼更易理解。
回到 Registry 類本身,有如下幾種用法:
# 0. 先構建一個全域性的 CATS 註冊器類
CATS = mmcv.Registry('cat')
# 透過裝飾器方式作用在想要加入註冊器的具體類中
# 1. 不需要傳入任何引數,此時預設例項化的配置字串是 str (類名)
@CATS.register_module()
class BritishShorthair:
pass
# 類例項化
CATS.get('BritishShorthair')(**args)
# 2.傳入指定 str,例項化時候只需要傳入對應相同 str 即可
@CATS.register_module(name='Siamese')
class SiameseCat:
pass
# 類例項化
CATS.get('Siamese')(**args)
# 3.如果出現同名 Registry Key,可以選擇報錯或者強制覆蓋
# 如果指定了 force=True,那麼不會報錯
# 此時 Registry 的 Key 中,Siamese2Cat 類會覆蓋 SiameseCat 類
# 否則會報錯
@CATS.register_module(name='Siamese',force=True)
class Siamese2Cat:
pass
# 類例項化
CATS.get('Siamese')(**args)
# 4. 可以直接註冊類
class Munchkin:
pass
CATS.register_module(Munchkin)
# 類例項化
CATS.get('Munchkin')(**args)
目前 Registry 類一共有4種用法,方便不同場景下注冊。
跨庫呼叫
OpenMMLab 使用一系列演算法庫支援了視覺領域絕大部分任務。這些任務之間在模組元件上存在著一定的共通之處,比如在檢測、分割等任務中,網路包含一個用於提取圖片特徵的主幹網路,該主幹網路的權重在不同任務間有通用性。因此在進行檢測、分割等任務之前,可以首先使用主幹網路進行分類任務的訓練。利用分類任務龐大的 ImageNet 資料集,可以提高主幹網路的特徵提取能力,並提高模型訓練的收斂速度。
利用 Registry 機制,OpenMMLab 的演算法庫能夠便捷地完成如上所述的,跨演算法庫的訓練流程,使各個演算法庫開發的模組有機結合在一起。以檢測任務的主幹網路跨庫呼叫為例,在 MMDetection 中,檢測演算法 Yolo V3 的一種預設配置是使用 MobileNet V2 主幹網路進行影象特徵提取。在實驗中,如有需求使用其他主幹網路進行特徵提取,如 MobileNet V3,而 MMDetection 演算法庫中沒有該主幹網路的實現,我們可以利用跨庫呼叫,直接從實現了該主幹網路的演算法庫中呼叫對應的模組,而不必重新實現需要的網路。在這裡,MobileNet V3 主幹網路在分類程式碼庫 MMClassification 中有對應的實現,使用如下配置即可完成模型的跨庫呼叫:
# 直接繼承 yolo v3 的原始配置
_base_ = "./yolov3_mobilenetv2_320_300e_coco.py"
# 因為 MMDetection 中沒有匯入 MMClassification 演算法庫
# 為了完成相關的模組註冊,需要呼叫 custom_imports 來指定額外的匯入
custom_imports=dict(imports='mmcls.models', allow_failed_imports=False)
model = dict(
backbone=dict(
# 使用 "scope.type" 的語法,指定從 MMClassification 中尋找需要的模組
type='mmcls.MobileNetV3',
# MobileNet V3 的其他設定
arch='large',
out_indices=(5, 11, 14),
init_cfg=dict(
type='Pretrained',
checkpoint='mmcls://mobilenet_v3_large'),
# 配置檔案與繼承的配置檔案中相同欄位的字典,預設會融合
# 這裡使用 `_delete_` 來刪除繼承的配置檔案中的其他配置
_delete_=True),
# 主幹網路發生變化,其他相應的配置也需要改變
neck=dict(in_channels=[160, 112, 40])
跨程式碼庫呼叫機制
自定義模組匯入
利用註冊器機制,在匯入相對應的模組時,模組中所包含類自動地被註冊到 Registry 中的。而具體匯入模組的操作,被放在了程式碼執行的入口程式中,一般為 tools/train.py 和 tools/test.py,分別對應了訓練和測試。
以 MMClassification 中的 tools/train.py 為例:
...
from mmcv.runner import get_dist_info, init_dist
...
from mmcls.datasets import build_dataset
from mmcls.models import build_classifier
• 透過匯入 mmcv.runner 包,完成了 mmcv/runner/__init__.py 中一系列執行器、鉤子、最佳化器等類的註冊。
• 透過匯入 mmcls.datasets 包,完成了mmcls/datasets/__init__.py 中一系列資料集的註冊。
• 透過匯入mmcls.models 包,完成了mmcls/models/__init__.py中一系列主幹網路、頸部頭部函式的註冊。
模組的的匯入和類的註冊不一定僅發生在入口程式的最外層,比如與資料處理和增強相關的註冊器 PIPELINES 是入口程式在執行 build_dataset 時,在 mmcls/datasets/base_dataset.py 中進行相關類的註冊。
通常,如果不存在明顯的依賴,一個程式碼庫中的入口程式不會匯入其他程式碼庫的模組,因而其他程式碼庫中的類也不會被註冊。為了實現跨庫呼叫,MMCV 在解析配置檔案時,提供了顯式匯入自定義模組的 custom_imports 介面。
custom_imports=dict(imports='mmcls.models', allow_failed_imports=False)
透過在配置檔案中加入上述程式碼,MMCV 會在解析時藉助 Python 內建的 importlib 包中的import_module 函式實現其他程式碼庫模組的匯入,進而完成對應的一系列類的註冊。
Regsitry 中的 scope 機制
在進行跨庫呼叫時,需要使用 scope.type 的語法顯示指明要呼叫的類所在的 scope,例如在type='mmcls.MobileNetV3' 中,scope 為 “mmcls”。
透過引入 scope 機制的引入,Registry 能夠更靈活地處理不同程式碼庫之間模組的命名衝突,例如在MMDetection 和 MMClassification 中均註冊了 MobileNetV2 主幹網路,而 Registry 機制不允許同一個註冊器中註冊兩個相同名字的類。因此,每一個程式碼庫在獨立開發,需要註冊自己的模型時,都會註冊到程式碼庫自己的 Regsitry 中,而不是註冊到 MMCV 統一的 Registry 中,透過這種方式來避免與其他程式碼庫產生衝突。
與此同時,每個程式碼庫同類模組的 Registry 並非獨立的,而是以 MMCV 中某個統一的 Registry 為父 Regsitry,從而形成如圖所示的樹狀結構。
由於 MMCV 能夠獲得所有掛靠在主 Registry 下的各個子 Registry 的 scope,因而允許使用者顯式地指定 scope,並定位對應程式碼庫的 Registry,從而實現跨庫呼叫。
開發團隊
●帶隊負責人:陳愷
陳愷博士,OpenMMLab負責人。上海人工智慧實驗室青年科學家,陳博士本科畢業於清華大學,在香港中文大學獲得博士學位,在計算機視覺頂級會議和期刊上發表了十餘篇論文,谷歌學術引用超過 2000,並多次在國際學術競賽中獲獎。所負責的OpenMMLab 開源專案在 GitHub 上獲得了超過 40000 star,是深度學習時代極具影響力的計算機視覺開源演算法體系,在學術界和工業界產生了廣泛影響。
●其他重要成員:呂成器、張文蔚、周再達
●隸屬機構:上海人工智慧實驗室&商湯科技
上海人工智慧實驗室是我國人工智慧領域的新型科研機構,開展戰略性、原創性、前瞻性的科學研究與技術攻關,突破人工智慧的重要基礎理論和關鍵核心技術,打造“突破型、引領型、平臺型”一體化的大型綜合性研究基地,支撐我國人工智慧產業實現跨越式發展,目標建成國際一流的人工智慧實驗室,成為享譽全球的人工智慧原創理論和技術的策源地。
作為人工智慧軟體公司,商湯科技以“堅持原創,讓AI引領人類進步”為使命,“以人工智慧實現物理世界和數字世界的連線,促進社會生產力可持續發展,併為人們帶來更好的虛實結合生活體驗”為願景,旨在持續引領人工智慧前沿研究,持續打造更具拓展性更普惠的人工智慧軟體平臺,推動經濟、社會和人類的發展,並持續吸引及培養頂尖人才,共同塑造未來。
相關評價
OpenMMLab系列開源框架對新手來說太好了,自己程式設計也會按照這些方法來,潛移默化,寫出來的程式碼賞心悅目。
——華中科技大學使用者free
研一AI小白一枚,喵喵lab讓我少走彎路,API很好用,文件清晰,程式碼結構也對理解其他開原始碼很有用。
——西南交通大學使用者Jin
OpenMMLab非常方便,很多方向的相關演算法統一易用,方便我們測試修改,快速跑通。
——中科院寧波材料所使用者Fan