尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
基于Python的农作物病虫害识别分类项目:源码、数据集与迁移学习实战
简介这份资源面向具备一定Python基础、希望上手农作物病虫害识别分类的开发者与学习者提供从数据到部署的完整项目实践方案。包内共61个文件以9个ipynb实验笔记、10个md说明文档、15张png与8张jpg示例图为主另含py脚本、js/css前端资源、yml/yaml部署配置、pkl模型文件及Dockerfile等压缩包约88.66MB覆盖训练、评估与上线各环节。项目围绕图像预处理、特征提取与模型训练展开包含ResNet50、VGG16、VGG19、DenseNet121等预训练网络并给出TensorFlow、Keras、PyTorch、Fastai多框架实现配套Flask后端与静态页面可完成实时识别交互。已有306人学习下载适合作为课程设计、毕业设计或竞赛项目的参考模板帮助读者快速理解病虫害分类的完整流程与工程结构。1. 农作物病虫害识别分类项目一份 Python 源码加数据集到底能跑出什么田里叶子刚出现黄褐色斑点时种植户往往分不清是早疫病还是叶霉病打错药不仅白花钱还会让病菌产生抗性。农作物病虫害识别分类要解决的就是这件事拍一张叶片照片让模型告诉你它得了什么病、属于哪一类。这个标题里的「基于 Python 的农作物病虫害识别分类项目源码数据集说明文档.zip」本质是一套可复现的迁移学习工程包——用 Python 把预训练卷积网络微调到植物叶片数据集上输出分类结果。它适合三类人想入门深度学习但缺完整案例的学生、需要给农业场景做原型验证的开发者、以及手里有自己田间数据想套用现成流程的从业者。热词里的 python 安装、python 教程、yolov8 训练自己的数据集其实都指向同一个诉求拿到能跑通的代码和数据而不是又一篇原理科普。下面我按「数据长什么样、模型怎么搭、训练怎么调、坑在哪」把这条路走一遍。2. 先看清数据集病虫害图像的分类体系与预处理拿到一个病虫害识别项目第一件事不是急着跑模型而是把数据集翻个底朝天。图像分类任务里数据决定了模型上限网络结构只是逼近这个上限。农作物病害数据集通常按「作物种类 病害名称」组织目录比如Tomato___Early_blight、Potato___Late_blight这种命名下划线分隔作物和病害这种命名方式直接对应 ImageFolder 的类别读取逻辑。2.1 目录结构与类别分布怎么读常见做法是把数据整理成每个类别一个文件夹文件夹名就是标签。用 Python 扫一遍目录能立刻看出类别是否均衡、有没有脏数据。import os from collections import Counter data_dir plant_disease/train class_counts {} for cls in sorted(os.listdir(data_dir)): cls_path os.path.join(data_dir, cls) if os.path.isdir(cls_path): # 只统计常见图片后缀避免把 .DS_Store 之类算进去 imgs [f for f in os.listdir(cls_path) if f.lower().endswith((.jpg, .jpeg, .png))] class_counts[cls] len(imgs) for k, v in class_counts.items(): print(f{k}: {v}) total sum(class_counts.values()) print(总样本数:, total) print(类别数:, len(class_counts)) # 找出最少的类别判断是否需要重采样 minority min(class_counts, keyclass_counts.get) print(最少类别:, minority, class_counts[minority])这段代码做三件事遍历训练目录、按类别统计图片数量、找出样本最少的类别。参数上data_dir指向训练集根目录后缀过滤是为了防止系统隐藏文件干扰计数。逻辑说明如果最多类别和最少类别差距超过 5 倍训练时模型会偏向多数类这时候要么对少数类做数据增强要么用加权损失。这一步不做后面准确率虚高但少数病害全预测错是血泪经验。2.2 图像尺寸、归一化与数据增强参数病虫害图像有个特点病斑在叶片上的位置随机大小不一。所以预处理不能只做中心裁剪得用随机裁剪加翻转。常见做法是统一缩放到 224×224配合 ImageNet 的均值和标准差做归一化因为后面要用预训练权重。from torchvision import transforms train_tf transforms.Compose([ transforms.Resize(256), # 先缩到 256保留更多细节 transforms.RandomResizedCrop(224), # 随机裁剪到 224增强位置鲁棒性 transforms.RandomHorizontalFlip(), # 叶片左右翻转不改变病害类别 transforms.RandomRotation(15), # 小角度旋转模拟拍摄角度差异 transforms.ColorJitter(0.2, 0.2, 0.2), # 亮度对比度扰动抗光照变化 transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) val_tf 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]) ])参数说明RandomResizedCrop(224)的缩放范围默认 0.08 到 1.0意味着可能裁到病斑局部这对小病斑识别有帮助。RandomRotation(15)角度别开太大超过 30 度叶片背景会出现黑边反而引入噪声。ColorJitter三个 0.2 分别控制亮度、对比度、饱和度数值再大可能把病斑颜色改得不像病。验证集必须用确定性的 CenterCrop否则每次评估结果都在抖没法判断模型是否真的在进步。提示如果数据集里同一片叶子拍了多张务必按叶片或按地块划分训练验证集不能随机按图片划分否则验证集里出现训练集同叶片的照片准确率会虚高十几个点。3. 模型选型与迁移学习为什么不用从零训练病虫害数据集规模通常在几千到几万张这个量级从零训练卷积网络必然过拟合。迁移学习是这里的标准答案拿在 ImageNet 上训练好的骨干网络换掉最后的分类头用较小学习率微调。热词里出现的 imagenet1k 数据集下载、yolov8 训练自己的数据集背后都是同一个思路——预训练权重是免费的先验知识。3.1 骨干网络对比与选择依据网络参数量输入尺寸适合场景注意事项ResNet18约 11M224数据量小、要快速验证层数浅细粒度病害可能欠拟合ResNet50约 25M224类别多、病斑细微显存占用翻倍小数据集易过拟合EfficientNet-B0约 5M224移动端部署、算力有限输入分辨率敏感别随意改MobileNetV3约 2.5M224边缘设备实时推理精度略低适合做基线我一般先用 ResNet18 跑通全流程确认数据管道没问题再换 ResNet50 看精度能涨多少。如果涨幅不到 2 个点说明瓶颈在数据质量而不是模型容量换更大网络是浪费算力。3.2 替换分类头与冻结策略import torch import torch.nn as nn from torchvision import models def build_model(num_classes, backboneresnet18, freeze_backboneTrue): if backbone resnet18: model models.resnet18(weightsmodels.ResNet18_Weights.DEFAULT) in_features model.fc.in_features model.fc nn.Linear(in_features, num_classes) # 替换分类头 elif backbone resnet50: model models.resnet50(weightsmodels.ResNet50_Weights.DEFAULT) in_features model.fc.in_features model.fc nn.Linear(in_features, num_classes) if freeze_backbone: # 冻结除 fc 外的所有参数先只训练分类头 for name, param in model.named_parameters(): if fc not in name: param.requires_grad False return model model build_model(num_classes38, backboneresnet18, freeze_backboneTrue) trainable sum(p.numel() for p in model.parameters() if p.requires_grad) print(可训练参数量:, trainable)逻辑说明weights...DEFAULT加载预训练权重model.fc是 ResNet 的全连接层替换成自己类别数的线性层。冻结骨干网络后只有分类头参与训练这样前几个 epoch 不会因为随机初始化的分类头产生大梯度而破坏预训练特征。参数上num_classes必须等于数据集类别数多一个少一个都会在算损失时报维度错误。等分类头收敛后再解冻后面几个 stage 做微调学习率要调小到 1e-4 量级。3.3 分阶段解冻的训练循环import torch.optim as optim from torch.utils.data import DataLoader from torchvision.datasets import ImageFolder train_ds ImageFolder(plant_disease/train, transformtrain_tf) val_ds ImageFolder(plant_disease/val, transformval_tf) train_loader DataLoader(train_ds, batch_size32, shuffleTrue, num_workers4) val_loader DataLoader(val_ds, batch_size32, shuffleFalse, num_workers4) device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device) criterion nn.CrossEntropyLoss() # 第一阶段只训练分类头 optimizer optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr1e-3) for epoch in range(5): model.train() for imgs, labels in train_loader: imgs, labels imgs.to(device), labels.to(device) optimizer.zero_grad() loss criterion(model(imgs), labels) loss.backward() optimizer.step() print(fstage1 epoch {epoch} loss {loss.item():.4f}) # 第二阶段解冻 layer4 和 fc小学习率微调 for name, param in model.named_parameters(): if layer4 in name or fc in name: param.requires_grad True optimizer optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr1e-4) for epoch in range(10): model.train() for imgs, labels in train_loader: imgs, labels imgs.to(device), labels.to(device) optimizer.zero_grad() loss criterion(model(imgs), labels) loss.backward() optimizer.step() print(fstage2 epoch {epoch} loss {loss.item():.4f})参数说明第一阶段学习率 1e-3因为分类头是随机初始化的需要较大步长。第二阶段降到 1e-4避免把预训练特征冲掉。batch_size32在 8G 显存下跑 ResNet18 比较稳显存不够就降到 16 并同步调小学习率。num_workers4是数据加载线程数Windows 上如果报错就设成 0。这套两阶段流程比一上来就全网络微调更稳尤其在小数据集上。4. 训练、评估与推理把模型跑成能用的工具训练完不等于能用得看混淆矩阵、看单类召回还要把模型导出成推理脚本。很多项目源码只给训练代码不给推理入口拿到手不知道怎么预测一张新图这是常见缺陷。4.1 评估指标与混淆矩阵from sklearn.metrics import classification_report, confusion_matrix import numpy as np model.eval() all_preds, all_labels [], [] with torch.no_grad(): for imgs, labels in val_loader: imgs imgs.to(device) preds model(imgs).argmax(dim1).cpu().numpy() all_preds.extend(preds) all_labels.extend(labels.numpy()) print(classification_report(all_labels, all_preds, target_namesval_ds.classes, digits3)) cm confusion_matrix(all_labels, all_preds) # 找出被误判最多的类别对 for i in range(len(cm)): for j in range(len(cm)): if i ! j and cm[i][j] 5: print(f{val_ds.classes[i]} 误判为 {val_ds.classes[j]}: {cm[i][j]} 次)逻辑说明classification_report给出每类的精确率、召回率、F1重点看召回率低的类别。混淆矩阵里非对角线的大数值就是主要错误来源。参数上target_names直接取val_ds.classes顺序和标签索引一致。如果某两类互相误判严重通常是它们病斑形态接近需要针对性补充这两类的区分性样本而不是盲目加数据。4.2 单张图片推理脚本from PIL import Image import torch.nn.functional as F def predict(image_path, model, class_names, device): model.eval() img Image.open(image_path).convert(RGB) # 强制三通道防灰度图报错 tensor val_tf(img).unsqueeze(0).to(device) # 增加 batch 维度 with torch.no_grad(): logits model(tensor) probs F.softmax(logits, dim1)[0] top_prob, top_idx probs.max(0) return class_names[top_idx.item()], top_prob.item() label, prob predict(test_leaf.jpg, model, val_ds.classes, device) print(f预测: {label}, 置信度: {prob:.3f})参数说明convert(RGB)很关键手机拍的叶片图可能是 RGBA 或灰度不转三通道会在归一化时报错。unsqueeze(0)把单张图变成[1, 3, 224, 224]因为模型要求有 batch 维度。softmax把 logits 转成概率置信度低于 0.6 时建议提示用户重新拍摄而不是硬给一个结果。注意推理时的预处理必须和验证集完全一致包括 Resize 尺寸和 Normalize 参数。训练用 256 缩放、推理用 224 直接缩放精度会掉好几个点这种不一致是排查半天才发现的典型翻车点。5. 避坑与排查病虫害识别项目最容易翻车的五个地方这一章按「现象 → 原因 → 解决」写都是我在实际项目里踩过的。现象一训练准确率 99%验证准确率 60% 都不到。原因训练集和验证集按图片随机划分同一片叶子的多张照片被分到两边模型记住了叶子背景而不是病斑。解决按叶片 ID 或拍摄批次划分确保同一来源的图片只出现在一个集合里。如果数据集没给叶片 ID就按文件名前缀分组划分。现象二模型把所有类别都预测成样本最多的那一类。原因类别极度不均衡交叉熵损失被多数类主导。解决用加权交叉熵权重取类别频率的倒数或者对少数类做过采样配合强增强。代码上给nn.CrossEntropyLoss(weightclass_weights)传入按类别数计算的权重张量。现象三验证集 loss 突然变成 nan。原因学习率太大或者某张图片损坏导致输入出现异常值。解决先把学习率降一个数量级再用脚本遍历数据集用 PIL 打开每张图捕获异常并打印文件名把损坏图片剔除。数据集中混入零字节文件是常见情况。现象四推理时置信度普遍偏低都在 0.3 左右。原因推理预处理和训练不一致最常见的是归一化均值标准差写错或者忘了除以 255。解决把训练时的 transform 对象直接复用到推理不要手写归一化。检查ToTensor()是否在Normalize之前。现象五换一台机器跑报显存不足或 num_workers 报错。原因batch_size 和 num_workers 是跟机器绑定的Windows 上多进程数据加载容易出问题。解决把 batch_size 和 num_workers 提成命令行参数或配置文件Windows 下 num_workers 设 0Linux 下再调大。别把机器相关参数硬编码在代码里。6. 从能跑到好用提升小样本病害识别的两个技巧模型跑通只是起点真正决定这个项目值不值得投入的是它在少见病害上的表现。我一般会做两件事。第一件是类别平衡采样加焦点损失的组合。焦点损失通过调制因子降低易分类样本的权重让模型把注意力放在难分的少数类上。实现上把交叉熵换成带 gamma 参数的焦点损失gamma 取 2 比较常用再配合按类别倒数采样的 WeightedRandomSampler少数类的召回率通常能提十来个点。参数别乱调gamma 超过 3 容易训练不稳定。第二件是用测试时增强做推理。对同一张待预测图片做多次轻微变换水平翻转、小角度旋转把多次预测概率平均。这个技巧不增加训练成本只增加推理时间在病斑边界模糊的样本上效果明显。技巧改动位置预期收益代价焦点损失损失函数少数类召回提升需调 gamma平衡采样DataLoader缓解类别偏斜训练轮次需增加测试时增强推理脚本置信度更稳推理耗时翻倍验证这些改动是否有效不能只看总体准确率要盯住混淆矩阵里少数类的召回变化。我习惯每次改动只动一个变量跑完对比分类报告确认涨的是目标类别再保留。这套流程走下来一个病虫害识别项目才算从「能跑」变成「敢用」。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

