超詳細(xì)!手把手教你使用YOLOX進(jìn)行物體檢測(cè)(附數(shù)據(jù)集)
作者:王浩,3D視覺開發(fā)者社區(qū)簽約作者,畢業(yè)于北京航空航天大學(xué),人工智能領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,CSDN博客認(rèn)證專家。
編輯:3D視覺開發(fā)者社區(qū)
摘要
YOLOX: Exceeding YOLO Series in 2021
•代碼:https://github.com/Megvii-BaseDetection/YOLOX•論文:https://arxiv.org/abs/2107.08430
YOLOX 是曠視開源的高性能檢測(cè)器。曠視的研究者將解耦頭、數(shù)據(jù)增強(qiáng)、無(wú)錨點(diǎn)以及標(biāo)簽分類等目標(biāo)檢測(cè)領(lǐng)域的優(yōu)秀進(jìn)展與 YOLO 進(jìn)行了巧妙的集成組合,提出了 YOLOX,不僅實(shí)現(xiàn)了超越 YOLOv3、YOLOv4 和 YOLOv5 的 AP,而且取得了極具競(jìng)爭(zhēng)力的推理速度。如下圖:
其中YOLOX-L版本以 68.9 FPS 的速度在 COCO 上實(shí)現(xiàn)了 50.0% AP,比 YOLOv5-L 高出 1.8% AP!還提供了支持 ONNX、TensorRT、NCNN 和 Openvino 的部署版本,本文將詳細(xì)介紹如何使用 YOLOX進(jìn)行物體檢測(cè)。
一、 配置環(huán)境
本機(jī)的環(huán)境:
操作系統(tǒng) | Win10 |
Pytorch版本 | 1.8.0 |
Cuda版本 | 11.1 |
1.1 下載源碼
GitHub地址:https://github.com/Megvii-BaseDetection/YOLOX,下載完成后放到D盤根目錄,然后用PyCharm打開。
1.2 安裝依賴包
點(diǎn)擊“Terminal”,如下圖,
然后執(zhí)行下面的命令,安裝所有的依賴包。
pip install -r requirements.txt
1.3 安裝yolox
python setup.py install
看到如下信息,則說明安裝完成了
1.4 安裝apex
APEX是英偉達(dá)開源的,完美支持PyTorch框架,用于改變數(shù)據(jù)格式來減小模型顯存占用的工具。其中最有價(jià)值的是amp(Automatic Mixed Precision),將模型的大部分操作都用Float16數(shù)據(jù)類型測(cè)試,一些特別操作仍然使用Float32。并且用戶僅僅通過三行代碼即可完美將自己的訓(xùn)練代碼遷移到該模型。實(shí)驗(yàn)證明,使用Float16作為大部分操作的數(shù)據(jù)類型,并沒有降低參數(shù),在一些實(shí)驗(yàn)中,反而由于可以增大Batch size,帶來精度上的提升,以及訓(xùn)練速度上的提升。
安裝步驟:
1) 到官網(wǎng)下載apex,地址:mirrors / nvidia / apex · CODE CHINA (csdn.net)[1]
2) 下載完成后,解壓后,在Shell里,進(jìn)入到apex-master中。
3) 執(zhí)行安裝命令
pip install -r requirements.txt
python setup.py install
看到如下log,則表明安裝成功。
1.5 安裝pycocotools
pip install pycocotools
注:如果出現(xiàn)環(huán)境問題,可以參考博客:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/105858384
1.6 驗(yàn)證環(huán)境
下載預(yù)訓(xùn)練模型,本文選用的是YOLOX-s,下載地址:https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.pth。
下載完成后,將預(yù)訓(xùn)練模型放到工程的根目錄,如下圖:
然后驗(yàn)證環(huán)境,執(zhí)行:
python tools/demo.py image -f exps/default/yolox_s.py -c ./yolox_s.pth --path assets/dog.jpg --conf 0.3 --nms 0.65 --tsize 640 --save_result --device gpu
參數(shù)說明
參數(shù) | 說明 |
-c | 權(quán)重的路徑 |
-path | 測(cè)試圖片的路徑 |
-conf | 置信度閾值 |
-nms | nms的IOU閾值 |
-tsize | 測(cè)試圖片resize的大小 |
-save_result | 是否保存推理結(jié)果 |
--device | 選用gpu或cpu推理 |
查看運(yùn)行結(jié)果:
看到上圖說明環(huán)境沒有問題了。
二、 制作數(shù)據(jù)集
數(shù)據(jù)集我們采用VOC數(shù)據(jù)集,原始數(shù)據(jù)集是Labelme標(biāo)注的數(shù)據(jù)集。下載地址:https://pan.baidu.com/s/1kj-diqEK2VNVqd2n4ROa5g (提取碼rrnz)
新建labelme2voc.py文件
import os from typing import List, Any import numpy as np import codecs import json from glob import glob import cv2 import shutil from sklearn.model_selection import train_test_split # 1.標(biāo)簽路徑 labelme_path = "LabelmeData/" # 原始labelme標(biāo)注數(shù)據(jù)路徑 saved_path = "VOC2007/" # 保存路徑 isUseTest = True # 是否創(chuàng)建test集 # 2.創(chuàng)建要求文件夾 if not os.path.exists(saved_path + "Annotations"): os.makedirs(saved_path + "Annotations") if not os.path.exists(saved_path + "JPEGImages/"): os.makedirs(saved_path + "JPEGImages/") if not os.path.exists(saved_path + "ImageSets/Main/"): os.makedirs(saved_path + "ImageSets/Main/") # 3.獲取待處理文件 files = glob(labelme_path + "*.json") files = [i.replace("\\", "/").split("/")[-1].split(".json")[0] for i in files] print(files) # 4.讀取標(biāo)注信息并寫入 xml for json_file_ in files: json_filename = labelme_path + json_file_ + ".json" json_file = json.load(open(json_filename, "r", encoding="utf-8")) height, width, channels = cv2.imread(labelme_path + json_file_ + ".jpg").shape with codecs.open(saved_path + "Annotations/" + json_file_ + ".xml", "w", "utf-8") as xml: xml.write('\n') xml.write('\t' + 'WH_data' + '\n') xml.write('\t' + json_file_ + ".jpg" + '\n') xml.write('\t\n') xml.write('\t\tWH Data\n') xml.write('\t\tWH\n') xml.write('\t\tflickr\n') xml.write('\t\tNULL\n') xml.write('\t\n') xml.write('\t\n') xml.write('\t\tNULL\n') xml.write('\t\tWH\n') xml.write('\t\n') xml.write('\t\n') xml.write('\t\t' + str(width) + '\n') xml.write('\t\t' + str(height) + '\n') xml.write('\t\t' + str(channels) + '\n') xml.write('\t\n') xml.write('\t\t0\n') for multi in json_file["shapes"]: points = np.array(multi["points"]) labelName = multi["label"] xmin = min(points[:, 0]) xmax = max(points[:, 0]) ymin = min(points[:, 1]) ymax = max(points[:, 1]) label = multi["label"] if xmax <= xmin: pass elif ymax <= ymin: pass else: xml.write('\t\n') print(json_filename, xmin, ymin, xmax, ymax, label) xml.write('') # 5.復(fù)制圖片到 VOC2007/JPEGImages/下 image_files = glob(labelme_path + "*.jpg") print("copy image files to VOC007/JPEGImages/") for image in image_files: shutil.copy(image, saved_path + "JPEGImages/") # 6.split files for txt txtsavepath = saved_path + "ImageSets/Main/" ftrainval = open(txtsavepath + '/trainval.txt', 'w') ftest = open(txtsavepath + '/test.txt', 'w') ftrain = open(txtsavepath + '/train.txt', 'w') fval = open(txtsavepath + '/val.txt', 'w') total_files = glob("./VOC2007/Annotations/*.xml") total_files = [i.replace("\\", "/").split("/")[-1].split(".xml")[0] for i in total_files] trainval_files = [] test_files = [] if isUseTest: trainval_files, test_files = train_test_split(total_files, test_size=0.15, random_state=55) else: trainval_files = total_files for file in trainval_files: ftrainval.write(file + "\n") # split train_files, val_files = train_test_split(trainval_files, test_size=0.15, random_state=55) # train for file in train_files: ftrain.write(file + "\n") # val for file in val_files: fval.write(file + "\n") for file in test_files: print(file) ftest.write(file + "\n") ftrainval.close() ftrain.close() fval.close() ftest.close()
運(yùn)行上面的代碼就可以得到VOC2007數(shù)據(jù)集。如下圖所示:
VOC的目錄如下,所以要新建data/VOCdevkit目錄,然后將上面的結(jié)果復(fù)制進(jìn)去