境配置到模型部署:目標(biāo)檢測全流程實戰(zhàn)指南)
直接開始寫。1. 環(huán)境準(zhǔn)備裝 YOLOv5 之前先把這幾件事搞清楚很多人拿到 YOLOv5 教程就開始復(fù)制粘貼git clone命令結(jié)果裝到一半報錯才回頭一個個排查環(huán)境問題。YOLOv5 是個看似簡單、實則對環(huán)境干凈程度要求不低的項目我見過太多新手卡在環(huán)境上真正把時間浪費在“安裝”而不是“使用”上。所以這篇教程我從環(huán)境講起把最容易被忽略的細(xì)節(jié)一次說透。先說結(jié)論YOLOv5 支持 Python 3.7-3.11官方推薦 PyTorch 1.7 以上版本。但“支持”和“能跑得舒服”是兩回事我個人長期用的組合是 Python 3.8 或 3.10 PyTorch 1.10/1.13/2.0這個區(qū)間最穩(wěn)。Python 版本太新比如 3.12、3.13反而容易踩坑因為一些老版本依賴庫還沒有對應(yīng)的輪子編譯起來會讓人崩潰。1.1 Python 版本與虛擬環(huán)境為什么不建議直接裝到系統(tǒng)環(huán)境第一步先確認(rèn)你的 Python 環(huán)境和顯卡情況。用 Anaconda 創(chuàng)建獨立虛擬環(huán)境是 YOLOv5 安裝中最值得養(yǎng)成的習(xí)慣。原因是 YOLOv5 的依賴項版本比較敏感比如numpy的版本會影響opencv的行為matplotlib版本太新會導(dǎo)致繪圖報錯。如果你把 YOLOv5 裝到系統(tǒng)環(huán)境里后面跑其他項目時很容易出現(xiàn)“裝 A 包卸 B 包”的惡性循環(huán)。創(chuàng)建虛擬環(huán)境的命令非常簡單conda create -n yolov5 python3.10 conda activate yolov5這里我特意選了 Python 3.10因為它在 PyTorch 生態(tài)里兼容性最好既支持老代碼也支持新庫。如果你用的是 Python 3.8也沒問題都是很穩(wěn)的版本。1.2 GPU 與 CUDA能不能跑顯卡決定了你的訓(xùn)練速度差多少倍接下來檢查 GPU 環(huán)境。YOLOv5 最大優(yōu)勢之一就是訓(xùn)練門檻低但“低”指的是算法層面不是硬件層面。你至少要有一塊像樣的 NVIDIA 顯卡建議顯存 4GB 以上。沒有獨顯也能跑但訓(xùn)練速度會慘不忍睹一個幾百張圖片的小數(shù)據(jù)集可能都要幾小時。確認(rèn)顯卡驅(qū)動和 CUDA 是否可用的標(biāo)準(zhǔn)操作nvidia-smi如果命令提示找不到說明驅(qū)動沒裝好先去 NVIDIA 官網(wǎng)裝對應(yīng)驅(qū)動。如果顯示正常你會看到驅(qū)動版本和 CUDA 版本信息。注意nvidia-smi顯示的 CUDA 版本是驅(qū)動最高支持的版本不代表你一定需要安裝對應(yīng)版本的 CUDA ToolkitPyTorch 自帶 CUDA 運行庫你只需要合適的驅(qū)動。然后是選擇 PyTorch 版本。這一點很多人搞混pip install torch默認(rèn)安裝的是 CPU 版本必須在 PyTorch 官網(wǎng)選擇對應(yīng)的 CUDA 版本命令安裝。比如pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118這里的cu118對應(yīng) CUDA 11.8cu121對應(yīng) CUDA 12.1。選哪個取決于你的顯卡驅(qū)動官方支持穩(wěn)定版即可不用刻意追求最新。一個排查 GPU 是否生效的小技巧python -c import torch; print(torch.cuda.is_available())輸出True說明 GPU 可用。輸出False先檢查 PyTorch 裝的是不是 CPU 版本再看驅(qū)動版本夠不夠新。1.3 目錄規(guī)劃一次把工作區(qū)和數(shù)據(jù)集分開后面能省一半事最后是目錄規(guī)劃。我建議建一個干凈的 YOLOv5 工作根目錄結(jié)構(gòu)類似下面這樣project/ ├── datasets/ # 數(shù)據(jù)集 ├── yolo_v5/ # 項目代碼 ├── runs/ # 訓(xùn)練輸出 └── weights/ # 預(yù)訓(xùn)練權(quán)重為什么要把數(shù)據(jù)、代碼、輸出分開因為 YOLOv5 默認(rèn)會把訓(xùn)練結(jié)果保存在runs/目錄下數(shù)據(jù)集放在項目外能避免誤刪、避免 git 提交時把幾千張圖片帶進(jìn)去也方便多個項目復(fù)用同一份數(shù)據(jù)集。別嫌這一步啰嗦我見過太多人數(shù)據(jù)集和代碼混在一個目錄里最后git clean一執(zhí)行數(shù)據(jù)全沒了的慘案。2. 依賴安裝pip 命令之外這些坑經(jīng)常勸退新手環(huán)境搭好后正式進(jìn)入安裝環(huán)節(jié)。YOLOv5 官方倉庫提供了requirements.txt這是最標(biāo)準(zhǔn)和省事的方式。但“pip install”命令就一行真正讓人卡住的往往是網(wǎng)絡(luò)、權(quán)重下載和某些依賴的版本暗坑。2.1 克隆倉庫與依賴安裝版本鎖定的用意先克隆倉庫再安裝依賴git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txtrequirements.txt里的依賴項都帶有版本號或版本范圍這是官方在大量測試后鎖定的組合。比如opencv-python4.1.2、matplotlib3.2.2這些并不是隨便填的版本過低缺少函數(shù)版本過高可能出現(xiàn) API 變更導(dǎo)致腳本報錯。安裝時盡量一次性裝完不要手動一個個裝否則容易出現(xiàn)版本沖突。這里要特別說一個經(jīng)驗如果你在中國大陸網(wǎng)絡(luò)環(huán)境pip install下載大尺寸依賴包如 PyTorch很容易超時中斷最好提前設(shè)置鏡像源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple但注意下載 PyTorch 這種帶 CUDA 運行庫的包時鏡像源不一定有對應(yīng)版本PyTorch 官方源的穩(wěn)定性更高。我的習(xí)慣是PyTorch 用官方源裝其他依賴用鏡像源裝。2.2 第一次運行自動下載權(quán)重文件安裝完依賴后很多人直接開始訓(xùn)練結(jié)果卡在權(quán)重下載這一步。YOLOv5 的模型權(quán)重文件托管在國外服務(wù)器首次運行時會自動下載網(wǎng)絡(luò)差的話經(jīng)常失敗。解決辦法是手動下載。YOLOv5 官方提供的權(quán)重文件包括yolov5s.pt輕量版、yolov5m.pt中等版、yolov5l.pt重量版、yolov5x.pt超大版文件大小從十幾 MB 到 100 多 MB 不等。下載后將.pt文件放到項目根目錄或你規(guī)劃的weights/目錄即可。一個常見疑問是這幾個版本到底選哪個我做了一張表方便你快速決策模型版本參數(shù)大小約推理速度相對精度相對適用場景yolov5n1.9MB極快較低移動端/嵌入式y(tǒng)olov5s7.2MB快中等大多數(shù)常規(guī)場景yolov5m21MB中較高對精度有要求yolov5l47MB慢高離線分析yolov5x89MB很慢最高極致精度追求新手入門一律選yolov5s.pt它平衡了速度和精度顯存需求也低跑通整個流程之后再按需換大模型。2.3 常見報錯補(bǔ)充顯卡驅(qū)動、numpy 版本與路徑問題安裝和使用過程中有幾個高頻報錯我直接列出來你遇到就不用猜了。第一個報錯AssertionError: CUDA unavailable, invalid device 0 requested。這是 PyTorch 認(rèn)為你的環(huán)境沒有 CUDA前面用torch.cuda.is_available()檢查一下大概率是裝錯包了重裝 GPU 版 PyTorch 即可。第二個報錯numpy.ndarray size changed, may indicate binary incompatibility。這是典型的 numpy 版本和其他包不兼容通常是 numpy 升級后二進(jìn)制接口變了降低版本即可pip install numpy1.23.5第三個報錯FileNotFoundError: weights/yolov5s.pt。這不是代碼問題是權(quán)重文件路徑不對。檢查你啟動訓(xùn)練的命令是在哪個目錄下執(zhí)行的YOLOv5 相對路徑依賴很強(qiáng)建議統(tǒng)一在yolov5/項目根目錄下執(zhí)行命令。我在實際使用中發(fā)現(xiàn)requirements.txt里的依賴一旦裝好就不要再動不動pip install --upgrade某個包除非你明確知道自己在做什么。YOLOv5 這套代碼對依賴版本很敏感無意間升級了某個庫可能就讓整個流程跑不通。3. 數(shù)據(jù)集準(zhǔn)備訓(xùn)練前必須搞懂的 YOLO 格式核心邏輯安裝只是熱身數(shù)據(jù)集才是 YOLOv5 使用里最核心、也最容易被忽視的一環(huán)。很多教程在安裝完之后直接讓你用官方預(yù)訓(xùn)練權(quán)重跑圖片檢測這當(dāng)然可以但如果你是要訓(xùn)練自己的模型就必須深刻理解 YOLO 格式的數(shù)據(jù)集結(jié)構(gòu)。3.1 目錄結(jié)構(gòu)訓(xùn)練集、驗證集怎么擺放才叫規(guī)范YOLOv5 推薦的數(shù)據(jù)集目錄結(jié)構(gòu)是這樣datasets/ └── mydata/ ├── images/ │ ├── train/ # 訓(xùn)練圖片 │ └── val/ # 驗證圖片 ├── labels/ │ ├── train/ # 訓(xùn)練標(biāo)簽 │ └── val/ # 驗證標(biāo)簽 └── data.yaml # 數(shù)據(jù)配置文件圖片和標(biāo)簽的文件名必須一一對應(yīng)比如img_001.jpg對應(yīng)img_001.txt。圖片格式支持.jpg、.png、.bmp等常見格式但建議統(tǒng)一成.jpg因為 JPEG 壓縮更穩(wěn)定、讀取更快。標(biāo)簽文件是.txt純文本格式。訓(xùn)練集和驗證集的比例沒有固定標(biāo)準(zhǔn)但我的習(xí)慣是 8:2 或 9:1。注意驗證集不能和訓(xùn)練集有重復(fù)圖片否則驗證結(jié)果沒有參考意義。如果你沒有現(xiàn)成的劃分腳本用train_test_split或者直接按文件名哈希分都行關(guān)鍵是保證隨機(jī)。3.2 標(biāo)簽格式每行代表一個目標(biāo)五個數(shù)字缺一不可這是 YOLO 格式最核心的部分。每一個.txt標(biāo)簽文件里每一行對應(yīng)一張圖片中的一個目標(biāo)格式為object-class x_center y_center width height中間四個坐標(biāo)值全部是歸一化后的結(jié)果取值在 0 到 1 之間。歸一化的意思是x_center表示目標(biāo)中心點的橫坐標(biāo)占圖片寬度的比例y_center是縱坐標(biāo)占圖高的比例width、height同理。舉個例子一張 1000x800 的圖片里有一個目標(biāo)其邊界框左上角坐標(biāo)為 (200, 150)右下角坐標(biāo)為 (500, 650)。那么計算過程是x_center (200 500) / 2 / 1000 0.35 y_center (150 650) / 2 / 800 0.5 width (500 - 200) / 1000 0.3 height (650 - 150) / 800 0.625所以這一行就是0 0.35 0.5 0.3 0.625其中0代表類別 ID。我自己標(biāo)注數(shù)據(jù)的時候一般直接用 LabelImg 或 X-AnyLabeling 這類工具。標(biāo)注工具會自動生成 YOLO 格式的標(biāo)簽避免手算坐標(biāo)。但無論用什么工具保存之前一定要確認(rèn)導(dǎo)出格式是 YOLO而不是 VOC 或 COCO。3.3 data.yaml 配置文件把數(shù)據(jù)集的“說明書”寫對數(shù)據(jù)集文件準(zhǔn)備好之后在datasets/mydata/下新建data.yaml文件。這個文件就像一份說明書告訴 YOLOv5 數(shù)據(jù)在哪里、有幾類、類別叫什么。內(nèi)容如下train: datasets/mydata/images/train val: datasets/mydata/images/val nc: 2 names: [person, car]注意train和val指向的是圖片文件夾路徑不是標(biāo)簽路徑。YOLOv5 會根據(jù)同名規(guī)則自動去找標(biāo)簽。這個路徑是相對于你運行訓(xùn)練命令的目錄而言的所以如果你在yolov5/根目錄下執(zhí)行訓(xùn)練命令datasets/要和它同級或者寫成絕對路徑。nc是類別數(shù)量names是類別名稱列表。這里有個非常搞笑的坑名字列表的順序一定要和標(biāo)注時定義的類別 ID 一致。你在標(biāo)注軟件里把person定義為 0在 names 里就要把person放在第一位否則訓(xùn)練出來的模型會把你所有的標(biāo)簽張冠李戴。3.4 標(biāo)注時容易犯的幾個錯誤說到標(biāo)注我把新手最常犯的錯集中講一下。第一個錯誤一個標(biāo)注框里包含了太多背景。YOLO 要求標(biāo)注框盡量貼合目標(biāo)邊緣框得太大模型會把背景特征學(xué)進(jìn)去框得太小目標(biāo)特征不完整兩種情況都會影響檢測精度。第二個錯誤類別不平衡。如果數(shù)據(jù)集里一類有兩千張圖另一類只有五十張圖模型大概率會把少數(shù)類忽略掉。這種情況可以收集更多少數(shù)類樣本或者用腳本做簡單過采樣。第三個錯誤圖片里有目標(biāo)但沒標(biāo)出來。這會產(chǎn)生“漏檢”樣本模型被隱性地告知“這里沒有目標(biāo)”后續(xù)極其容易誤判。每次標(biāo)完一批數(shù)據(jù)我建議用可視化腳本把標(biāo)簽畫到圖片上檢查一遍YOLOv5 里可以直接用detect.py配合--save-txt反過來檢查標(biāo)注質(zhì)量也可以用其它開源可視化工具。4. 開始訓(xùn)練參數(shù)、監(jiān)控與結(jié)果解讀一次跑通的基本功數(shù)據(jù)集準(zhǔn)備好環(huán)境沒問題就可以進(jìn)入訓(xùn)練環(huán)節(jié)了。YOLOv5 的訓(xùn)練命令本身不復(fù)雜真正值得講清楚的是參數(shù)的含義以及訓(xùn)練過程中應(yīng)該看什么、怎么判斷模型練得好不好。4.1 訓(xùn)練命令與核心參數(shù)解析最基礎(chǔ)的訓(xùn)練命令python train.py --img 640 --batch 16 --epochs 100 --data datasets/mydata/data.yaml --weights yolov5s.pt每個參數(shù)我都拆開講一下--img是訓(xùn)練時輸入的圖片尺寸。YOLOv5 會把所有訓(xùn)練圖片統(tǒng)一縮放到這個尺寸默認(rèn)是 640。它直接決定了模型的輸入分辨率和顯存占用一般用 640 起步如果你的目標(biāo)是小物體可以試試 1280但顯存需求會成倍增長。--batch是批大小。它表示一次輸入多少張圖片到 GPU 進(jìn)行訓(xùn)練。批大小由顯存決定顯存 8GB 的話 16 比較穩(wěn)妥顯存 4GB 就降到 8 或更低。批大小不宜過小否則梯度更新太頻繁收斂不穩(wěn)定。--epochs是訓(xùn)練輪數(shù)。小數(shù)據(jù)集 100-300 輪足夠大規(guī)模數(shù)據(jù)集可以 300-500。不是越多越好后面我會教你判斷什么時候該停。--weights指預(yù)訓(xùn)練權(quán)重。用yolov5s.pt會自動下載并加載官方在 COCO 數(shù)據(jù)集上訓(xùn)練好的權(quán)重這叫做遷移學(xué)習(xí)。比從零訓(xùn)練收斂更快、精度更高。如果想從頭訓(xùn)練改成--weights 即可。另一個很重要的參數(shù)是--cache。它表示把數(shù)據(jù)提前緩存到內(nèi)存中省去每次迭代都從磁盤讀圖的 IO 時間訓(xùn)練速度能提升不少。顯存夠用的話建議加上python train.py --img 640 --batch 16 --epochs 100 --data datasets/mydata/data.yaml --weights yolov5s.pt --cache4.2 訓(xùn)練過程監(jiān)控怎么判斷模型在變好還是過擬合訓(xùn)練啟動后終端會不斷打印日志同時會在runs/train/exp目錄下生成訓(xùn)練結(jié)果。你需要看三樣?xùn)|西loss 曲線、PR 曲線和驗證集精度。loss 分為三部分box_loss邊框回歸損失、obj_loss目標(biāo)置信度損失、cls_loss分類損失。訓(xùn)練初期 loss 會快速下降中后期下降變慢這很正常。真正需要注意的是 val loss也就是驗證集上的損失。如果 train loss 一直降、val loss 反而上升說明模型開始過擬合了這時應(yīng)該停掉訓(xùn)練或增加數(shù)據(jù)增強(qiáng)。訓(xùn)練結(jié)束后重點看results.png里的 PPrecision 精確率、RRecall 召回率、mAP平均精度均值。這里我給大家一個通俗解釋精確率是“你檢測出來的框里有多少是對的”召回率是“真實目標(biāo)里你有多少找出來了”mAP 是兩者的綜合指標(biāo)。對于絕大多數(shù)自定義場景mAP0.5 達(dá)到 0.9 以上就算非常好了。如果只有 0.5 左右先別急著調(diào)參一般先從數(shù)據(jù)下手檢查標(biāo)注對不對、樣本夠不夠、是否類別失衡。4.3 斷點續(xù)訓(xùn)與學(xué)習(xí)率調(diào)整訓(xùn)練是一件很耗時的事哪怕用 GPU幾百張圖片的幾輪訓(xùn)練也可能要幾個小時。YOLOv5 支持自動保存最新權(quán)重last.pt和最優(yōu)權(quán)重best.pt。如果你中途斷了不需要重新跑直接執(zhí)行python train.py --img 640 --batch 16 --epochs 100 --data datasets/mydata/data.yaml --weights runs/train/exp/weights/last.pt這就是斷點續(xù)訓(xùn)接著上次的進(jìn)度繼續(xù)。這是一個非常實用的功能我自己訓(xùn)練的時候基本都會提前規(guī)劃好訓(xùn)練輪數(shù)但總會因為各種意外中斷斷點續(xù)訓(xùn)省下的時間非??捎^。另外新手容易忽略的一個參數(shù)是--patience它表示如果驗證集精度連續(xù)多少輪沒有提升就提前終止訓(xùn)練。默認(rèn)是 100意思是 100 輪沒進(jìn)步就自動停。這個機(jī)制很好用能幫你節(jié)省大量時間。實際使用中我一般設(shè)置成 30-50讓它在精度上升乏力時及時止損。5. 推理檢測從命令行到 Python 調(diào)用把模型用起來訓(xùn)練完模型總算進(jìn)入“展示成果”的階段了。YOLOv5 既提供了簡單的命令行方式也提供了靈活的 Python 接口。這個環(huán)節(jié)我會兩種都講因為日常快速驗證用命令行但真正嵌入項目時幾乎都是寫 Python 調(diào)用。5.1 命令行推理一行命令搞定圖片和視頻檢測使用訓(xùn)練好的best.pt對圖片進(jìn)行檢測python detect.py --weights runs/train/exp/weights/best.pt --source test_images/ --conf-thres 0.25--source可以是單張圖片、圖片文件夾、視頻文件甚至可以是攝像頭編號。比如用攝像頭實時檢測python detect.py --weights runs/train/exp/weights/best.pt --source 0--conf-thres是置信度閾值默認(rèn) 0.25也就是說模型認(rèn)為某個框有 25% 以上的概率是目標(biāo)才會畫出來。閾值調(diào)高框更少但更準(zhǔn)調(diào)低框更多但誤檢也會變多。這個參數(shù)沒有絕對標(biāo)準(zhǔn)實際部署時你需要根據(jù)自己的場景調(diào)一版比如寧可漏檢不要誤檢就把閾值調(diào)到 0.4 甚至 0.5。運行結(jié)束后檢測結(jié)果會保存在runs/detect/exp目錄下圖片上已經(jīng)畫好了邊界框、類別標(biāo)簽和置信度。命令行方式能滿足大部分預(yù)覽需求但它的問題在于每次都要加載模型、解析參數(shù)、跑完整流程。如果你要在一個已有的業(yè)務(wù)系統(tǒng)里調(diào)用檢測能力絕對不適合用命令行方式。5.2 Python 接口加載模型、推理與結(jié)果解析YOLOv5 官方直接支持通過 Python 方式加載模型非常簡單import torch model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/exp/weights/best.pt)這里path指向你自己的權(quán)重文件。加載之后就可以對圖片進(jìn)行推理img test_images/001.jpg results model(img)results對象包含很多好東西。我這里給你展示最常用的幾個屬性# 獲取邊界框坐標(biāo)、置信度、類別ID boxes results.xyxy[0] # 每行: x1, y1, x2, y2, conf, class # 顯示檢測結(jié)果 results.show() # 保存檢測結(jié)果 results.save(output/)如果你要在服務(wù)端部署絕對不建議再用model.show()這種帶 GUI 的調(diào)用方式。更專業(yè)的做法是把檢測結(jié)果轉(zhuǎn)成結(jié)構(gòu)化數(shù)據(jù)detections results.pandas().xyxy[0] for _, row in detections.iterrows(): x1, y1, x2, y2 int(row[xmin]), int(row[ymin]), int(row[xmax]), int(row[ymax]) conf row[confidence] cls_name row[name] print(f類別: {cls_name}, 置信度: {conf:.2f}, 坐標(biāo): ({x1},{y1})-({x2},{y2}))這一段代碼基本就是你在實際業(yè)務(wù)中處理 YOLOv5 輸出時的雛形。無論你接的是拍照檢測、視頻分析還是實時流處理前面加個讀取幀/圖片后面加個邏輯處理整個鏈路就通了。5.3 攝像頭或視頻流檢測的顯存注意點很多人興致勃勃跑攝像頭實時檢測結(jié)果發(fā)現(xiàn)視頻非??◣手挥袀€位數(shù)。這是因為業(yè)務(wù)邏輯沒優(yōu)化。YOLOv5 的默認(rèn)推理方式是每幀調(diào)用一次完整前向傳播而視頻每秒鐘有 20-30 幀對 GPU 的消耗非常大。簡單的優(yōu)化手段是跳幀檢測不是每一幀都做檢測而是每隔幾幀檢測一次比如每 3 幀檢測一次。這個策略對大部分場景完全夠用畢竟目標(biāo)不會在 100 毫秒內(nèi)憑空消失。另外檢測前把輸入圖片縮放到更小的尺寸也能顯著提速比如從 640 降到 416幀率能提升一半以上精度下降卻不太明顯。6. 模型導(dǎo)出從 PyTorch 到 ONNX部署前的最后一步模型訓(xùn)練好、驗證好真正要落地到生產(chǎn)環(huán)境還需要做模型導(dǎo)出。YOLOv5 官方提供了一鍵導(dǎo)出功能支持導(dǎo)出為 ONNX、TorchScript、TensorRT 等格式。把這一步講清楚是因為很多人在“跑通檢測”之后卡在了部署模型在開發(fā)機(jī)上運行良好換一臺機(jī)器換成其他框架就完全跑不起來了。6.1 ONNX 導(dǎo)出跨平臺部署的標(biāo)準(zhǔn)動作ONNXOpen Neural Network Exchange是一種跨框架的模型中間表示格式可以理解成“模型界的通用語言”。導(dǎo)出 ONNX 的步驟如下python export.py --weights runs/train/exp/weights/best.pt --include onnx --img 640導(dǎo)出的文件叫best.onnx放在權(quán)重同目錄下。之后你可以用 ONNX Runtime 加載它在完全不依賴 PyTorch 的環(huán)境下運行import onnxruntime as ort import numpy as np import cv2 sess ort.InferenceSession(best.onnx) input_name sess.get_inputs()[0].name img cv2.imread(test.jpg) img cv2.resize(img, (640, 640)) img img[:, :, ::-1].transpose(2, 0, 1) # BGR - RGB, HWC - CHW img np.ascontiguousarray(img, dtypenp.float32) / 255.0 img np.expand_dims(img, axis0) outputs sess.run(None, {input_name: img})ONNX 導(dǎo)出的最大價值在于部署靈活性你的模型現(xiàn)在可以被 C、Java、C# 等任意語言調(diào)用可以部署在云服務(wù)器也可以部署在邊緣設(shè)備完全繞開了 Python 和 PyTorch 的依賴。6.2 導(dǎo)出時的常見問題動態(tài)尺寸和結(jié)果解析差異導(dǎo)出和使用 ONNX 時有兩個容易踩的坑。第一個坑是輸入尺寸固定問題。默認(rèn)情況下導(dǎo)出時指定的--img 640會把模型的輸入尺寸固定為 640x640。如果你需要用其他尺寸推理可以在導(dǎo)出時加上--dynamic讓 ONNX 模型支持動態(tài)輸入尺寸但要注意動態(tài)尺寸的推理速度通常會略慢一些。第二個坑是輸出解析差異。PyTorch 推理時results.xyxy已經(jīng)幫你把預(yù)測結(jié)果解析成了好理解的左上角右下角坐標(biāo)。但 ONNX 模型的原始輸出是一個高維數(shù)組需要你自己解析邊界框、置信度和類別。這個過程涉及 NMS非極大值抑制比較復(fù)雜。我建議新手不要改動 YOLOv5 的推理倉庫直接復(fù)用官方提供的models/experimental.py或者用輔助工具庫處理可以少掉很多頭發(fā)。6.3 TensorRT 導(dǎo)出極致推理速度的一條小路如果你的部署環(huán)境是 NVIDIA 的 GPU那 TensorRT 是繞不開的加速手段。它可以對模型做層融合和精度校準(zhǔn)FP16/INT8推理速度通常能提升兩到三倍。導(dǎo)出命令也很簡單python export.py --weights runs/train/exp/weights/best.pt --include engine --half--half表示使用半精度 FP16推理速度更快顯存占用更少。但要注意TensorRT 導(dǎo)出的.engine文件是與 GPU 型號強(qiáng)相關(guān)的在 A 卡上導(dǎo)出的引擎不一定能在 B 卡上運行換機(jī)器必須重新導(dǎo)出。7. 訓(xùn)練效果提升數(shù)據(jù)與超參數(shù)的幾個實用調(diào)整思路安裝、訓(xùn)練、檢測、導(dǎo)出全流程已經(jīng)跑通。最后我想分享一些我長期使用 YOLOv5 后總結(jié)的提效經(jīng)驗這些不是官方文檔里會寫的東西但確實能幫你少走彎路。7.1 數(shù)據(jù)質(zhì)量比模型參數(shù)更重要如果把 YOLOv5 用的時間拉長到幾個項目你會發(fā)現(xiàn)一個規(guī)律數(shù)據(jù)集質(zhì)量決定了精度的上限模型參數(shù)只是逼近這個上限。同一個模型我用質(zhì)量差的數(shù)據(jù)集訓(xùn)練到 mAP 0.6 后無論如何調(diào)參都上不去換成清洗過得當(dāng)?shù)臄?shù)據(jù)后不做任何調(diào)整精度直接沖到 0.92。差距不在模型在數(shù)據(jù)。所以當(dāng)精度不理想時第一反應(yīng)不應(yīng)該是網(wǎng)上找各種魔改模型而是回頭檢查數(shù)據(jù)標(biāo)注框貼合度、誤標(biāo)漏標(biāo)、類別平衡、場景多樣性把這些做扎實之后再考慮參數(shù)優(yōu)化。7.2 數(shù)據(jù)增強(qiáng)的克制使用YOLOv5 自帶了相當(dāng)豐富的數(shù)據(jù)增強(qiáng)策略比如隨機(jī)翻轉(zhuǎn)、縮放、拼接Mosaic等。理解這些增強(qiáng)策略之后有一個常見的錯誤是為了追求“更強(qiáng)的泛化性”人為把增強(qiáng)參數(shù)拉滿結(jié)果訓(xùn)練出來的模型在驗證集上表現(xiàn)極差。增強(qiáng)要適度。訓(xùn)練小數(shù)據(jù)集時建議保留默認(rèn)增強(qiáng)策略即可不要做太多自定義改動。真實世界的項目場景優(yōu)先保證驗證集和測試集與部署環(huán)境盡量一致而不是指望數(shù)據(jù)增強(qiáng)能彌補(bǔ)數(shù)據(jù)分布差異。7.3 遷移學(xué)習(xí)里的“凍結(jié)訓(xùn)練”技巧如果項目里可用的標(biāo)注數(shù)據(jù)很少比如幾百張可以考慮先凍結(jié)主干網(wǎng)絡(luò)、只訓(xùn)練檢測頭等 loss 穩(wěn)定后再解凍全部層訓(xùn)練。YOLOv5 里可以直接通過--freeze參數(shù)指定凍結(jié)前多少層python train.py --img 640 --batch 16 --epochs 50 --data datasets/mydata/data.yaml --weights yolov5s.pt --freeze 10這種做法在數(shù)據(jù)量有限時能有效避免過擬合因為預(yù)訓(xùn)練主干網(wǎng)絡(luò)已經(jīng)學(xué)到過通用的視覺特征你只需要讓它適配你當(dāng)前任務(wù)的檢測邏輯。等第一階段訓(xùn)練完畢去掉--freeze參數(shù)再繼續(xù)訓(xùn)練完整模型泛化效果通常比直接完整訓(xùn)練好不少。我最近一個項目就是用這個思路在只有 700 多張圖片的情況下把一個小目標(biāo)檢測場景的 mAP 從 0.67 拉到了 0.85而且訓(xùn)練時間比從頭完整訓(xùn)練還短。如果你的數(shù)據(jù)集不大這個技巧值得認(rèn)真試試。8. 寫在最后的一點體會YOLOv5 這個東西網(wǎng)上教程多如牛毛動不動號稱“超詳細(xì)”但大部分都停留在 command 復(fù)述層面。真正讓你成長的是理解每一步操作背后的原因為什么用那個倉庫、為什么數(shù)據(jù)集要這么放、為什么調(diào)那個參數(shù)以及精度不行時從哪下手排查。我在實際使用中還有一個習(xí)慣每次訓(xùn)練完都會在runs/train/目錄外另存一份訓(xùn)練配置副本包括data.yaml、訓(xùn)練命令參數(shù)和best.pt的 mAP 指標(biāo)。這樣一個月后回頭想調(diào)模型時不用靠記憶猜當(dāng)時怎么訓(xùn)的直接翻記錄就能完整復(fù)現(xiàn)。這個習(xí)慣看起來不起眼但對長期維護(hù)模型幫助極大。另外如果你打算把 YOLOv5 用到自己的業(yè)務(wù)里建議嚴(yán)格控制版本不要頻繁升級項目倉庫。它本身已經(jīng)非常成熟不會因為新功能頻繁變動而給你帶來額外收益。用熟一個版本、吃透一套流程比天天追新版本更重要。這是我看過無數(shù)人折騰之后最想說的一句話。