TR 38.901-e30 信道模型实战:从参数解读到5G波束管理仿真落地

TR 38.901-e30 信道模型实战:从参数解读到5G波束管理仿真落地

简介:这是一份3GPP技术报告TR 38.901(对应Release 14),由3GPP无线接入网技术规范组制定,聚焦0.5~100 GHz频段的信道模型研究,面向5G新空口(NR)系统的标准制定者、设备制造…

📅 2026/10/12 11:53:42
蓝桥杯校内模拟赛C:C语言工程化编码能力实战指南

蓝桥杯校内模拟赛C:C语言工程化编码能力实战指南

1. 项目概述:一场面向实战的C语言能力压力测试“蓝桥杯校内模拟赛C”这七个字,对很多高校计算机相关专业的学生来说,不是一道题,而是一次临场反应、代码肌肉记忆和工程思维的综合体检。它不考概念背诵,不考PPT式汇报&a…

📅 2026/10/12 11:53:42
EasyExcel模板导出的工程化实践:数据拍平、语法契约与健壮渲染

EasyExcel模板导出的工程化实践:数据拍平、语法契约与健壮渲染

1. 为什么模板导出不是“加个注解就完事”——EasyExcel里最容易被低估的工程复杂度“EasyExcel通过模板导出数据”这个标题,乍看平平无奇,像一句开发文档里的功能描述。但我在某高校实验室带学生做教务系统二期时,亲眼见过三个不同背景的开发…

