歡迎大家使用PaddleDetection,針對目前大家使用PaddleDetection過程中遇到的問題,我們將高頻出現的情況整理成了FAQ(常見問題)
傳送門:https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/docs/tutorials/FAQ.md
Github地址為:https://github.com/PaddlePaddle/PaddleDetection 歡迎大家試用,點star支持~
Q: 為什么我使用單GPU訓練loss會出NaN?
A: 配置文件中原始學習率是適配多GPU訓練(8x GPU),若使用單GPU訓練,須對應調整學習率(例如,除以8)。
以faster_rcnn_r50 為例,在靜態圖下計算規則表如下所示,它們是等價的,表中變化節點即為piecewise decay里的boundaries:
| GPU數 | batch size/卡 | 學習率 | 最大輪數 | 變化節點 |
|---|---|---|---|---|
| 2 | 1 | 0.0025 | 720000 | [480000, 640000] |
| 4 | 1 | 0.005 | 360000 | [240000, 320000] |
| 8 | 1 | 0.01 | 180000 | [120000, 160000] |
- 上述方式適用於靜態圖下。在動態圖中,由於訓練以epoch方式計數,因此調整GPU卡數后只需要修改學習率即可,修改方式和靜態圖相同.
Q: 自定義數據集時,配置文件里的num_classes應該如何設置?
A: 動態圖中,自定義數據集時將num_classes統一設置為自定義數據集的類別數即可,靜態圖中(static目錄下),YOLO系列模型和anchor free系列模型將num_classes設置為自定義數據集類別即可,其他模型如RCNN系列,SSD,RetinaNet,SOLOv2等模型,由於檢測原理上分類中需要區分背景框和前景框,設置的num_classes須為自定義數據集類別數+1,即增加一類背景類。
Q: PP-YOLOv2模型訓練使用—eval做訓練中驗證,在第一次做eval的時候hang住,該如何處理?
A: PP-YOLO系列模型如果只加載backbone的預訓練權重從頭開始訓練的話收斂會比較慢,當模型還沒有較好收斂的時候做預測時,優於輸出的預測框比較混亂,在NMS時做排序和濾除會非常耗時,就好像eval時hang住了一樣,這種情況一般發生在使用自定義數據集並且自定義數據集樣本數較少導致訓練到第一次做eval的時候訓練輪數較少,模型還沒有較好收斂的情況下,可以通過如下三個方面排查解決。
-
PaddleDetection中提供的默認配置一般是采用8卡訓練的配置,配置文件中的
batch_size數為每卡的batch size,若訓練的時候不是使用8卡或者對batch_size有修改,需要等比例的調小初始learning_rate來獲得較好的收斂效果 -
如果使用自定義數據集並且樣本數比較少,建議增大
snapshot_epoch數來增加第一次進行eval的時候的訓練輪數來保證模型已經較好收斂 -
若使用自定義數據集訓練,可以加載我們發布的COCO或VOC數據集上訓練好的權重進行finetune訓練來加快收斂速度,可以使用
-o pretrain_weights=xxx的方式指定預訓練權重,xxx可以是Model Zoo里發布的模型權重鏈接
Q: 如何更好的理解reader和自定義修改reader文件
# 每張GPU reader進程個數
worker_num: 2
# 訓練數據
TrainReader:
inputs_def:
num_max_boxes: 50
# 訓練數據transforms
sample_transforms:
- Decode: {} # 圖片解碼,將圖片數據從numpy格式轉為rgb格式,是必須存在的一個OP
- Mixup: {alpha: 1.5, beta: 1.5} # Mixup數據增強,對兩個樣本的gt_bbbox/gt_score操作,構建虛擬的訓練樣本,可選的OP
- RandomDistort: {} # 隨機顏色失真,可選的OP
- RandomExpand: {fill_value: [123.675, 116.28, 103.53]} # 隨機Canvas填充,可選的OP
- RandomCrop: {} # 隨機裁剪,可選的OP
- RandomFlip: {} # 隨機左右翻轉,默認概率0.5,可選的OP
# batch_transforms
batch_transforms:
- BatchRandomResize: {target_size: [320, 352, 384, 416, 448, 480, 512, 544, 576, 608], random_size: True, random_interp: True, keep_ratio: False}
- NormalizeBox: {}
- PadBox: {num_max_boxes: 50}
- BboxXYXY2XYWH: {}
- NormalizeImage: {mean: [0.485, 0.456, 0.406], std: [0.229, 0.224, 0.225], is_scale: True}
- Permute: {}
- Gt2YoloTarget: {anchor_masks: [[6, 7, 8], [3, 4, 5], [0, 1, 2]], anchors: [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45], [59, 119], [116, 90], [156, 198], [373, 326]], downsample_ratios: [32, 16, 8]}
# 訓練時batch_size
batch_size: 24
# 讀取數據是是否亂序
shuffle: true
# 是否丟棄最后不能完整組成batch的數據
drop_last: true
# mixup_epoch,大於最大epoch,表示訓練過程一直使用mixup數據增廣。默認值為-1,表示不使用Mixup。如果刪去- Mixup: {alpha: 1.5, beta: 1.5}這行代碼則必須也將mixup_epoch設置為-1或者刪除
mixup_epoch: 25000
# 是否通過共享內存進行數據讀取加速,需要保證共享內存大小(如/dev/shm)滿足大於1G
use_shared_memory: true
如果需要單尺度訓練,則去掉batch_transforms里的BatchRandomResize這一行,在sample_transforms最后一行添加- Resize: {target_size: [608, 608], keep_ratio: False, interp: 2}
Decode是必須保留的,如果想要去除數據增強,則可以注釋或刪除Mixup RandomDistort RandomExpand RandomCrop RandomFlip,注意如果注釋或刪除Mixup則必須也將mixup_epoch這一行注釋或刪除,或者設置為-1表示不使用Mixup
sample_transforms:
- Decode: {}
- Resize: {target_size: [608, 608], keep_ratio: False, interp: 2}
Q: 用戶如何控制類別類別輸出?即圖中有多類目標只輸出其中的某幾類
A: 用戶可自行在代碼中進行修改,增加條件設置。
# filter by class_id
keep_class_id = [1, 2]
bbox_res = [e for e in bbox_res if int(e[0]) in keep_class_id]
Q: 用戶自定義數據集訓練,預測結果標簽錯誤
A: 此類情況往往是用戶在設置數據集路徑時候,並沒有關注TestDataset中anno_path的路徑問題。需要用戶將anno_path設置成自己的路徑。
TestDataset:
!ImageFolder
anno_path: annotations/instances_val2017.json
