據(jù)集整理與YOLO11cls訓練避坑指南)
簡介面向水稻葉病蟲害識別任務(wù)的中文分類數(shù)據(jù)集資源適合算法工程師與農(nóng)業(yè)AI研究者用于模型訓練與場景驗證。數(shù)據(jù)集包含細菌性葉枯病、褐斑病、健康葉片、葉瘟病、葉鞘腐病、窄褐斑病、穗頸瘟、稻飛虱、紋枯病、鎢黃病毒病共10個類別共15000張真實環(huán)境下的高質(zhì)量水稻葉片圖片按類別文件夾整理標注規(guī)范可直接用于YOLO11cls等分類算法的訓練與評估。壓縮包內(nèi)僅含1個PDF文件大小2.32MB因原始數(shù)據(jù)體量較大托管在百度網(wǎng)盤PDF內(nèi)附數(shù)據(jù)集基本情況說明及百度網(wǎng)盤獲取方式。目前已有318人學習適合作為水稻病蟲害實際項目落地或通用分類數(shù)據(jù)集擴充的參考。附贈YOLO11cls一鍵訓練腳本及博主訓練結(jié)果日志可幫助讀者快速復現(xiàn)訓練流程并觀察各類別識別效果降低從數(shù)據(jù)到模型的搭建門檻。1. 水稻葉病蟲害分類數(shù)據(jù)集配YOLO11cls15000張圖真正要解決的是數(shù)據(jù)組織問題真正的瓶頸從來不是YOLO11cls模型本身而是你手頭有一堆水稻葉病蟲害照片時不知道哪些圖該歸到哪一類、病斑長相近的類別怎么和模型說清楚。目標分類任務(wù)看名字簡單做起來卻很現(xiàn)實15000張圖如果只是堆在一個目錄里YOLO11cls訓練時就會把背景、光照、拍攝角度一起學進去準確率再高也不敢下田用。這套分類文件夾整理與YOLO11cls一鍵訓練腳本的組合解決的正是從散裝圖片到可復用分類模型之間的臟活先把圖按類別歸好再用腳本完成劃分、訓練、驗證。適合剛拿到水稻葉病蟲害圖像、準備訓練第一個分類模型的工程師也適合用yolov5或yolov8訓練過自己數(shù)據(jù)集、想轉(zhuǎn)到Y(jié)OLO11cls的從業(yè)者。2. 先弄懂分類文件夾整理的含義YOLO11cls需要的只是目錄不是標注文件2.1 分類文件夾為什么比任何標注格式都省心檢測任務(wù)要畫框分割任務(wù)要畫mask而目標分類任務(wù)只需要一個約定同一類別的圖片放在同名文件夾里文件夾名就是標簽。這個約定在深度學習里叫ImageNet風格目錄結(jié)構(gòu)YOLO11cls的classification模式原樣繼承了這個設(shè)計。你不需要寫xml不需要寫txt不需要標注框坐標分類任務(wù)的全部標注信息都藏在目錄名里。數(shù)據(jù)格式選什么直接決定后面腳本的復雜程度。我見過不少從檢測轉(zhuǎn)過來的朋友第一反應(yīng)是給圖片寫標注文件其實分類任務(wù)根本不需要。你只要保證數(shù)據(jù)集根目錄下每個類別一個文件夾里面放好對應(yīng)圖片即可。15000張圖聽起來很多但如果按8個類別來分平均每個類別不到2000張這個量級做微調(diào)是夠用的。真正要小心的不是總數(shù)而是類別之間有沒有人肉眼都分不清的相近病斑這會在第五章驗證部分細說。如果數(shù)據(jù)已經(jīng)按類別分好文件夾最終要形成的標準目錄結(jié)構(gòu)是這樣的rice_leaf_dataset_split/ ├── train/ │ ├── leaf_blast/ # 稻葉瘟 │ │ ├── leaf_blast_0001.jpg │ │ ├── leaf_blast_0002.jpg │ │ └── ... │ ├── leaf_blight/ # 白葉枯 │ ├── brown_spot/ # 胡麻葉斑病 │ ├── sheath_blight/ # 紋枯病 │ └── healthy/ # 健康葉 └── val/ ├── leaf_blast/ ├── leaf_blight/ ├── brown_spot/ ├── sheath_blight/ └── healthy/注意我們用的是train和val兩層結(jié)構(gòu)而不是把15000張圖全部塞進類別文件夾里直接開訓。Ultralytics的classify接口接收data參數(shù)時默認按train和val兩個子目錄去找圖如果你的數(shù)據(jù)一開始沒有劃分腳本里就得自己切。這也解釋了為什么對應(yīng)分類文件夾整理這么重要——目錄結(jié)構(gòu)對了后面腳本能寫得很薄目錄結(jié)構(gòu)不對腳本會寫出一堆補丁邏輯來收拾數(shù)據(jù)。2.2 別把整理任務(wù)做成手工活用Python把散圖歸到類別文件夾手里圖片的命名通常是不規(guī)律的常見有一批按采集時間命名一批按病害拼音縮寫命名。最穩(wěn)妥的做法是先寫一個掃描腳本把圖片預(yù)覽和文件名輸出成清單人工確認幾輪再交給腳本去搬。單純的復制粘貼在Windows資源管理器里做幾千張還行做到上萬張就容易漏而且無法復現(xiàn)。下面是一個整理腳本它假設(shè)你的原始圖片已經(jīng)按類別放了子目錄類別子目錄名就是要用的標簽import os import shutil from collections import Counter src_root raw_images # 原始圖片目錄里面按類別分好了子目錄 dst_root rice_leaf_dataset # 整理后的數(shù)據(jù)集根目錄 class_labels sorted([ d for d in os.listdir(src_root) if os.path.isdir(os.path.join(src_root, d)) ]) for cls in class_labels: src_cls_dir os.path.join(src_root, cls) for img_name in os.listdir(src_cls_dir): if not img_name.lower().endswith((.jpg, .jpeg, .png)): continue dst_cls_dir os.path.join(dst_root, cls) os.makedirs(dst_cls_dir, exist_okTrue) shutil.copy2( os.path.join(src_cls_dir, img_name), os.path.join(dst_cls_dir, img_name), ) stat Counter() for cls in os.listdir(dst_root): cls_dir os.path.join(dst_root, cls) if os.path.isdir(cls_dir): stat[cls] len([ f for f in os.listdir(cls_dir) if f.lower().endswith((.jpg, .jpeg, .png)) ]) print(整理完成各類別圖片數(shù)) for cls, n in stat.most_common(): print(f{cls}: {n})這段腳本的邏輯是先掃描原始目錄下有哪些類別子目錄類別名直接作為標簽然后把每張圖片復制到目標目錄的對應(yīng)類別文件夾里。復制而不是移動是為了保留原始素材萬一類別分錯了還能重來。最后用Counter統(tǒng)計每個類別的圖片數(shù)量這一步非常重要類別不平衡會讓模型看起來準確率很高、實際卻在偷懶第四章會專門講。有個高頻翻車點文件名里帶中文或空格。Ultralytics框架本身能處理中文路徑但不同操作系統(tǒng)的路徑編碼不統(tǒng)一容易出現(xiàn)能找到文件但打不開的怪問題。我一般會在整理階段就把文件名統(tǒng)一改成英文字母加數(shù)字例如leaf_blast_0001.jpg這樣做的好處是后面換服務(wù)器、換操作系統(tǒng)都不會因為路徑編碼問題突然報錯。2.3 數(shù)據(jù)體檢損壞圖片與重復圖片的排查整理完目錄后不要急著訓練先跑一遍體檢。最常見的雷是下載或拷貝過程中圖片文件損壞PIL讀不出來或者同一張圖被保存了多個尺寸版本導致訓練集和驗證集之間出現(xiàn)近重復樣本讓驗證指標虛高。from PIL import Image import os data_root rice_leaf_dataset bad_files [] for cls in os.listdir(data_root): cls_dir os.path.join(data_root, cls) if not os.path.isdir(cls_dir): continue for img_name in os.listdir(cls_dir): img_path os.path.join(cls_dir, img_name) try: with Image.open(img_path) as im: im.verify() # 只檢查文件結(jié)構(gòu)不加載完整像素 except Exception: bad_files.append(img_path) print(f發(fā)現(xiàn) {len(bad_files)} 個損壞文件) for p in bad_files[:20]: print(p)這里有個小坑Image.verify()調(diào)用之后這張圖的句柄就失效了如果你想繼續(xù)對圖像做處理需要重新open一次。所以上面代碼里用with Image.open包住就是為了防止后續(xù)誤用同一個句柄。重復圖片的去重我一般不在這一步做因為分類任務(wù)對少量重復并不敏感。但需要注意如果某個類別的圖大量來自同一塊田、同一個拍攝角度就要警惕了。最粗暴的檢查方法是把圖片縮小到16x16再算哈希把相似度高的圖挑出來。這個動作不是必須的但能防止驗證集里混入訓練圖的影子后面判斷模型是否真的泛化時會省很多力氣。3. 拆解YOLO11cls一鍵訓練腳本五個關(guān)鍵參數(shù)與一條能真正跑通的命令3.1 從一堆文件夾到開始訓練腳本替你做了哪三步Ultralytics提供的YOLO11cls用法核心其實就一行把數(shù)據(jù)根目錄傳給train方法模型用預(yù)訓練權(quán)重初始化。但真正的一鍵訓練腳本不應(yīng)該只是封裝這一行。常見做法是腳本要先做三件事檢查目錄結(jié)構(gòu)、按固定種子劃分訓練驗證集、把模型和超參固定下來保證兩次訓練之間只改一個變量。用yolov5或yolov8訓練過自己數(shù)據(jù)集的人對這套流程肯定不陌生先準備data.yaml再寫train命令然后盯日志。YOLO11cls把data.yaml弱化了分類模式下直接給根目錄內(nèi)部按train和val兩個子目錄去讀圖。這也是為什么整理階段的目錄結(jié)構(gòu)會直接影響腳本復雜度——目錄對了腳本可以寫得很薄目錄不對腳本就得花一堆代碼去補數(shù)據(jù)坑。下面這份是我常用的訓練腳本骨架可以直接改成自己的數(shù)據(jù)集路徑import argparse import os import random import shutil from ultralytics import YOLO def prepare_split(root: str, val_ratio: float 0.2, seed: int 42) - str: 確保數(shù)據(jù)目錄是 train/val 結(jié)構(gòu)返回可直接傳給 YOLO 的目錄。 entries os.listdir(root) if train in entries and val in entries: print(已存在 train/val 結(jié)構(gòu)直接使用原目錄) return root out_root root _split random.seed(seed) classes sorted([ d for d in entries if os.path.isdir(os.path.join(root, d)) ]) for cls in classes: cls_dir os.path.join(root, cls) images sorted([ f for f in os.listdir(cls_dir) if f.lower().endswith((.jpg, .jpeg, .png)) ]) random.shuffle(images) n_val max(1, int(len(images) * val_ratio)) for split_name, split_images in ( (train, images[n_val:]), (val, images[:n_val]), ): dst_dir os.path.join(out_root, split_name, cls) os.makedirs(dst_dir, exist_okTrue) for f in split_images: shutil.copy2( os.path.join(cls_dir, f), os.path.join(dst_dir, f), ) print(f已生成劃分后的數(shù)據(jù)集目錄: {out_root}) return out_root def parse_args(): parser argparse.ArgumentParser(descriptionYOLO11cls 水稻葉病蟲害分類訓練) parser.add_argument(--data, typestr, defaultrice_leaf_dataset, help數(shù)據(jù)集根目錄包含 train/val 或直接是類別文件夾) parser.add_argument(--model, typestr, defaultyolo11cls.pt, help預(yù)訓練權(quán)重支持本地路徑或框架內(nèi)置名稱) parser.add_argument(--epochs, typeint, default100) parser.add_argument(--batch, typeint, default16) parser.add_argument(--imgsz, typeint, default224) parser.add_argument(--seed, typeint, default42) parser.add_argument(--val-ratio, typefloat, default0.2) parser.add_argument(--workers, typeint, default4) return parser.parse_args() def main(): args parse_args() data_dir prepare_split(args.data, args.val_ratio, args.seed) model YOLO(args.model) model.train( datadata_dir, epochsargs.epochs, batchargs.batch, imgszargs.imgsz, seedargs.seed, workersargs.workers, ) model.val() if __name__ __main__: main()這段代碼里prepare_split函數(shù)是關(guān)鍵。它先檢查數(shù)據(jù)根目錄下是否已經(jīng)有train和val兩個子目錄有就直接用沒有就按類別文件夾自動切分。注意兩點一是classes和images都做了sorted排序再在隨機種子下shuffle避免不同操作系統(tǒng)里os.listdir返回順序不一致導致劃分結(jié)果對不上二是生成的新目錄是root加上_split后綴不污染原始類別文件夾。為什么不直接在原目錄里創(chuàng)建train和val因為原始類別文件夾還留在根目錄里如果Ultralytics掃描根目錄可能會把train、val之外的多余文件夾也當成類別。把劃分結(jié)果放到獨立的root_split目錄從結(jié)構(gòu)上避開這個坑。train部分直接調(diào)用YOLO(args.model)再train模型參數(shù)可以傳本地權(quán)重路徑也可以傳框架預(yù)置的模型名。如果你不想讓腳本每次下載權(quán)重就把權(quán)重文件放在腳本同級目錄并把--model改成對應(yīng)的路徑。訓練結(jié)束后model.val()會加載best.pt做驗證省得手動換權(quán)重。3.2 五個必調(diào)參數(shù)epochs、batch、imgsz、model、seed理解和調(diào)整參數(shù)是腳本里真正值錢的部分。先看參數(shù)表參數(shù)常見取值范圍影響備注modelyolo11cls.pt / yolo11s-cls.pt模型容量與速度的取舍數(shù)據(jù)量小選輕量版epochs50200訓練輪次決定擬合程度看val曲線收斂再停batch864顯存占用與梯度穩(wěn)定性batch太小loss震蕩imgsz224 / 256 / 320輸入分辨率影響細粒度紋理病斑小的建議256起seed固定一個整數(shù)復現(xiàn)性不固定沒法對比實驗epochs不要無腦開大。水稻葉病蟲害分類里類間差異往往集中在病斑的紋理和顏色上如果訓練集只有一兩千張一類跑200輪很容易過擬合。我一般先跑100輪看val的top1曲線在哪個epoch后不再上升再用早停或直接在該輪數(shù)附近重跑。Ultralytics本身不自動早停腳本里可以觀察日志后手動決定也可以外部包一層early stopping。batch和imgsz之間是顯存博弈。imgsz224時batch32大概需要6到8GB顯存如果顯卡只有8GB優(yōu)先把batch降到16而不是把imgsz降到160——分辨率太低時水稻葉片上毫米級的病斑紋理細節(jié)會直接丟失。目標分類模型對輸入分辨率比檢測任務(wù)更敏感因為整張圖只產(chǎn)出一個類別判斷特征全在全局信息和紋理統(tǒng)計里。model參數(shù)看起來簡單實際上決定了下限。選yolo11cls.pt作為預(yù)訓練權(quán)重相當于把ImageNet上訓練的通用視覺特征遷移過來對細粒度病害識別幫助很大。如果你的類別數(shù)和圖量都不大不需要從隨機權(quán)重開始練那會慢得讓人懷疑人生。seed這個參數(shù)最容易被忽略。很多人用yolov8訓練自己的數(shù)據(jù)集時發(fā)現(xiàn)同樣代碼跑兩次accuracy差兩三個點其實不是代碼寫錯了而是數(shù)據(jù)劃分、增強、權(quán)重初始化里的隨機性沒有被鎖住。YOLO11cls的train方法支持seed參數(shù)腳本里務(wù)必把它暴露成命令行參數(shù)我的默認值是42至少保證同一份數(shù)據(jù)、同一個種子下結(jié)果可復現(xiàn)。3.3 訓練中斷與續(xù)訓last.pt和best.pt的分工訓練到一半斷電或顯存溢出是家常便飯。Ultralytics在訓練過程中會同時保存兩份權(quán)重last.pt用來續(xù)訓best.pt用來做最終評估。續(xù)訓命令很簡單python train.py --model runs/classify/train/weights/last.pt --data rice_leaf_dataset --epochs 100這里有個容易誤解的地方--epochs在續(xù)訓時表示的是總輪次而不是剩余輪次。如果你上次跑了80輪這次想補20輪要把epochs設(shè)成100不是20否則相當于又從頭跑了100輪。這個細節(jié)我在初用Ultralytics時踩過翻車的原因就是想當然地以為傳剩余輪次就行。另一個常見問題是修改batch后繼續(xù)訓。加載last.pt繼續(xù)訓練時優(yōu)化器的學習率狀態(tài)會延續(xù)但如果把batch從16改成32學習率最好也按比例調(diào)整否則loss曲線可能突然跳變。分類任務(wù)對學習率沒那么敏感但遇到loss反而升高的情況先檢查是不是這個原因。4. 避坑水稻葉分類訓練最常翻車的五個位置4.1 類別不平衡96%的準確率可能只是稻瘟病猜對了現(xiàn)象訓練結(jié)束打印accuracy讀到0.96很興奮。打開混淆矩陣一看leaf_blast類別的recall接近1而brown_spot類別的recall只有0.3多數(shù)類把少數(shù)類完全淹沒了。原因數(shù)據(jù)集中稻瘟病圖特別多比如有7000張胡麻葉斑病只有500張。模型優(yōu)化的是整體loss少數(shù)類貢獻的梯度占比太小學到一定程度后模型就選擇偷懶——把不確定的樣本都猜成多數(shù)類。這就是為什么分類任務(wù)里單看accuracy會騙人。解決先看類別統(tǒng)計再決定要不要做平衡。常見做法有三種一是給少數(shù)類做離線增強旋轉(zhuǎn)、裁剪、顏色擾動都可以但注意不要把增強樣本直接復制粘貼進原始文件夾否則訓練集和驗證集可能混入近似重復圖二是在腳本里給少數(shù)類加權(quán)YOLO11cls的分類頭沒有直接暴露class_weight參數(shù)我一般用采樣策略三是硬性設(shè)定每個類別的最小訓練張數(shù)不足的用同一病斑的多個角度補拍。和PlantDoc這類公開植物病害集不同水稻葉病蟲害分類沒有開箱即用的標準庫自己采集整理仍然是主流這反而要求你在采集階段就盡量均勻。4.2 背景噪聲被當成病害特征換塊田就失效現(xiàn)象訓練集上accuracy很高但拿手機新拍幾張不同背景的水稻葉照片去推理預(yù)測結(jié)果明顯亂掉甚至把健康的葉子判成稻瘟病。原因拍攝時稻葉后面有土壤、水面、稻穗模型學到的是有土壤和水面的圖等于稻瘟病而不是病斑本身。分類模型不會自動忽略背景它只會統(tǒng)計哪個區(qū)域和標簽最相關(guān)。尤其水稻葉病害的早期病斑面積很小背景像素在整張圖里占比極大模型很容易走捷徑。解決整理階段統(tǒng)一把葉片主體裁出來或者至少把背景面積控制在一小部分。裁剪時不要用固定框硬切因為水稻葉細長最好先做簡單的顏色分割或直接人工框出葉片。比裁剪更省力的替代方案是加大imgsz讓模型能看到更多紋理細節(jié)但背景干擾嚴重的場景里這只能緩解不能根治。我自己的血淚經(jīng)驗是采集時盡量用純色墊板墊在葉子下面一張白紙都行數(shù)據(jù)集質(zhì)量立刻上一個大臺階。4.3 驗證集劃分不固定兩次實驗的差異說不清來源現(xiàn)象只把batch從16改成32accuracy從0.92變成0.94你以為是batch的功勞。把batch改回去再跑accuracy卻回不到0.92而是0.93。原因每次訓練腳本都重新隨機劃分train/val驗證集里具體包含哪些圖在變結(jié)果根本沒有可比性。這個坑在yolov8訓練自己的數(shù)據(jù)集時特別常見因為很多人習慣了框架自動劃分沒意識到隨機種子會變。解決固定seed只是第一步。更強硬的做法是把劃分好的數(shù)據(jù)集目錄固化下來比如第一次劃分時把train和val作為獨立目錄保存之后所有實驗都用這套劃分不再重新切。第三章腳本里的prepare_split已經(jīng)做了這件事——第一次運行時生成rice_leaf_dataset_split目錄之后運行檢測到train和val就跳過劃分。注意看腳本輸出里有沒有已存在train/val結(jié)構(gòu)這句話確認它確實在復用同一套劃分。4.4 resize把細長葉片壓變形病斑紋理被拉伸后不可信現(xiàn)象稻葉是典型的細長形狀長寬比經(jīng)常超過5比1而imgsz默認會把它直接縮放到224x224的正方形。原本長條狀的病斑在圖上被壓扁或拉長模型學到的是變形后的紋理。訓練時看不出來因為所有訓練圖都被同樣地變形但下田識別時采集到的原始比例不同模型就懵了。原因Ultralytics分類模式的默認預(yù)處理是resize到正方形不會保持原始長寬比也沒有像檢測任務(wù)那樣自動letterbox的邏輯。對方形輸入而言細長葉片的空白區(qū)域會被強行拉伸病斑形態(tài)完全失真。解決有兩種思路。一種是采集階段盡量把葉片橫過來或豎起來統(tǒng)一方向讓長寬比差異變小另一種是在訓練時用更大的imgsz比如320再用隨機裁剪增強給模型機會學到局部病斑紋理而不是整片葉子的全局形狀。如果病斑本身只有幾毫米把圖放大到256以上基本是必須的。4.5 訓練集里混入水印與網(wǎng)絡(luò)重復圖指標高全是假象現(xiàn)象val的top1有0.95但你手動拿真實大田照片一測準確率掉到0.7以下。仔細翻訓練集發(fā)現(xiàn)不少圖來自搜索引擎角落還留著網(wǎng)站水印或截圖邊框。原因模型忠實學到了水印和邊框的特征。這些特征在訓練集里和標簽強相關(guān)但在真實場景中不存在所以一落地就翻車。解決整理階段做一次水印和邊框巡檢把帶水印的圖剔除或裁掉邊緣。重復圖的處理可以用感知哈希去重方法簡單把每張圖縮到8x8或16x16比較哈希距離距離小于閾值就刪掉一張。這一步不需要特別精確目標只是防止同一張圖同時出現(xiàn)在train和val里導致驗證指標虛高。順手檢查有沒有從第三方平臺截圖的圖這類圖通常自帶界面元素模型會把按鈕和進度條也當成特征。5. 訓練完別急著下田用混淆矩陣、Top-1/Top-5和單圖推理做三重驗證5.1 混淆矩陣比accuracy誠實得多畫出每個類別的真實表現(xiàn)訓練日志里的accuracy是一個加權(quán)平均值看不出哪個類別在拖后腿。我每次做完訓練都會先用val目錄跑一遍推理直接出混淆矩陣和分類報告這一步能看出模型到底是會判斷還是只會猜多數(shù)類。import os from ultralytics import YOLO from sklearn.metrics import classification_report model YOLO(runs/classify/train/weights/best.pt) data_root rice_leaf_dataset_split/val class_names sorted([ d for d in os.listdir(data_root) if os.path.isdir(os.path.join(data_root, d)) ]) y_true, y_pred [], [] for cls in class_names: cls_dir os.path.join(data_root, cls) for img_name in os.listdir(cls_dir): img_path os.path.join(cls_dir, img_name) result model.predict(img_path, verboseFalse)[0] pred_cls class_names[int(result.probs.argmax())] y_true.append(cls) y_pred.append(pred_cls) print(classification_report(y_true, y_pred, target_namesclass_names))這段邏輯是遍歷驗證目錄下每個類別文件夾對每張圖調(diào)用model.predict得到概率分布用probs.argmax()取概率最高的類別。注意pred_cls這里用class_names做下標映射而不是直接拿模型的names字段——雖然兩者通常一致但如果訓練時的類別順序和當前目錄的排序不一致就會發(fā)生錯位。多數(shù)類準確率高、少數(shù)類召回率低的情況下classification_report里一眼就能看出來。給模型打包前我會保留這份報告和混淆矩陣圖作為這一版權(quán)重的體檢檔案。5.2 Top-1和Top-5分開看相似病斑類別的容錯設(shè)計水稻葉病蟲害分類里有相當一部分類別人眼都容易混淆比如稻葉瘟的初期病斑和胡麻葉斑病的小病斑顏色和形狀都很接近。這種場景下Top-1準確率會顯得很苛刻模型其實已經(jīng)給出了正確的候選只是把兩個相近類別的概率排序搞反了。Ultralytics在驗證輸出里會計算Top-1和Top-5兩個指標。Top-5的意思是只要正確類別出現(xiàn)在概率最高的5個預(yù)測中就認為正確。我建議把兩個指標一起打印出來如果Top-5比Top-1高很多說明類別定義之間本身存在語義重疊此時可以考慮合并類別或者把細分類別改成疑似稻瘟或胡麻斑這類聯(lián)合標簽而不是急著堆更多訓練數(shù)據(jù)。Top-5也有它的迷惑性當類別總數(shù)本身很少時比如只有4類Top-5幾乎永遠等于100%沒有參考價值。水稻葉分類如果有8到12個類別Top-5才有意義。類別越多Top-5和Top-1之間的差值越能反映數(shù)據(jù)定義的模糊程度。5.3 單圖推理的固定套路給新照片一個可信區(qū)間驗證集的圖雖然和訓練圖不同但拍攝環(huán)境與采集習慣一致。真要判斷模型能不能下田得拿一批完全不在已知數(shù)據(jù)集里的實拍照片單圖推理看概率分布。from ultralytics import YOLO model YOLO(runs/classify/train/weights/best.pt) img field_test/IMG_20250401_153000.jpg result model.predict(img, verboseFalse)[0] probs result.probs for i in range(len(probs)): class_name result.names[i] p probs[i].item() print(f{class_name}: {p:.3f})這段代碼會把每個類別的概率都打出來??锤怕史植紩r我關(guān)注兩點一是最高概率是否明顯超過第二高如果只差零點零幾說明模型自己也不確定二是所有類別的概率排布是否集中如果模型輸出的分布非常平坦說明這張圖里根本沒有它認識的特征不要硬猜。真實田間場景的照片光照復雜偶爾出現(xiàn)一張低置信度預(yù)測是正常的只要比例控制在可接受范圍內(nèi)就可以部署。6. 讓YOLO11cls少翻車的三個習慣訓練前自檢與下田部署前的最后一輪驗證6.1 訓練前自檢清單六件事五分鐘核對完檢查項操作方法通過標準類別數(shù)量運行2.3的統(tǒng)計腳本每類不低于300張背景一致性隨機抽看20張圖每類葉片主體居中背景不雜亂重復圖感知哈希粗查一遍無同一圖跨train和valtrain/val結(jié)構(gòu)查看是否存在兩個子目錄已存在且不自動重切文件名規(guī)范全部英文字母和數(shù)字無空格、無中文seed固定腳本參數(shù)默認42二次訓練指標一致這套清單是我每次訓練前都會過一遍的固定動作。六項里花時間最多的是背景一致性和重復圖排查其余都是腳本自動完成的。很多人在YOLO11cls上翻車翻的根本不是模型參數(shù)而是這些沒被檢查到的數(shù)據(jù)問題。6.2 部署前的大田模擬測試用陌生照片做一次冒煙測試正式交付之前我最看重的一步是拿一臺手機去田間拍20到50張和訓練集風格完全不同的照片。拍攝時不要刻意追求和訓練集一致的構(gòu)圖就按實際使用習慣去拍背景可能帶天空、帶水面、帶稻穗。之后用5.3段的單圖推理腳本逐張過一遍記錄每張圖的置信度和Top-1命中情況。如果陌生照片上的準確率和val集差距過大先不要懷疑模型參數(shù)回頭查訓練集是不是太多來自同一塊田、同一時段、同一設(shè)備的照片。這比盲目調(diào)超參數(shù)有用得多。分類模型的泛化能力很大程度在數(shù)據(jù)采集時就定了訓練腳本只能幫你把這批數(shù)據(jù)的潛力發(fā)揮出來。6.3 三個讓我少翻車的小習慣第一每次訓練在runs目錄外另存一份劃分后的數(shù)據(jù)集路徑文本文件里面記錄seed、各類數(shù)量、數(shù)據(jù)來源時間。第二把best.pt和驗證時的混淆矩陣、分類報告放進同一個文件夾命名帶上日期。第三訓練完成的權(quán)重不直接覆蓋老版本保留最近兩個版本方便回滾。這三個動作加起來不超過十分鐘但能在幾周后完全忘了當時怎么訓練時把整個過程的來龍去脈拉回來。我自己在目標分類項目上翻過不少車最深刻的一條教訓就是數(shù)據(jù)整理階段省下的時間都會在驗證和部署階段加倍還回來。把目錄整理、劃分固定、數(shù)據(jù)體檢這幾件事做到位YOLO11cls的一鍵訓練才能真正一鍵。希望幫到你。本文還有配套的精品資源點擊獲取