📅 2026/10/12 11:53:42
MORE NEWS

更多资讯

📰

SAP云平台Cockpit使用指南:从子账户到服务实例的完整实操路径

做了几年SAP相关项目之后,我发现一个挺有意思的现象:很多人第一次打开SAP云平台(现在官方全名叫SAP Business Technology Platform,行业里还是习惯叫SAP云平台)的Cockpit时,盯着满屏的英文菜单和卡片&#…

📰

Python工程化入门:面向对象、文件读写与异常处理实战笔记

1. 学习笔记三:走出语法舒适区,开始接触真正工程化的 Python进入这套 100 天学习路线图的第三阶段,最大的感受是:前面几章还停留在"认识 Python"的层面,到了这一部分,才真正开始"用 Python …

📰

R语言基础入门:向量、循环法则与NA/NaN处理

搞R语言也有几年了,每次带新人入门,我都会让他们先把向量、循环法则、NA和NaN这几个概念弄明白,再往后学才是正路。别小看这些基础,多少人在实际处理数据时,被循环法则静默回收坑得怀疑人生,被NA和NaN的组合…

📰

南开大学编译原理作业实战:简单C语言编译器从词法到代码生成

简介:这份资源是南开大学软件学院编译原理课程的作业成果,包含一个可运行的简单C语言编译器完整源码与配套文档,面向计算机、人工智能、通信工程等专业的在校学生及自学者,适合用作课程设计、毕业设计参考或编译原理入门实践。压缩…

📰

基于Docker的大学生兼职平台部署:容器化设计与避坑实践

简介:基于Docker的大学生兼职平台项目完整资源包,服务于计算机专业学生与后端开发人员,也适合作为毕业设计选题参考。项目围绕兼职信息发布、岗位检索、用户管理等核心功能展开,采用Java语言结合常见微服务开发框架,后…

📰

AI数据合规全链路指南:从训练语料到模型输出的落地实践

前阵子跟一个做AI客服系统的朋友喝茶,他一句话让我记了很久:功能做完了,评审会开了一个月,最后砍掉了一半的训练语料。原因不复杂——语料里全是真实用户的聊天记录,里面有手机号、有住址,甚至还有用户照着…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