入門
本頁提供有關MMDetection用法的基本教程。 有關安裝說明,請參閱上一篇的安裝文檔 。
預訓練模型的推論
我們提供測試腳本來評估整個數據集(COCO,PASCAL VOC等)以及一些高級api,以便更輕鬆地集成到其他項目。
測試數據集
[x]單個GPU測試[x]多個GPU測試[x]可視化檢測結果你可以使用以下命令測試數據集。
#單GPU測試python tools / test.py $ {CONFIG_FILE} $ {CHECKPOINT_FILE} [--out $ {RESULT_FILE}] [--eval $ {EVAL_METRICS}] [--show]#多GPU測試./tools/dist_test.sh $ {CONFIG_FILE} $ {CHECKPOINT_FILE} $ {GPU_NUM} [--out $ {RESULT_FILE}] [--eval $ {EVAL_METRICS}]可選參數: RESULT_FILE:輸出結果的文件名是pickle格式。如果未指定,結果將不會保存到文件中。 EVAL_METRICS:要根據結果評估的項目。允許的值取決於數據集,例如proposal_fast,proposal,bbox,segm可用於COCO和mAP,recall為PASCAL VOC。
--show:如果指定,檢測結果將繪製在圖像上並顯示在新窗口中。它僅適用於單個GPU測試,並用於調試和可視化。請確保GUI在你的環境中可用,否則你可能會遇到類似cannot connect to X server的錯誤。
如果要評估數據集,請不要同時指定--show。
例子:
假設你已經將檢查點下載到目錄checkpoints/。
1.測試更快的R-CNN並可視化結果。按任意鍵獲取下一張圖像。
python tools/test.py configs/faster_rcnn_r50_fpn_1x.py \ checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth \ --show2.在PASCAL VOC上測試更快的R-CNN(不保存測試結果)並評估mAP。
python tools/test.py configs/pascal_voc/faster_rcnn_r50_fpn_1x_voc.py \ checkpoints/SOME_CHECKPOINT.pth \ --eval mAP3.使用8個GPU測試Mask R-CNN,並評估bbox和mask AP。
./tools/dist_test.sh configs/mask_rcnn_r50_fpn_1x.py \ checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \ 8 --out results.pkl --eval bbox segm4.在具有8個GPU的COCO test-dev上測試Mask R-CNN,並生成json文件提交給官方評估伺服器。
./tools/dist_test.sh configs/mask_rcnn_r50_fpn_1x.py \ checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \ 8 --format-only --options "jsonfile_prefix=./mask_rcnn_test-dev_results"你將獲得兩個json文件mask_rcnn_test-dev_results.bbox.json和mask_rcnn_test-dev_results.segm.json。
網絡攝像頭演示
我們提供了一個網絡攝像頭演示來說明結果。
python demo / webcam_demo.py $ {CONFIG_FILE} $ {CHECKPOINT_FILE} [-設備$ {GPU_ID}] [--camera-id $ {CAMERA-ID}] [--score-thr $ {SCORE_THR}]例子:
python demo/webcam_demo.py configs/faster_rcnn_r50_fpn_1x.py \ checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth用於測試圖像的高級API
同步接口
這是構建模型並測試給定圖像的示例。
from mmdet.apis import init_detector, inference_detector, show_resultimport mmcvconfig_file = 'configs/faster_rcnn_r50_fpn_1x.py'checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth'# 從配置文件和檢查點文件構建模型model = init_detector(config_file, checkpoint_file, device='cuda:0')# 測試一張圖片並顯示結果img = 'test.jpg' # or img = mmcv.imread(img), which will only load it onceresult = inference_detector(model, img)# 在新窗口中可視化結果show_result(img, result, model.CLASSES)# 或者將可視化結果保存到圖像文件中show_result(img, result, model.CLASSES, out_file='result.jpg')# 測試視頻並顯示結果video = mmcv.VideoReader('video.mp4')for frame in video: result = inference_detector(model, frame) show_result(frame, result, model.CLASSES, wait_time=1)Jupyter Notebook演示可以在 demo/inference_demo.ipynb.(https://github.com/open-mmlab/mmdetection/blob/master/demo/inference_demo.ipynb)中找到。
異步接口-受Python 3.7+支持
異步接口允許不阻塞GPU綁定推理代碼上的CPU,並為單線程應用程式提供更好的CPU / GPU利用率。可以在不同的輸入數據樣本之間或某個推理管道的不同模型之間同時進行推理。
請參閱tests/async_benchmark.py比較同步和異步接口的速度。
import torchfrom mmdet.apis import init_detector, async_inference_detector, show_resultfrom mmdet.utils.contextmanagers import concurrentasync def main(): config_file = 'configs/faster_rcnn_r50_fpn_1x.py' checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth' device = 'cuda:0' model = init_detector(config_file, checkpoint=checkpoint_file, device=device) # 隊列用於多幅圖像的並發推理 streamqueue = asyncio.Queue() # 隊列大小定義並發級別 streamqueue_size = 3 for _ in range(streamqueue_size): streamqueue.put_nowait(torch.cuda.Stream(device=device)) # 測試單個圖像並顯示結果 img = 'test.jpg' # or img = mmcv.imread(img), which will only load it once async with concurrent(streamqueue): result = await async_inference_detector(model, img) # 在新窗口中可視化結果 show_result(img, result, model.CLASSES) # 或者將可視化結果保存到圖像文件中 show_result(img, result, model.CLASSES, out_file='result.jpg')訓練模型
MMDetection實施分布式訓練和非分布式訓練, 它分別使用MMDistributedDataParallel和MMDataParallel。
所有輸出(日誌文件和檢查點)將保存到工作目錄中, 在配置文件中由work_dir指定。
默認情況下,我們在每個epoch後在驗證集上評估模型,你可以通過在訓練配置中添加interval參數來更改評估間隔。
Evaluation = dict(interval = 12)#每12個時間段評估一次模型。重要:配置文件中的默認學習率是8個GPU和2 img / gpu(批量大小= 8 * 2 = 16)。根據線性縮放規則(https://arxiv.org/abs/1706.02677),如果你使用不同的GPU或每個GPU的圖像,則需要按批大小設置成比例的學習率,例如,對於4個GPU,lr = 0.01 * 2 img / gpu;對於16個GPU,lr = 0.08 * 4 img / gpu。使用單個GPU訓練
python tools / train.py $ {CONFIG_FILE}如果要在命令中指定工作目錄,則可以添加參數--work_dir $ {YOUR_WORK_DIR}。
使用多個GPU訓練
./tools/dist_train.sh $ {CONFIG_FILE} $ {GPU_NUM} [可選參數]可選參數為:
--validate(強烈建議):在訓練過程中,每隔k個epoch執行一次評估(默認值為1,可以像這樣(https://github.com/open-mmlab/mmdetection/blob/master/configs/mask_rcnn_r50_fpn_1x.py#L174) 修改)。--work_dir ${WORK_DIR}:覆蓋配置文件中指定的工作目錄。--resume_from ${CHECKPOINT_FILE}:從先前的檢查點文件恢復。resume_from和load_from之間的區別: resume_from加載模型權重和優化器狀態,並且epoch也從指定的檢查點繼承。它通常用於恢復意外中斷的訓練過程。 load_from僅加載模型權重,訓練時期從0開始。通常用於微調。
用多臺機器訓練
如果在由slurm(https://slurm.schedmd.com/) 管理的群集上運行MMDetection,則可以使用腳本"slurm_train.sh"。(此腳本還支持單機訓練。)
./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR} [${GPUS}]這是使用16個GPU在dev分區上訓練Mask R-CNN的示例。
./tools/slurm_train.sh dev mask_r50_1x configs/mask_rcnn_r50_fpn_1x.py /nfs/xxxx/mask_rcnn_r50_fpn_1x 16你可以檢查slurm_train.sh(https://github.com/open-mmlab/mmdetection/blob/master/tools/slurm_train.sh) 中的完整參數和環境變量。
如果只有多臺計算機與乙太網連接,則可以參考 pytorch 啟動實用程序(https://pytorch.org/docs/stable/distributed_deprecated.html#launch-utility)。 如果沒有像infiniband這樣的高速網絡,通常速度很慢。
在單臺計算機上啟動多個作業
如果你在一臺計算機上啟動多個作業,例如,在具有8個GPU的計算機上進行2個4-GPU訓練作業, 你需要為每個作業指定不同的埠(默認為29500),以避免通信衝突。
如果你使用dist_train.sh啟動訓練作業,則可以在命令中設置埠。
CUDA_VISIBLE_DEVICES = 0,1,2,3 PORT = 29500 ./tools/dist_train.sh $ {CONFIG_FILE} 4CUDA_VISIBLE_DEVICES = 4,5,6,7 PORT = 29501 ./tools/dist_train.sh $ {CONFIG_FILE} 4如果你將啟動訓練作業與slurm一起使用,則需要修改配置文件(通常是配置文件底部的第6行)以設置不同的通信埠。
在config1.py中,
dist_params = dict(backend='nccl',port= 29500)在config2.py中,
dist_params = dict(backend='nccl',port= 29501)然後,你可以使用config1.py和config2.py啟動兩個作業。
CUDA_VISIBLE_DEVICES=0,1,2,3 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config1.py ${WORK_DIR} 4CUDA_VISIBLE_DEVICES=4,5,6,7 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config2.py ${WORK_DIR} 4有用的工具
我們在tools/目錄下提供了許多有用的工具。
分析日誌
你可以繪製給定訓練日誌文件的損耗/ mAP曲線。首先運行pip install seaborn來安裝依賴項。
python tools/analyze_logs.py plot_curve [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]例子:
繪製一些運行的分類損失。python tools/analyze_logs.py plot_curve log.json --keys loss_cls --legend loss_cls繪製一些運行的分類和回歸損失,並將該圖保存為pdf。python tools/analyze_logs.py plot_curve log.json --keys loss_cls loss_reg --out losses.pdf比較同一圖中兩次運行的bbox mAP。python tools/analyze_logs.py plot_curve log1.json log2.json --keys bbox_mAP --legend run1 run2你還可以計算平均訓練速度。
python tools/analyze_logs.py cal_train_time ${CONFIG_FILE} [--include-outliers]預期輸出將如下所示。
-----Analyze train time of work_dirs/some_exp/20190611_192040.log.json-----slowest epoch 11, average time is 1.2024fastest epoch 1, average time is 1.1909time std over epochs is 0.0028average iter time: 1.1959 s/iter獲取FLOP和參數(實驗)
我們提供了一個根據 flops-counter.pytorch (https://github.com/sovrasov/flops-counter.pytorch)改編的腳本,用於計算給定模型的FLOP和參數。
python tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}]你將得到這樣的結果。
==============================Input shape: (3, 1280, 800)Flops: 239.32 GMacParams: 37.74 M==============================注意:此工具仍處於試驗階段,我們不保證該數字正確。你可以將結果用於簡單比較,但是在將其用於技術報告或論文之前,請仔細檢查。
(1)FLOP與輸入形狀有關,而參數與輸入形狀無關。默認輸入形狀為(1、3、1280、800)。 (2)某些運算符不像GN和自定義運算符那樣計入FLOP。 你可以通過修改mmdet / utils / flops_counter.py(https://github.com/open-mmlab/mmdetection/blob/master/mmdet/utils/flops_counter.py) 添加對新操作員的支持。 (3)兩級檢測器的FLOP取決於提議的數量。
發布模型
在將模型上傳到AWS之前,你可能需要 (1)將模型權重轉換為CPU張量, (2)刪除優化器狀態並 (3)計算檢查點文件的哈希並將哈希ID附加到文件名中。
python tools/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}例如,
python tools/publish_model.py work_dirs/faster_rcnn/latest.pth faster_rcnn_r50_fpn_1x_20190801.pth最終輸出文件名將為faster_rcnn_r50_fpn_1x_20190801- {hash id} .pth。
測試檢測器的魯棒性
請參考ROBUSTNESS_BENCHMARKING.md
操作方法
使用我自己的數據集
最簡單的方法是將數據集轉換為現有的數據集格式(COCO或PASCAL VOC)。
在這裡,我們展示了一個添加5類自定義數據集的示例,假設它也是COCO格式。
在mmdet/datasets/my_dataset.py中:
from .coco import CocoDatasetfrom .registry import DATASETS@DATASETS.register_moduleclass MyDataset(CocoDataset): CLASSES = ('a', 'b', 'c', 'd', 'e')在mmdet/datasets/__init__.py中:
from .my_dataset import MyDataset然後,你可以在配置文件中使用MyDataset,並使用與CocoDataset相同的API。
如果你不想將注釋格式轉換為COCO或PASCAL格式,也可以。 實際上,我們定義了一種簡單的注釋格式,並且所有現有數據集都是 處理以使其與在線或離線兼容。
數據集的注釋是字典列表,每個字典對應一個圖像。有3個欄位filename(相對路徑),width,height用於測試,還有一個用於訓練的欄位ann``ann也是一個至少包含2個欄位的字典:都是numpy數組的bboxes和labels。一些數據集可能會提供注釋,例如crowd/difficult/被忽略的bbox, 我們使用bboxes_ignore和labels_ignore掩蓋他們。
這是一個例子。
[ { 'filename': 'a.jpg', 'width': 1280, 'height': 720, 'ann': { 'bboxes': <np.ndarray, float32> (n, 4), 'labels': <np.ndarray, int64> (n, ), 'bboxes_ignore': <np.ndarray, float32> (k, 4), 'labels_ignore': <np.ndarray, int64> (k, ) (optional field) } }, ...]有兩種使用自定義數據集的方法。
在線轉換 你可以編寫一個繼承自CustomDataset的新Dataset類,並覆蓋兩個方法 load_annotations(self,ann_file)和get_ann_info(self,idx), 像CocoDataset(https://github.com/open-mmlab/mmdetection/blob/master/mmdet/datasets/coco.py) 和VOCDataset(https://github.com/open-mmlab/mmdetection/blob/master/mmdet/datasets/voc.py)離線轉換 你可以將注釋格式轉換為上面的預期格式,然後將其保存到 泡菜或json文件,例如pascal_voc.py(https://github.com/open-mmlab/mmdetection/blob/master/tools/convert_datasets/pascal_voc.py)。 然後,你可以簡單地使用CustomDataset。自定義優化
在mmdet/core/optimizer/copy_of_sgd.py中定義了定製優化器CopyOfSGD的示例。 更一般地,可以如下定義定製的優化器。
在mmdet/core/optimizer/my_optimizer.py中:
from .registry import OPTIMIZERSfrom torch.optim import Optimizer@OPTIMIZERS.register_moduleclass MyOptimizer(Optimizer):在mmdet/core/optimizer/__init__.py中:
from .my_optimizer import MyOptimizer然後,你可以在配置文件的"optimizer"欄位中使用"MyOptimizer"。
開發新組件
我們基本上將模型組件分為4種類型。
backbone:通常是FCN網絡,用於提取特徵圖,例如ResNet,MobileNet。neck:骨幹和頭部之間的組件,例如FPN,PAFPN。head:用於特定任務的組件,例如bbox預測和掩碼預測。roi提取器:用於從要素圖(例如RoI Align)中提取RoI要素的部分。在這裡,我們以MobileNet為例說明如何開發新組件。
創建一個新文件"mmdet/models/backbones/mobilenet.py"。import torch.nn as nnfrom ..registry import BACKBONES@BACKBONES.register_module class MobileNet(nn.Module):def __init__(self, arg1, arg2): passdef forward(self, x): # should return a tuple passdef init_weights(self, pretrained=None): pass2. 將模塊導入"mmdet/models/backbones/__init__.py"。
```pythonfrom .mobilenet import MobileNet在配置文件中使用它。model = dict( ... backbone=dict( type='MobileNet', arg1=xxx, arg2=xxx), ...有關其工作原理的更多信息,可以參考技術細節手冊。