新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于深度学习的农作物病虫害识别系统:Python源码与数据集实战

发布时间:2026/10/1 19:04:31来源:尧图网络
基于深度学习的农作物病虫害识别系统:Python源码与数据集实战
简介这份资源是面向计算机相关专业学生与深度学习入门者的农作物病虫害识别检测系统完整项目基于卷积神经网络实现图像分类与检测可作为毕业设计、课程设计或期末大作业的实战参考。包内共56个文件涵盖9个ipynb实验笔记、2个py核心脚本、15个png与4个jpg效果图、10个md说明文档以及yml、html、css、pkl模型文件、Dockerfile等部署配置压缩包约88.3MB目录按app、models、notebook、static等模块划分结构清晰。项目包含ResNet50、DenseNet121、VGG16、VGG19等多种网络实现并附TensorFlow、PyTorch、Keras、Fastai多框架版本方便对比学习。已有98人学习下载适合希望快速跑通完整流程、理解模型训练与Web端部署的读者参考借鉴。1. 农作物病虫害识别系统从数据集到可运行 Python 源码的完整落地路径田里出现一片发黄的叶片农户拍张照上传系统在 1 秒内返回“玉米大斑病置信度 0.93建议喷施苯醚甲环唑”——这就是基于深度学习卷积神经网络的农作物病虫害识别检测系统要干的事。它本质是一个图像分类或检测任务输入作物叶片照片输出病虫害类别。整套东西通常包含三块Python 源码、运行说明、标注好的数据集。适合谁正在做高分毕设的本科生、想入门深度学习算法又不想只跑 MNIST 的开发者、以及需要快速搭一个农业 AI demo 的工程师。热搜里“深度学习”“卷积神经网络”“python”“源码”“数据集”这几个词恰好对应了这套系统的五个核心环节环境、模型、训练、推理、部署。下面按我实际搭过一遍的顺序把每一步拆开讲清楚包括参数怎么设、坑在哪。2. 数据集怎么选、怎么洗决定模型上限的不是网络结构2.1 公开数据集与自建数据集的取舍农作物病虫害领域最常被引用的公开数据集是 PlantVillage包含约 5 万多张叶片图像覆盖 38 个类别作物-病害组合背景多为单一颜色标注质量高。但它的致命问题是真实田间照片有复杂背景、光照变化、遮挡直接拿 PlantVillage 训出来的模型下地就翻车。我的做法是用 PlantVillage 做预训练或基线再用自己拍的 200500 张田间图做微调。如果毕设时间紧至少要在运行说明里写清楚“本模型适用于单一背景叶片图”别让答辩老师拿一张田间图把你问住。自建数据集时类别命名建议用“作物_病害”格式比如corn_blight、rice_blast避免中文路径。每类至少 200 张少于这个数就得靠数据增强硬撑。图像统一缩放到 224×224 或 256×256格式统一为 JPG文件名不要带空格。2.2 数据清洗与划分的实操脚本拿到原始图片后第一步不是直接训练而是去重、去模糊、检查标签。下面这段脚本做三件事删除损坏图片、按 8:1:1 划分训练/验证/测试集、生成类别索引文件。import os import shutil import random from PIL import Image from tqdm import tqdm RAW_DIR raw_data # 原始数据每个子文件夹是一个类别 OUT_DIR dataset # 输出目录 SPLIT (0.8, 0.1, 0.1) # 训练/验证/测试比例 def is_valid_image(path): try: img Image.open(path) img.verify() # 校验文件完整性 return True except Exception: return False classes sorted(os.listdir(RAW_DIR)) for cls in classes: cls_dir os.path.join(RAW_DIR, cls) if not os.path.isdir(cls_dir): continue imgs [f for f in os.listdir(cls_dir) if f.lower().endswith((.jpg, .jpeg, .png))] imgs [f for f in imgs if is_valid_image(os.path.join(cls_dir, f))] random.shuffle(imgs) n len(imgs) n_train int(n * SPLIT[0]) n_val int(n * SPLIT[1]) splits { train: imgs[:n_train], val: imgs[n_train:n_train n_val], test: imgs[n_train n_val:] } for split, files in splits.items(): dst os.path.join(OUT_DIR, split, cls) os.makedirs(dst, exist_okTrue) for f in tqdm(files, descf{cls}-{split}): shutil.copy(os.path.join(cls_dir, f), os.path.join(dst, f)) print(划分完成)逻辑说明is_valid_image用 PIL 的verify()过滤掉下载不全或格式损坏的图这一步能避免训练时突然报UnidentifiedImageError。random.shuffle前建议固定随机种子random.seed(42)保证每次划分一致方便复现。参数上SPLIT比例不是死的如果某类样本少于 300验证集可以压到 0.05把更多数据留给训练。输出目录结构直接兼容torchvision.datasets.ImageFolder后面写 Dataset 时不用再改。注意划分必须在“去重”之后做。我见过有人先划分再发现训练集和测试集有重复图测试准确率虚高到 99%答辩时被当场戳穿。2.3 数据增强别把叶片转成“外星生物”增强策略要符合田间实际。随机水平翻转、±15° 旋转、亮度对比度微调是安全的但垂直翻转对叶片图像通常不合理自然界叶片不会倒挂大角度旋转会引入黑边。颜色抖动ColorJitter幅度别超过 0.3否则病斑颜色失真模型学到的特征就偏了。from torchvision import transforms train_tf transforms.Compose([ transforms.Resize((256, 256)), transforms.RandomResizedCrop(224, scale(0.7, 1.0)), # 模拟不同拍摄距离 transforms.RandomHorizontalFlip(p0.5), transforms.RandomRotation(15), transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) # ImageNet 统计量 ]) val_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])RandomResizedCrop的scale(0.7,1.0)是关键它让模型见过“叶片只占画面一部分”的情况提升对真实拍摄的鲁棒性。归一化用的均值和方差是 ImageNet 的只要你是用预训练权重微调就必须保持一致否则预训练学到的分布对不上收敛会变慢甚至不收敛。3. 卷积神经网络选型与训练ResNet18 够用别一上来就上 ViT3.1 为什么农作物病虫害识别首选 ResNet 系列卷积神经网络处理图像的核心是局部感受野和权值共享这对叶片病斑这种局部纹理特征非常对路。选型上我的建议很直接毕设或中小规模数据集几千到几万张ResNet18 或 ResNet50 微调就是性价比最高的方案。ResNet 的残差连接解决了深层网络退化问题18 层在 224×224 输入下参数量约 1100 万单张 1080Ti 或 3060 就能训。ViT 这类 Transformer 结构需要更大数据量才能发挥优势5 万张以下的数据集上ResNet 通常更稳。如果标题里强调“检测”而非“分类”那要用 YOLO 系列如 YOLOv8做目标检测输出病斑位置框。但多数毕设的“识别检测系统”实际做的是分类运行说明里要写清楚别让评审误解。3.2 用迁移学习微调 ResNet18 的完整训练脚本下面这段代码是可直接跑的最小训练闭环加载预训练权重、替换最后一层、冻结部分层、训练、保存最优模型。import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, models, transforms from torchvision.models import ResNet18_Weights DEVICE torch.device(cuda if torch.cuda.is_available() else cpu) BATCH_SIZE 32 EPOCHS 30 LR 1e-3 NUM_CLASSES 10 # 改成你的类别数 train_ds datasets.ImageFolder(dataset/train, transformtrain_tf) val_ds datasets.ImageFolder(dataset/val, transformval_tf) train_loader DataLoader(train_ds, batch_sizeBATCH_SIZE, shuffleTrue, num_workers4) val_loader DataLoader(val_ds, batch_sizeBATCH_SIZE, shuffleFalse, num_workers4) model models.resnet18(weightsResNet18_Weights.IMAGENET1K_V1) for param in model.parameters(): param.requires_grad False # 先冻结全部 model.fc nn.Linear(model.fc.in_features, NUM_CLASSES) # 替换分类头 criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.fc.parameters(), lrLR) # 只训分类头 scheduler optim.lr_scheduler.StepLR(optimizer, step_size10, gamma0.1) model model.to(DEVICE) best_acc 0.0 for epoch in range(EPOCHS): 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() model.eval() correct, total 0, 0 with torch.no_grad(): for imgs, labels in val_loader: imgs, labels imgs.to(DEVICE), labels.to(DEVICE) preds model(imgs).argmax(dim1) correct (preds labels).sum().item() total labels.size(0) acc correct / total scheduler.step() if acc best_acc: best_acc acc torch.save(model.state_dict(), best_resnet18.pth) print(fEpoch {epoch1}/{EPOCHS} val_acc{acc:.4f} best{best_acc:.4f})逻辑说明先冻结主干只训分类头是为了让随机初始化的fc层不把预训练特征带偏训 10 个 epoch 后如果验证准确率停滞可以解冻layer4一起微调学习率降到 1e-4。StepLR每 10 轮降一次学习率防止后期震荡。保存的是state_dict而非整个模型加载时更灵活。参数说明BATCH_SIZE32在 8GB 显存下安全显存不够就降到 16 并同步调小学习率到 5e-4。num_workers4在 Windows 上如果报错就改成 0。NUM_CLASSES必须和你的类别数严格一致改错会直接维度不匹配报错。3.3 训练过程要看哪些曲线、怎么判断过拟合训练时至少盯三条线训练 loss、验证 loss、验证准确率。正常情况训练 loss 平稳下降验证 loss 先降后平。如果训练 loss 一直降、验证 loss 开始上升就是过拟合处理顺序是先加数据增强再加 Dropoutnn.Dropout(0.5)放在 fc 前最后才考虑减模型容量。如果两条 loss 都不降先查学习率是不是太大loss 震荡或太小几乎不动再查数据标签有没有错。我一般会在训练脚本里每轮打印学习率确认 scheduler 生效。4. 推理与系统封装把模型变成能点的界面4.1 单张图片推理与置信度输出训练完只是拿到权重用户要的是“上传图片→出结果”。下面是最小推理函数返回类别名和置信度。import torch import torch.nn.functional as F from PIL import Image from torchvision import models, transforms CLASS_NAMES [corn_blight, rice_blast, healthy, ...] # 与训练顺序一致 infer_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) def predict(image_path, model_pathbest_resnet18.pth): model models.resnet18(weightsNone) model.fc torch.nn.Linear(model.fc.in_features, len(CLASS_NAMES)) model.load_state_dict(torch.load(model_path, map_locationcpu)) model.eval() img Image.open(image_path).convert(RGB) tensor infer_tf(img).unsqueeze(0) with torch.no_grad(): probs F.softmax(model(tensor), dim1)[0] idx probs.argmax().item() return CLASS_NAMES[idx], probs[idx].item()关键点CLASS_NAMES的顺序必须和ImageFolder按文件夹名排序后的顺序一致否则结果全错。map_locationcpu保证在没有 GPU 的机器上也能加载。softmax后的置信度低于 0.6 时建议在界面上提示“不确定请重新拍摄”而不是硬给一个类别。4.2 用 Gradio 快速搭一个可演示界面毕设演示不需要写前端Gradio 三行代码出网页界面支持拖拽上传。import gradio as gr def classify(img): label, conf predict(img) return f{label} ({conf:.2%}) demo gr.Interface( fnclassify, inputsgr.Image(typefilepath), outputstext, title农作物病虫害识别系统 ) demo.launch(server_name0.0.0.0, server_port7860)server_name0.0.0.0让局域网内其他设备也能访问答辩时用手机拍一张就能现场演示。如果运行说明里要求“离线可用”Gradio 默认会尝试联网加载前端资源需要提前把静态文件本地化或者改用 PyQt5 写桌面端。4.3 运行说明该写什么才算合格一份能让人复现的运行说明至少包含Python 版本建议 3.83.10、依赖安装命令pip install -r requirements.txt、数据集放置路径、训练命令、推理命令、常见报错。requirements.txt 里要锁版本比如torch2.0.1、torchvision0.15.2不锁版本是复现失败的头号原因。我见过有人写“安装 PyTorch 即可”结果对方装了最新版API 变了直接跑不起来。5. 避坑与排查这五个坑我替你踩过了5.1 现象训练准确率 99%测试准确率 40%原因训练集和测试集有重复图片或者同一张图的不同增强版本被分到了两个集合。解决划分前用图片哈希如 MD5去重确保同一原图只出现在一个集合。5.2 现象loss 变成 NaN原因学习率过大或者输入数据没有归一化像素值 0255 直接进网络。解决确认ToTensor()后接Normalize学习率从 1e-3 起调出现 NaN 就降到 1e-4。5.3 现象验证集准确率远高于训练集原因验证集太小比如只有 20 张或者验证集类别分布和训练集差异大。解决验证集至少每类 20 张且用分层抽样保证类别比例一致。5.4 现象推理时类别名对不上原因CLASS_NAMES手写顺序和ImageFolder的class_to_idx不一致。解决训练后打印train_ds.classes并保存成 json推理时读取同一个文件。5.5 现象换台机器就报CUDA out of memory原因batch size 按大显存设的小显存机器扛不住。解决在代码里加自动降级逻辑捕获 OOM 异常后把 batch size 减半重试或者直接在运行说明里写明最低显存要求。6. 把准确率再抬 3 个点的三个技巧第一个技巧是测试时增强TTA。推理时对同一张图做原图、水平翻转、轻微缩放三个版本分别预测后取平均概率。这个操作不重训模型通常能涨 12 个点代价是推理时间变三倍。代码上就是把infer_tf跑三次probs累加后除以 3。第二个技巧是类别不平衡处理。如果健康叶片样本远多于病害样本用加权交叉熵weight 1 / 每类样本数归一化后传给nn.CrossEntropyLoss(weightweight)。这比简单过采样更稳不会让模型反复看同一张图。第三个技巧是混淆矩阵驱动优化。训练完在测试集上画混淆矩阵找出最容易被混淆的两个类别比如两种叶斑病针对这两类单独补数据或调整增强策略。我一般会把这个矩阵直接放进毕设论文比只报一个总体准确率有说服力得多。最后说个习惯每次改完超参数把配置写进一个config.yaml连同权重文件一起存档。我吃过亏隔了两周想复现最好的那次结果忘了当时学习率是 5e-4 还是 1e-3只能重训。模型训练没有后悔药配置留档就是给自己留退路。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

