在 2021 年 7 月時曠世科技在 YOLOv3 和 YOLOv5 的基礎下推出了 YOLOX,跟之前的 YOLO 系列最大的不同點就是在 Detection Head 的地方將 Coupled Head 換成 Decoupled Head,簡單來說就是把 Class, Bounding Box, Objectness 切成不同分支來訓練,架構如 圖一 所示:
另外在 label 分配 anchor 並計算 loss 採用了 SimOTA 方法,有興趣可以去看這篇論文:https://arxiv.org/abs/2103.14259
YOLOX 有許多網路架構可以應用在不同場景上,可以分成三大類:
- 基於 YOLOv3 修改後得到的架構:
YOLOX-Darknet53
- 基於 YOLOv5 修改後得到的架構:
YOLOX-s, YOLOX-m, YOLOX-l, YOLOX-x
- 輕量化的架構:
YOLOX-Nano, YOLOX-Tiny
這邊附上各種架構在 coco 資料集上的 mAP
標準的模型:
輕量化的模型:
牛刀小試
Installation
1.安裝 YOLOX
$ git clone https://github.com/Megvii-BaseDetection/YOLOX.git
$ cd YOLOX
$ pip install -U pip && pip install -r requirements.txt
$ pip install -v -e . # or python setup.py develop
2.安裝 pycocotools
$ pip install cython; pip install 'git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI'
Demo
1.下載預訓練模型,這邊用 YOLOX-s 來 demo
$ wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.pth
更多 weight 檔可以在 官方 github 下載
2.預測
$ python tools/demo.py image -f exps/default/yolox_s.py -c yolox_s.pth --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device [gpu]
預測結果如 圖二 所示。
- -f 後面放參數設定的檔案,這邊使用官方的預設參數 exps/default/yolox_s.py
- -c 後面放預測時使用的 weight 檔,這邊使用官方的預訓練模型 yolox_s.pth
- --path 後面放你要預測的圖片路徑,也可以放想要預測的資料夾路徑,這邊使用官方提供的照片 assets/dog.jpg
- --conf 後面放 confidence 的 threshold,這邊使用 0.25
- --nms 後面放非極大值抑制 (Non-Maximum Suppression) 的 threshold,這邊使用 0.45
- --tsize 後面放你要將影像 resize 成多大丟進模型裡預測,這邊使用 640
- --save_result 如果要將預測結果存下來可以加這個
- --device 要用什麼 device 預測,可選 cpu 或 gpu,這邊使用 gpu
訓練自己的資料集
1.標記資料
可以先使用 label 工具來進行 label,推薦使用 labelimg。
- windows 用戶:可以直接去下載編譯好的版本 labelimg
- mac 用戶:使用 pip install labelimg 安裝,再用 labelimg 指令打開程式
使用 Open Dir 讀進自己的資料集,label 完後存成 PascalVOC 格式方便做之後的處理
存成 PascalVOC 格式可以得到對應的 xml 檔案
2.訓練YOLOX
- 官方提供兩種訓練格式 COCO 格式和 VOC格式,我推薦使用 COCO 格式去訓練,不用改太多東西!
COCO 格式訓練(推薦使用)
1.快速體驗
可以先試試看能不能訓練這個簡單的範例,如果能訓練就代表環境安裝都沒有問題。
(1) 下載 mini-coco128
# 安裝 gdown 並下載 mini-coco128
$ pip install gdown
$ gdown --id 16N3u36ycNd70m23IM7vMuRQXejAJY9Fs# 解壓縮
$ unzip coco128.zip
解壓縮後就可以得到指定的樹狀資料結構
(2) 開始訓練
# 下載預訓練權重
$ wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.pth# 開始訓練
$ python tools/train.py -f exps/example/custom/yolox_s.py -d 8 -b 64 --fp16 -o -c yolox_s.pth
(3) 進行測試
$ python tools/demo.py image -f exps/example/custom/yolox_s.py -c YOLOX_outputs/coco128/best_ckpt.pth --path car.jpg --conf 0.25 --nms 0.5 --tsize 640 --save_result --device [gpu]
2.使用自己 label 好的 xml 檔訓練 COCO 格式
(1) 將標記好的資料轉換成 YOLOX 的 COCO 訓練格式
將標記好的資料放在 YOLOX/datasets/data 裡,裡面要包含訓練的影像 (jpg) 和對應的標註 (xml),接著我們使用 train_val_data_split_coco.py 來生成對應的資料夾結構和切分資料集,這邊設置的比例為 9:1,大家也可自行調整
$ cd YOLOX/datasets
$ wget https://raw.githubusercontent.com/d246810g2000/YOLOX/main/datasets/train_val_data_split_coco.py
$ python train_val_data_split_coco.py
執行完後會得到指定的資料夾結構和對應的 instances_train2017.json 和 instances_val2017.json 檔
- annotations 放對應的 instances_train2017.json 和 instances_val2017.json 檔
- train2017 放訓練集影像
- val2017 放驗證集影像
(2) 修改訓練參數
在 YOLOX/exps/example/custom/yolox_s.py 中,修改資料夾路徑 self.data_dir 和類別數量 self.num_classes
在 YOLOX/yolox/data/datasets/coco_classes.py 中的類別改成自己對應的類別,例如這邊我改成 car
(3) 開始訓練
# 下載預訓練權重
$ wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.pth# 開始訓練
$ python tools/train.py -f exps/example/custom/yolox_s.py -d 0 -b 4 --fp16 -o -c yolox_s.pth
訓練好的檔案和訓練歷史紀錄都在 YOLOX/YOLOX_outputs/yolox_s 裡面
(4) 進行測試
$ python tools/demo.py image -f exps/example/custom/yolox_s.py -c YOLOX_outputs/yolox_s/best_ckpt.pth --path datasets/data/car1.jpg --conf 0.25 --nms 0.5 --tsize 640 --save_result --device [gpu]
這邊的範例是 YOLOX-s,如果想用較大一點的網路架構進而得到較高的準確率可以自行修改 exps/example/custom/yolox_s.py 裡面的 self.depth 和 self.width,對應的 depth 和 width 如下表所示:
VOC 格式訓練(較不推薦,要改很多東西)
1.將標記好的資料轉換成 YOLOX 的 VOC 訓練格式
將標記好的資料放在 YOLOX/datasets/data 裡,裡面要包含訓練的影像 (jpg) 和對應的標註 (xml),還有類別資訊 (class_names.txt),接著我們使用 train_val_data_split_voc.py 來生成對應的資料夾結構和切分資料集,這邊設置的比例為 9:1,大家也可自行調整
$ cd YOLOX/datasets
$ wget https://raw.githubusercontent.com/d246810g2000/YOLOX/main/datasets/train_val_data_split_voc.py
$ python train_val_data_split_voc.py
執行完後會生成指定的資料夾結構和對應的 train.txt 和 val.txt 檔案
- Annotations 放標記好的 xml 檔
- JPEGImages 放資料集的影像
- ImageSets/Main 放對應的 train.txt 和 val.txt 檔
2.修改訓練參數
(1) 修改類別
在 YOLOX/yolox/data/datasets/voc_classes.py 中的類別改成自己對應的類別,例如這邊我改成 car
(2) 修改 year 資訊
在 YOLOX/yolox/data/datasets/voc.py 中因為自己的資料集沒有 year 的資訊,所以程式裡有用到 year 的都需要更改
- _get_voc_results_file_template
- _do_python_eval
(3) 修改 yolox_voc_s.py
在 YOLOX/exps/example/yolox_voc/yolox_voc_s.py 中修改以下地方
- self.num_classes = 20 -> self.num_classes = 1
- get_data_loader 的 train 路徑
- get_eval_loader 的 val 路徑
3.開始訓練
# 下載預訓練權重
$ wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.pth# 開始訓練
$ python3 tools/train.py -f exps/example/yolox_voc/yolox_voc_s.py -d 0 -b 64 -c yolox_s.pth
4.進行測試
$ python tools/demo.py image -f exps/example/yolox_voc/yolox_voc_s.py -c YOLOX_outputs/yolox_voc_s/best_ckpt.pth --path datasets/data/car1.jpg --conf 0.25 --nms 0.5 --tsize 640 --save_result --device [gpu]