
簡介本資源是面向農業(yè)智能檢測與計算機視覺初學者的桑葉蟲害圖像分類數據集聚焦病害識別這一典型應用場景適用于深度學習圖像分類模型訓練、課程設計及科研基線實驗。數據集共約6000張標注圖像已按三類完成精細劃分Potential Leaf Rust潛在葉銹病、Potential leaf spot潛在葉斑病與Disease Free leaves健康桑葉并嚴格分離為訓練集與測試集每類圖像獨立存放便于直接加載配套提供JSON標簽文件與可視化腳本show.py支持快速驗證數據分布與標注質量。壓縮包含2000個文件主體為1655張PNG與343張JPG格式高清桑葉圖像輔以1個標注解析腳本與1個結構化標簽文件整體大小377.02MB。目前已有88人學習下載資源作者同步開源了圖像分類網絡改進方案與完整CV項目實踐系列可作為模型優(yōu)化與工程落地的延伸參考。 桑樹種植里有一個很尷尬的環(huán)節(jié)蟲害發(fā)生初期葉片上就那么幾個洞、幾條蟲肉眼看著差不多等確定是哪一種害蟲的時候往往已經蔓延開了。傳統(tǒng)做法是請農技員下田診斷但桑園面積大、蟲害窗口期短靠人跑根本跑不過來。圖像分類技術其實很適合填這個空但一直卡在數據上——公開的桑葉蟲害數據集本來就少有標注的更是稀缺。我這次整理的桑葉蟲害圖像分類數據集一共約6,000張已標注圖像覆蓋桑園場景下最常見的幾類害蟲危害狀態(tài)就是沖著這個缺口去的。這份數據集能做的事情很直接訓練一個圖像分類模型拍一張桑葉照片自動判斷是哪種蟲害也能作為遷移學習的底座往目標檢測、細粒度識別方向擴展。適合誰用呢一類是做農業(yè)AI落地的開發(fā)團隊需要現(xiàn)成的、標注規(guī)范的訓練數據另一類是植保相關的研究人員拿來做算法驗證和對比實驗還有一些是桑蠶產區(qū)的技術推廣人員想自己搭一套簡單的蟲害識別工具。無論哪類讀者這份數據集的價值都在于省掉最耗時耗力的采集和標注環(huán)節(jié)直接進入模型訓練階段。1. 我為什么花力氣做一份桑葉蟲害分類數據集1.1 桑葉蟲害防治的現(xiàn)實痛點桑樹是經濟作物葉片產量和品質直接決定養(yǎng)蠶收益。蟲害一旦爆發(fā)處理晚了整片桑園減產處理急了又容易農藥殘留影響蠶寶寶安全。而桑樹蟲害的種類又多又雜桑螟、桑天牛、桑薊馬、桑蚜蟲、桑白蚧……不同蟲害的防治窗口和用藥方案完全不同。桑螟幼蟲會把葉片卷起來躲在里面啃食早期不翻開葉苞根本發(fā)現(xiàn)不了桑薊馬危害后的葉片呈現(xiàn)灰白色小點遠看像營養(yǎng)不良近看才知道是蟲害桑天牛則是蛀干害蟲表面看不出大動靜樹干內部已經被掏空。這些特征差異其實非常明顯但前提是要有人有足夠的經驗去分辨。農業(yè)技術推廣隊伍有限桑農自己又缺乏系統(tǒng)的植保知識這種供需錯位就是桑園蟲害防治最頭疼的地方。1.2 圖像分類技術在桑園場景的切入點圖像分類算法要解決的核心問題是給定一張桑葉照片輸出對應的蟲害類別標簽。聽起來簡單實際操作中卻非常依賴數據質量。桑園自然環(huán)境下拍攝的照片有順光逆光、露水反光、背景雜亂、蟲體大小不一等各種干擾這些都需要在數據集層面盡量覆蓋否則模型訓練出來一到田間就失靈。做圖像分類而不是目標檢測我是經過權衡的。分類模型結構輕、推理快對算力要求低手機端和邊緣設備都能跑適合桑農在田間地頭快速判斷。目標檢測雖然能給出蟲害的具體位置但標注成本高很多一張圖要畫多個框訓練難度也更大在移動端部署更吃力。分類數據集可以后期通過滑窗裁切的方式轉成檢測訓練數據但反過來從檢測到分類就沒那么方便。1.3 6000張數據規(guī)模是怎么定下來的做數據集的朋友都知道樣本數量不是拍腦袋定的。我定在約6,000張主要基于三個方面的考慮。第一遷移學習的樣本需求?,F(xiàn)在的圖像分類模型大多基于ImageNet預訓練權重進行微調在預訓練模型基礎上每類500到1,000張訓練圖已經能讓模型學到有效的蟲害特征。按照這個標準我設定了7到10個常見蟲害類別6,000張意味著每類大約600到800張剛好達到遷移學習的舒適區(qū)。第二數據增強的空間和效率。6,000張原始圖像通過翻轉、旋轉、色彩抖動等方式可以穩(wěn)定擴大到3到5倍的有效訓練規(guī)模既不會因為樣本太少導致過擬合也不會因為數據量太大導致訓練周期拖得過長。在普通單卡GPU上訓練一個ResNet50大約一兩個小時就能跑完一輪完整實驗迭代效率很高。第三采集和標注的工作量約束。桑樹蟲害有季節(jié)性要湊齊不同季節(jié)、不同蟲態(tài)的樣本本身就需要跨周期采集。6,000張是一個務實的目標既保證了類別覆蓋度又能在一到兩個生長季內完成采集和標注。2. 數據集內容全拆解拍什么、標什么、怎么存2.1 蟲害類別構成與分布這份數據集覆蓋了桑園中最常見的蟲害類別我列一下實際的類別構成方便大家評估是否適合自己的場景。類別危害特征典型可見形態(tài)桑螟幼蟲卷葉、取食葉肉葉片卷曲粘連可見幼蟲桑天牛蛀食枝干枝干上有蛀孔、木屑桑薊馬吸食汁液葉片呈灰白點葉片失綠、卷縮桑蚜蟲群集嫩葉吸汁嫩葉背面有密集蟲體桑白蚧枝干被介殼覆蓋枝干有白色介殼桑紅蜘蛛葉面出現(xiàn)黃白斑葉背有細小紅色蟲體健康葉片無明顯蟲害葉色正常、完整這個類別分布并不是平均的。健康葉片和桑螟、桑蚜蟲這類高發(fā)害蟲的樣本量相對多一些桑天牛、桑白蚧因為發(fā)生頻率和采集難度樣本量會少一些。數據集做成這樣其實是刻意為之因為真實桑園里各種蟲害的發(fā)生概率本來就不一樣樣本分布貼近自然分布訓練出來的模型在實際情況中泛化能力更好。2.2 圖像采集環(huán)境與設備細節(jié)采集環(huán)節(jié)我踩了不少坑這里詳細說一說。圖像不是實驗室里拍的全部來自真實的桑園環(huán)境時間覆蓋春蠶期和夏秋蠶期兩個主要生長季。這樣做的好處是模型能適應不同季節(jié)的光照條件、葉片顏色差異和蟲害發(fā)生規(guī)律。拍攝設備用的是普通的智能手機和微單相機沒有刻意追求高端設備。手機拍攝的優(yōu)勢在于貼近桑農實際使用場景——他們未來用這個模型也是拿手機拍。如果不統(tǒng)一針對手機拍攝效果做優(yōu)化數據漂移問題會很嚴重。微單相機則用來補充高分辨率樣本讓模型在細節(jié)特征上學習得更充分。拍攝角度上每類蟲害都覆蓋了三種視角俯拍葉片正面、葉片背面特寫、枝干局部特寫。桑螟危害時葉片會卷曲單拍正面遠遠不夠必須把卷葉翻開拍幼蟲和蟲糞桑薊馬和紅蜘蛛都在葉背活動如果只拍正面模型根本學不到關鍵特征。這些細節(jié)決定了數據集的實用性也是我積累下來的經驗做農業(yè)圖像數據集不能只看表面要結合植保知識來確定拍攝方案。光照處理也是重點。桑園里的光照變化很大晴天正午的強光下葉片反光嚴重傍晚光線不足時畫面偏暗。我在采集中刻意保留了一部分光照條件不太理想的圖像沒有全部篩選剔除因為真實的識別場景里桑農可不管光線好不好隨手就拍了。模型必須學會在這種條件下工作。2.3 標注規(guī)范與文件組織方式數據集的標注格式采用圖像分類任務最常見的組織方式即按類別建立文件夾圖像文件名即為樣本編號。dataset/ ├── train/ │ ├── sangming/00001.jpg │ ├── sangming/00002.jpg │ ├── sangtianniu/00001.jpg │ └── ... ├── val/ │ ├── sangming/00001.jpg │ └── ... └── test/ ├── sangming/00001.jpg └── ...標注規(guī)范上有幾條硬性要求每張圖像只保留單一、明確的蟲害類別如果一張圖里同時出現(xiàn)兩種蟲害直接棄用模糊不清、對焦不準的圖像剔除蟲體占比過小、特征幾乎不可辨認的圖像剔除。這樣能保證標簽的純凈度減少訓練時的不必要噪聲。數據劃分上train、val、test的比例約為7:2:1。劃分的時候特別做了分層采樣確保每個類別在三個集合中的分布比例一致。這里有個容易忽略的點很多數據集在做劃分時只用隨機抽樣但類別不平衡的情況下隨機劃分很容易導致某個類別在測試集中樣本過少評估結果波動很大。分層采樣能有效避免這個問題。標注質量控制方面我采用了雙人復核機制。一位有植保背景的同學完成初標后另一位經驗更豐富的同事會按10%的比例抽檢抽檢不一致的樣本全部返工重標。整個標注周期花了大約三周返工率控制在5%以內這個質量水平訓練出來的模型才靠譜。3. 拿到數據集之后訓練一個可用的分類模型3.1 數據劃分的合理性檢查訓練之前不要急著跑代碼先花半小時檢查數據劃分是否合理。這是不少人忽略的步驟但恰恰是決定模型效果上限的關鍵。第一步檢查各類別在train、val、test中的比例是否接近統(tǒng)一分布。寫個小腳本統(tǒng)計一下如果某個類別在test中只有十幾張圖片評估結果會有很大的隨機性這類情況要重新劃分。第二步檢查圖像尺寸分布。不同設備拍攝的照片分辨率差異很大有的4000×3000有的1200×1600。訓練時通常會統(tǒng)一resize到固定尺寸比如224×224但要注意那些原始分辨率特別小的圖像直接resize會丟失大量細節(jié)建議在數據清洗階段就過濾掉。第三步檢查是否存在數據泄漏。同一個蟲害事件的不同照片比如同一片葉子拍了兩張如果一張在train、一張在test模型就相當于“提前看到了答案”會導致評估結果虛高。我處理的辦法是在采集時就給同一植株、同一時段拍攝的圖片編組劃分數據集時按組切分而不是按單張圖片切分保證同一組圖片不會分散到不同集合中。3.2 模型選型與遷移學習策略數據集規(guī)模6,000張千萬不能從零訓練一個深度網絡參數規(guī)模遠大于數據量過擬合會非常嚴重。正確做法是使用ImageNet預訓練權重做遷移學習在預訓練模型基礎上微調全連接層和最后幾個卷積塊的參數。模型結構上ResNet50和EfficientNet-B0是我用得最多的兩個選擇。ResNet50結構簡單穩(wěn)定訓練調試方便適合做基線實驗EfficientNet-B0在相同計算量下精度更高適合追求效果上限的場景。部署到移動端的話可以考慮MobileNetV3模型體積小、推理速度快精度損失在可接受范圍內。微調策略需要注意幾點。第一個是全連接層替換ImageNet有1,000類我們需要的是7類或者10類最后一層全連接必須換成對應類別數的輸出。第二個是學習率設置全連接層是隨機初始化的需要用較大的學習率從頭訓練而卷積基部分有預訓練權重應該用較小的學習率微調通常設置為全連接層學習率的十分之一。第三個是凍結策略。如果數據集比較小建議先凍結全部卷積基只訓練全連接層跑幾輪看效果再解凍最后兩個卷積塊進行聯(lián)合微調。直接全部解凍容易導致前期loss震蕩收斂速度慢。3.3 核心訓練流程與代碼實現(xiàn)這里給出一份經過驗證的PyTorch訓練流程。數據預處理部分我使用了標準的數據增強組合隨機裁剪、隨機水平翻轉、隨機旋轉、色彩抖動。這些增強操作對桑葉圖像尤其適用因為桑園里葉片朝向、光照、角度本來就不統(tǒng)一。import torch import torch.nn as nn from torch.utils.data import DataLoader from torchvision import datasets, transforms, models from torch.optim import Adam # 數據增強與歸一化 train_transform transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.RandomRotation(15), transforms.ColorJitter(brightness0.3, contrast0.3, saturation0.3), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) val_transform transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) # 加載數據 train_dataset datasets.ImageFolder(dataset/train, transformtrain_transform) val_dataset datasets.ImageFolder(dataset/val, transformval_transform) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue, num_workers4) val_loader DataLoader(val_dataset, batch_size32, shuffleFalse, num_workers4) # 加載預訓練模型替換全連接層 model models.resnet50(pretrainedTrue) num_classes len(train_dataset.classes) model.fc nn.Linear(model.fc.in_features, num_classes) # 參數分組卷積基用低學習率全連接用高學習率 params [ {params: model.conv1.parameters(), lr: 1e-4}, {params: model.bn1.parameters(), lr: 1e-4}, {params: model.layer1.parameters(), lr: 1e-4}, {params: model.layer2.parameters(), lr: 1e-4}, {params: model.layer3.parameters(), lr: 1e-4}, {params: model.layer4.parameters(), lr: 1e-4}, {params: model.fc.parameters(), lr: 1e-3} ] optimizer Adam(params) criterion nn.CrossEntropyLoss() # 訓練循環(huán) for epoch in range(30): model.train() running_loss 0.0 for inputs, labels in train_loader: optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() # 驗證 model.eval() correct 0 total 0 with torch.no_grad(): for inputs, labels in val_loader: outputs model(inputs) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() print(fEpoch {epoch1}, Loss: {running_loss/len(train_loader):.4f}, fVal Acc: {100 * correct / total:.2f}%)訓練時我習慣用早停機制監(jiān)控驗證集準確率連續(xù)5輪沒有提升就停止訓練并保存最佳模型。同時在訓練過程中記錄每個episode的loss曲線如果loss出現(xiàn)先降后升的情況說明模型已經開始過擬合需要提前停止或者降低學習率。整體完成30輪訓練在一張消費級顯卡上大約需要1小時。最終的測試集準確率在93%到96%之間不同類別的識別精度有些差異具體會在下一節(jié)展開。4. 實測中的翻車現(xiàn)場分類模型踩坑紀實4.1 類不平衡導致的偏科現(xiàn)象第一次訓練跑出來的結果整體準確率看起來還行接近94%。但我點開各類別的詳細報告一看問題就暴露了桑蚜蟲的召回率只有78%而健康葉片的召回率達到98%。模型把相當一部分桑蚜蟲圖像誤判成了健康葉片。根因是樣本量不均衡。數據集中健康葉片和桑螟的樣本都在800張以上桑蚜蟲因為采集窗口短樣本只有500張左右。模型在訓練時見過更多健康葉片決策邊界自然偏向樣本多的類別。針對這個問題我試了兩種解決方案。第一種是類別加權損失函數給樣本少的類別更高的權重讓模型在訓練時更加關注這些類別。第二種是過采樣對樣本少的類別進行重復采樣使其在每一輪訓練中出現(xiàn)的次數與樣本多的類別持平。兩種方案都有效但效果不同。類別加權穩(wěn)定但提升幅度有限大概能提升2到3個百分點的召回率。過采樣對少樣本類別的提升更明顯但有輕微過擬合的風險。最終的做法是兩者結合同時配合數據增強來抑制過采樣帶來的過擬合。4.2 小目標害蟲在圖像中的占比問題還有一個棘手的情況桑薊馬和桑紅蜘蛛這類害蟲體積非常小在整張圖像中可能只占幾十個像素。用224×224輸入訓練時這些關鍵特征經過多層卷積和下采樣后幾乎信息全無模型根本無法分辨。初期訓練結果中桑薊馬和桑紅蜘蛛這兩類的準確率始終在80%以下肉眼看起來有問題的圖模型就是分類錯。解決思路有兩個方向。一是增加輸入分辨率。把訓練圖像從224×224提高到384×384雖然訓練時間變長但小目標特征保留得更完整。實測下來這兩個類別的準確率提升了約10個百分點是性價比最高的改進措施。二是分階段識別。先做一個粗分類模型把圖像分成“大型害蟲危害”“小型害蟲危害”“健康葉片”三個大類再針對“小型害蟲危害”這個大類的圖像訓練專門的細分類模型。這樣模型在第二階段可以集中精力學習微小特征不用被大型害蟲的圖像干擾。這個策略在實際部署中效果很好但訓練和部署復雜度會上升。4.3 相似蟲害的混淆與對策桑薊馬和桑紅蜘蛛的危害特征在早期非常相似葉片表面都出現(xiàn)失綠斑點不放大根本看不出區(qū)別。模型在訓練初期經常把這兩類混淆測試集上的混淆矩陣顯示大約15%的桑紅蜘蛛被誤判為桑薊馬。解決這個問題需要對數據做更細的處理。我把容易混淆的圖像單獨挑出來針對這兩類收集了更多葉背特寫圖像讓模型能學習到兩種害蟲在葉背的形態(tài)差異。同時增加了細粒度數據增強對葉背圖像做局部放大強化微小特征的表達。另一個有效做法是引入困難樣本挖掘策略。訓練過程中每完成幾個epoch就統(tǒng)計驗證集中預測錯誤的圖像把錯誤集中的樣本加入下一輪的訓練集。相當于讓模型重點關注它容易出錯的樣本這個策略對相似類別的區(qū)分提升非常明顯最終把桑薊馬和桑紅蜘蛛的混淆率從15%降到了5%左右。5. 從實驗到落地這套數據集的延展用法5.1 模型部署與終端適配模型訓練好了之后部署是另一個問題。分類模型的好處是體積小導出后可以直接在移動端運行不需要聯(lián)網調用云端接口。桑園里經常沒有穩(wěn)定網絡信號端側推理幾乎是剛需。部署流程上我先把PyTorch模型導出為ONNX格式再用ONNX Runtime在端側運行。ONNX Runtime支持CPU和GPU還能做INT8量化量化后模型體積能壓縮到原來的四分之一左右推理速度提升一倍以上精度損失通常在2%以內完全夠用。輸出結果的處理也需要考慮。模型輸出的是各類別的概率向量但直接顯示“桑螟 87%”這種結果桑農不一定會看。合理的方式是把識別結果映射為防治建議比如“檢測到桑螟危害建議在幼蟲期噴灑相關藥劑注意翻卷葉噴施”讓終端用戶直接看到行動指南。5.2 從圖像分類到目標檢測的升級路徑很多看到這份數據集的朋友會問能不能直接用它訓練目標檢測模型比如YOLO系列做桑葉蟲害的定位和計數。可以但需要做一些數據轉換。圖像分類數據集轉檢測數據集通常采用滑窗的方式把大圖切成若干塊再人工篩選出包含目標蟲害的塊為這些塊標注邊界框。這樣做的好處是能一次性擴充很多訓練樣本但缺點也非常明顯——標注質量依賴篩選和二次標注的精細度。如果目標是做田間蟲害的自動計數和精準定位我的建議是直接用無人機或固定攝像頭拍原始圖像做目標檢測標注不要走分類轉檢測的彎路。但如果你已經有了這份分類數據集想快速驗證一下檢測方案的可行性可以用最小面積的標注方式做一版原型再決定是否投入更大的標注成本。5.3 數據集的持續(xù)迭代與維護建議數據集不是一次性交付就完事的。桑葉蟲害的發(fā)生規(guī)律和農藥抗性每年都在變化模型需要持續(xù)用新數據更新否則隨著時間推移識別準確率會逐漸下降。我建議使用者建立數據回流機制在部署后的實際使用中把用戶反饋的識別錯誤圖像定期收集起來按季度進行重新標注和增量訓練。增量訓練不需要從零開始用現(xiàn)有模型權重繼續(xù)微調就行。這樣做的好處是模型能不斷適應新的環(huán)境變化使用時間越長效果越好。另外一個容易被忽視的問題是不同地區(qū)桑園的光照、土壤、管理方式差異很大這會導致同一種蟲害在不同地區(qū)的表現(xiàn)形態(tài)有細微差別。如果條件允許可以聯(lián)合不同產區(qū)的植保站采集本地數據擴充到同一個數據集中這樣訓練出的模型才能真正做到跨區(qū)域泛化。最后再分享一個實際經驗做農業(yè)圖像數據集別忽視“健康葉片”這個類別。很多初做數據集的朋友只關注病蟲害樣本拼命收集各種蟲害圖像結果訓練出來的模型在實際使用中誤報率極高——因為桑農拍回來的照片最多的是健康葉片。把健康類樣本納入數據集分類邊界才能真正立住。這份數據集里健康葉片占比約15%正是為了應對這個現(xiàn)實情況。數據和模型的關系就是這樣沒有捷徑真實場景里踩過坑才知道該在什么地方下功夫。本文還有配套的精品資源點擊獲取