考研党C语言环境配置指南:VSCode与MinGW-W64最佳实践 2026/10/1 19:50:48

考研党C语言环境配置指南:VSCode与MinGW-W64最佳实践

很多考研党第一次接触C语言,卡住他们的往往不是语法本身,而是“怎么让自己的电脑跑起第一行代码”。网上的教程东一篇西一篇,今天装这个明天卸那个,折腾一天还在跟环境变量搏斗。这篇文章就是专门写给C语言初学者的,特…

阅读更多 →
Java AI开源量化交易平台:从架构到实战的自动交易工程指南 2026/10/1 19:50:46

Java AI开源量化交易平台:从架构到实战的自动交易工程指南

简介:这是一套基于JAVA的AI开源量化交易平台源码,面向具备一定编程基础的程序员与量化爱好者,覆盖期货、股票、外汇、数字货币等多种交易场景,可实现自动与半自动交易,常被用于替代文华、MC、金字塔等传统工具。平台内…

阅读更多 →
CSDN首页发布文章CSDN同步助手【模拟电力变压器电气测试】使用电磁暂态程序(EMTP)对各种情景进行建模(包括:正常运行、一次绕组故障、铁芯故障)(Matlab代码实现)69 / 10 2026/10/1 19:50:39

CSDN首页发布文章CSDN同步助手【模拟电力变压器电气测试】使用电磁暂态程序(EMTP)对各种情景进行建模(包括:正常运行、一次绕组故障、铁芯故障)(Matlab代码实现)69 / 10

