將目標(biāo)檢測(cè)模型導(dǎo)出到C++|RT-DETR、YOLO-NAS、YOLOv10、YOLOv9、YOLOv8
最近,出現(xiàn)了更新的YOLO模型,還有RT-DETR模型,這是一個(gè)聲稱能擊敗YOLO模型的變換器模型,我想將這些模型導(dǎo)出并進(jìn)行比較,并將它們添加到我的庫(kù)中。在這篇文章中,我將帶你了解如何將這些模型導(dǎo)出到ONNX并運(yùn)行它們,然后最終比較這些模型的速度。
將RT-DETR模型導(dǎo)出到ONNX
這是從模型的GitHub頁(yè)面獲取的模型示例輸出
為了導(dǎo)出模型,我們需要從模型的GitHub倉(cāng)庫(kù)克隆代碼(https://github.com/lyuwenyu/RT-DETR)。我將向你展示如何導(dǎo)出模型的第二個(gè)版本。如果你想使用第一個(gè)版本,導(dǎo)出步驟應(yīng)該是類似的。
git clone https://github.com/lyuwenyu/RT-DETR.git
cd RT-DETR/rtdetrv2_pytorch
然后我們需要?jiǎng)?chuàng)建一個(gè)Python虛擬環(huán)境來(lái)運(yùn)行代碼。如果你已經(jīng)有一個(gè)工作的環(huán)境,那么你可以跳過(guò)這一步。
python -m venv rtdetrv2-env
source rtdetrv2-env/bin/activate
pip install -r requirements.txt
pip install scipy
代碼需要scipy庫(kù),但它不在需求文件中,你需要手動(dòng)安裝。然后我們需要下載coco數(shù)據(jù)集的YAML配置文件和模型。我們將在這里下載的模型是中等大小的模型。你可以在這里找到其他模型的鏈接。
mkdir models
cd models
wget -c https://github.com/lyuwenyu/storage/releases/download/v0.1/rtdetrv2_r34vd_120e_coco_ema.pth
wget -O dataset/coco_detection.yml https://raw.githubusercontent.com/ultralytics/ultralytics/main/ultralytics/cfg/datasets/coco.yaml
現(xiàn)在我們可以導(dǎo)出模型了。請(qǐng)注意,如果你改變了模型大小,那么你需要更改下面的配置文件路徑以匹配模型。
python tools/export_onnx.py -c configs/rtdetrv2/rtdetrv2_r34vd_120e_coco.yml -r models/rtdetrv2_r34vd_120e_coco_ema.pth --check
現(xiàn)在你有了你的模型(在rtdetrv2_pytorch目錄中的model.onnx文件)。你可以進(jìn)入運(yùn)行模型部分。
將YOLO-NAS導(dǎo)出到ONNX
與模型的GitHub頁(yè)面上的其他模型相比,YOLO-NAS模型
為了導(dǎo)出YOLO-NAS模型,你需要安裝super_gradients庫(kù),然后運(yùn)行以下Python代碼。模型變體是YOLO_NAS_S、YOLO_NAS_M、YOLO_NAS_L。
from super_gradients.training import models
from super_gradients.common.object_names import Models
model = models.get(Models.YOLO_NAS_S, pretrained_weights="coco")
model.eval()
model.prep_model_for_conversion(input_size=[1, 3, 640, 640])
model.export("yolo_nas_s.onnx", postprocessing=None, preprocessing=None)
現(xiàn)在你有了你的模型(yolo_nas_s.onnx文件)。你可以進(jìn)入運(yùn)行模型部分。
將YOLOv10導(dǎo)出到ONNX
與模型的GitHub頁(yè)面上的其他模型相比,YOLOv10模型的延遲
我們需要克隆GitHub倉(cāng)庫(kù)(https://github.com/THU-MIG/yolov10)并創(chuàng)建一個(gè)Conda環(huán)境來(lái)運(yùn)行導(dǎo)出代碼。
git clone https://github.com/THU-MIG/yolov10.git
cd yolov10
conda create -n yolov10-env python=3.9
conda activate yolov10-env
pip install -r requirements.txt
pip install -e .
現(xiàn)在我們需要導(dǎo)出模型。模型的前綴是jameslahm/,支持的模型有yolov10n、yolov10s、yolov10m、yolov10b、yolov10l、yolov10x。
yolo export model=jameslahm/yolov10m format=onnx opset=13 simplify
現(xiàn)在你有了你的模型(yolov10目錄中的yolov10m.onnx文件)。你可以進(jìn)入運(yùn)行模型部分。
將YOLOv9導(dǎo)出到ONNX
與模型的GitHub頁(yè)面上的其他模型相比,YOLOv9模型的參數(shù)數(shù)量
為了導(dǎo)出YOLOv9,你需要有一個(gè)工作的正常安裝的docker。你可以啟動(dòng)一個(gè)容器并導(dǎo)出模型。你可以在這里找到模型文件。
# Create an empty directory and cd into it
git clone https://github.com/WongKinYiu/yolov9.git
# Now we have yolov9 folder in out current directory. Then we run the following line:
docker run --name yolov9 -it -v `pwd`:`pwd` -w `pwd` --shm-size=64g nvcr.io/nvidia/pytorch:21.11-py3
# Install dependencies
apt update
apt install -y zip htop screen libgl1-mesa-glx
pip install seaborn thop
cd yolov9
# Download the model
wget https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-s.pt
# Export the model
python export.py --weights yolov9-s.pt --include onnx
現(xiàn)在你有了你的模型(yolov9目錄中的yolov9-s.onnx文件)。你可以進(jìn)入運(yùn)行模型部分。
將YOLOv8導(dǎo)出到ONNX
與模型的GitHub頁(yè)面上的其他模型相比,YOLOv8模型
將YOLOv8導(dǎo)出比其他模型更容易。你只需要安裝ultralytics并導(dǎo)出模型。支持的模型有yolov8n、yolov8s、yolov8m、yolov8l和yolov8x。如果你想的話,你可以創(chuàng)建一個(gè)虛擬環(huán)境來(lái)隔離安裝。
pip install ultralytics
wget https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt
yolo export model=yolov8n.pt format=onnx
現(xiàn)在你有了模型(yolov8n.onnx文件),可以進(jìn)入運(yùn)行模型部分。
運(yùn)行模型
現(xiàn)在你有了你想要導(dǎo)出的ONNX模型,你可以使用我編寫的庫(kù)來(lái)運(yùn)行這些模型。你可以在這里找到這個(gè)庫(kù)。庫(kù)的README文件解釋了如何鏈接到庫(kù)。以下是如何使用庫(kù)中的RT-DETR模型的示例。
#include <objdetex/objdetex.h>
int main()
{
using namespace ObjDetEx;
Detector detector(Detector::RT_DETR, "<path/to/onnx/model>");
Size batchSize = 1;
double detectionThreshold = .6;
// Fill this with batchSizex3x640x640 image data
float *imagePtr = nullptr;
// Fill this with batchSizex2 dimension data, not needed for YOLO models
// NOTE: 2 is width and height of the original images before resizing to 640x640
int64_t *dimensionPtr = nullptr;
auto detections = detector(Tensor(imagePtr, {batchSize, 3, 640, 640}), //
Tensor(dimensionPtr, {batchSize, 2}), detectionThreshold);
// Use the detections
return 0;
}