发布文章 ​编辑CSDN同步助手 69 / 100 0 / 256 AI提取摘要 您已同意GitCode 用户协议 和 隐私政策,我们会为您自动创建账号并备份文章至我的项目。 活动 话题 共 0 字 i今日发文额度已用完,可去这里提升额度 反馈已提交,感谢你的帮助。

阅读更多 →
STM32 串口底层深度解析|USART 中断标志、硬件 FIFO,乱码根源底层定位 2026/10/1 19:50:33

STM32 串口底层深度解析|USART 中断标志、硬件 FIFO,乱码根源底层定位

摘要 很多人调试 STM32 串口,只停留在 HAL 库HAL_UART_RxCpltCallback回调函数,遇到乱码、丢字节、偶发接收异常,只会怀疑波特率或者上位机。 但实际上大量工程里的串口玄学 bug,根源来自USART 硬件中断标志理解错误、硬件 FIFO 溢…

阅读更多 →
参保意愿预测5-标签定义与时间切分的坑 2026/10/1 19:50:33

参保意愿预测5-标签定义与时间切分的坑

参保意愿预测5-标签定义与时间切分——一个模型最容易被忽略的两个坑 模型上线后数字对不上业务预期,最常见的两个根源不在模型——在标签定义和时间切分。“最终参保"还是"当年参保”、随机切分还是时间切分——这两个决定比选RF还是GBDT重要一百倍。这篇…

阅读更多 →
基于改进型YOLOv8的森林火灾实时监测系统设计与实现 2026/10/1 19:50:33

基于改进型YOLOv8的森林火灾实时监测系统设计与实现

本研究为森林火灾智能监测提供了坚实的理论依据和高效的技术支持,并且也为计算机视觉技术应用于灾害科学领域开辟了新的实践路径。一、研究背景和问题考察由于全球气候变化越来越强烈、极端天气事件也越来越多地出现,所以森林火灾作为一次突发性很强、危…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