新闻详情

新闻详情

首页 / 资讯中心 / 详情

果蔬识别数据集系统实战:从12类标签到CNN与MobileNet训练闭环

发布时间:2026/10/2 18:18:12来源:尧图网络
果蔬识别数据集系统实战:从12类标签到CNN与MobileNet训练闭环
简介这份资源面向计算机视觉入门者、课程设计或毕业设计开发者提供一套基于YOLOv5的果蔬识别完整方案覆盖数据集、训练代码与使用教程帮助读者快速搭建可运行的果蔬分类与检测系统。压缩包共56个文件约94.07MB包含14个Python脚本、12个PNG与9个JPG/6个JPEG图像、6个TXT说明、4个XML标注、2个H5权重及1个Markdown文档脚本涵盖数据读取、数据划分、CNN与MobileNet训练、模型测试、实时摄像头识别及错误样本清理等模块图像与权重文件则用于训练、验证和热力图可视化。数据集覆盖土豆、圣女果、大白菜、大葱、梨、胡萝卜、芒果、苹果、西红柿、韭菜、香蕉、黄瓜等常见果蔬类别并附有训练过程记录与测试记录便于对照复现。目前已有3769人学习下载适合希望掌握YOLOv5实战流程、理解数据预处理与模型评估的读者参考。1. 果蔬识别数据集系统从 12 类标签到可跑通的训练闭环拿到一个标着「果蔬识别数据集系统代码教程」的压缩包第一反应往往不是兴奋而是怀疑——里面到底是几张图加一个跑不起来的 demo还是真能从头训到推理的完整工程。这个包我拆过它属于后者12 个类别土豆、圣女果、大白菜、大葱、梨、胡萝卜、芒果、苹果、西红柿、韭菜、香蕉、黄瓜两套模型路线自建 CNN 和 MobileNet 迁移学习外加 PyQt 写的图形界面训练脚本、数据划分脚本、实时摄像头推理脚本都在。它解决的核心问题是你不用再从零攒数据集、搭训练框架、写界面直接进入调参和验证环节。适合两类人——想快速跑通一个图像分类闭环的新手以及需要现成 baseline 做对比实验的从业者。但它不是 YOLOv5 检测工程这点后面会专门讲清楚别被标题里的关键词带偏。2. 拆包先看结构两套模型路线与数据流怎么走2.1 目录里到底有什么哪些是核心解压后第一眼会看到一堆散落的图片bb.jpeg、tmpx.jpg、ccc.jpeg 这类别慌那些是界面素材和测试残留不是数据集本体。真正要盯住的是这几组文件文件/目录作用是否核心train_cnn.py自建 CNN 训练入口核心train_mobilenet.pyMobileNet 迁移学习训练入口核心get_data.py / data_split.py数据读取与训练集划分核心data_read.py数据加载封装核心test_model.py单张/批量测试核心window.py / window_new.pyPyQt 主界面核心window_realtime.py / window_up_camera.py实时摄像头推理核心cnn_fv.h5 / mobilenet_fv.h5预训练好的权重核心utils / remove_wrong_image.py脏数据清理工具辅助jpeg2jpg.py格式统一脚本辅助results 目录训练曲线、热力图、混淆矩阵结果requirements.txt依赖清单必读这里有个容易翻车的点old_train_mobilenet.py是历史版本别拿它当主训练脚本参数和train_mobilenet.py不一致跑出来的曲线对不上。我一般先看readme.md和readme.txt再对照requirements.txt确认环境最后才动训练脚本。2.2 数据是怎么喂进去的get_data.py和data_split.py负责把原始图片按类别整理成训练/验证集。常见做法是按 8:2 或 7:3 切分目录结构通常是每个类别一个文件夹。如果你自己的数据是混在一起的得先手动分好类脚本不会帮你做无监督聚类。data_read.py里一般封装了ImageDataGenerator或自定义 Dataset做归一化和尺寸统一。果蔬图片尺寸参差不齐统一到 224×224 是 MobileNet 的标准输入自建 CNN 也建议对齐这个尺寸否则卷积层维度对不上。# data_read.py 里典型的数据加载逻辑示意以实际文件为准 import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator IMG_SIZE 224 BATCH_SIZE 32 def build_generator(data_dir): datagen ImageDataGenerator( rescale1.0/255, # 归一化到 0-1 validation_split0.2, # 20% 做验证 rotation_range20, # 果蔬摆放角度多变加旋转增强 horizontal_flipTrue, # 水平翻转苹果香蕉左右对称不影响类别 zoom_range0.15 ) train_gen datagen.flow_from_directory( data_dir, target_size(IMG_SIZE, IMG_SIZE), batch_sizeBATCH_SIZE, subsettraining, class_modecategorical ) val_gen datagen.flow_from_directory( data_dir, target_size(IMG_SIZE, IMG_SIZE), batch_sizeBATCH_SIZE, subsetvalidation, class_modecategorical ) return train_gen, val_gen这段逻辑的关键参数是target_size和validation_split。target_size必须和模型输入层一致改了一个另一个也得改。validation_split在数据量少的时候别设太小12 类果蔬如果每类只有几十张验证集太小会导致曲线剧烈抖动看不出真实趋势。数据增强里的rotation_range和zoom_range对果蔬场景是合理的因为拍摄角度和距离本来就多变但别加vertical_flip倒过来的香蕉和正着的香蕉在语义上不该被当成同一类增强。3. 两条训练路线怎么选自建 CNN 还是 MobileNet 迁移3.1 自建 CNN 的适用边界train_cnn.py走的是从零搭卷积网络的路子。它的优势是完全可控层数、卷积核大小、池化策略都能改适合教学和理解特征提取过程。缺点是数据量不够时容易过拟合12 类果蔬如果每类只有一两百张自建 CNN 的验证准确率往往卡在 70% 上下上不去。results_cnn.png和cnn训练过程.txt记录的就是这条线的表现你可以先看这两个文件判断原始数据量下自建网络的天花板在哪。# train_cnn.py 核心结构示意 from tensorflow.keras import layers, models def build_cnn(num_classes12): model models.Sequential([ layers.Conv2D(32, (3,3), activationrelu, input_shape(224,224,3)), layers.MaxPooling2D(2,2), layers.Conv2D(64, (3,3), activationrelu), layers.MaxPooling2D(2,2), layers.Conv2D(128, (3,3), activationrelu), layers.MaxPooling2D(2,2), layers.Flatten(), layers.Dense(256, activationrelu), layers.Dropout(0.5), # 关键全连接层前加 dropout 抑制过拟合 layers.Dense(num_classes, activationsoftmax) ]) model.compile(optimizeradam, losscategorical_crossentropy, metrics[accuracy]) return modelDropout(0.5)是这条线里最该保留的一层去掉它过拟合会明显加重。学习率用默认的 adam 就行但如果你发现 loss 在前几个 epoch 就炸成 nan把学习率降到 1e-4 再试。num_classes必须和实际类别数一致这个包里是 12如果你自己增删了类别这里和data_read.py里的类别映射要同步改否则 softmax 输出维度对不上报错信息还不直观。3.2 MobileNet 迁移学习为什么更适合这个场景train_mobilenet.py加载预训练的 MobileNet 权重冻结卷积基只训练顶部分类层。这是小数据集上的标准打法mobilenet_fv.h5就是训好的结果。results_mobilenet.png和heatmap_mobilenet.png能看出它比自建 CNN 收敛更快、验证准确率更高。热力图还能告诉你模型到底在看哪里——如果热力集中在果蔬主体上说明特征学对了如果散在背景上说明数据里背景干扰太大得回去清洗数据。# train_mobilenet.py 迁移学习核心示意 from tensorflow.keras.applications import MobileNetV2 from tensorflow.keras import layers, models, optimizers base_model MobileNetV2(weightsimagenet, include_topFalse, input_shape(224,224,3)) base_model.trainable False # 冻结卷积基 model models.Sequential([ base_model, layers.GlobalAveragePooling2D(), layers.Dense(128, activationrelu), layers.Dropout(0.3), layers.Dense(12, activationsoftmax) ]) model.compile(optimizeroptimizers.Adam(1e-3), losscategorical_crossentropy, metrics[accuracy])base_model.trainable False是迁移学习的关键开关。数据量特别少的时候保持冻结如果数据量够每类上千张可以解冻最后几个卷积块做微调但学习率要调小到 1e-5 量级否则预训练权重会被冲垮。GlobalAveragePooling2D替代Flatten能大幅减少参数量降低过拟合风险这是 MobileNet 路线的常见做法。3.3 训练完怎么验证不是自欺欺人test_model.py是验证入口results目录里的混淆矩阵比准确率更有信息量。12 类里最容易混的是颜色和形状接近的类别比如土豆和胡萝卜在某些光照下、大白菜和大葱的局部纹理。看混淆矩阵时重点盯非对角线上的大数值那才是真正需要补数据的方向。测试记录.txt里如果记录了不同轮次的测试结果可以对比看模型是否稳定。# 典型测试命令以实际脚本参数为准 python test_model.py --model mobilenet_fv.h5 --image test_samples/apple_01.jpg如果脚本用的是 argparse--model和--image是常见参数名如果直接硬编码路径就去test_model.py里改MODEL_PATH和TEST_IMG两个变量。测试单张图只能看个感觉真正判断模型好坏要跑一批留出集看整体准确率和各类召回率。4. 图形界面与实时推理从脚本到能演示的系统4.1 PyQt 界面怎么跑起来window.py和window_new.py是主界面入口window_up_camera.py和window_realtime.py负责摄像头实时识别。跑界面之前先确认 PyQt5 装好了requirements.txt里应该有。常见报错是No module named PyQt5.QtWidgets那就是没装或装到了别的 Python 环境里。pip install -r requirements.txt python window_new.py界面里一般有「选择图片」「开始识别」「摄像头」几个按钮识别结果会叠加在图片上或单独显示类别和置信度。window_up_camera.py和window_realtime.py的区别通常是前者单帧上传识别后者连续帧实时推理。实时推理对帧率有要求MobileNet 比自建 CNN 轻量更适合实时场景。4.2 实时推理的延迟与帧率怎么调实时识别卡顿通常不是模型慢而是每帧都在做完整的预处理和后处理。常见优化是降低输入分辨率比如从 224 降到 160、跳帧推理每两帧识别一次、或者把模型转成 TensorFlow Lite 格式。这个包里没带 TFLite 转换脚本但你可以自己加# 把 h5 模型转成 tflite用于边缘部署 import tensorflow as tf converter tf.lite.TFLiteConverter.from_keras_model(model) converter.optimizations [tf.lite.Optimize.DEFAULT] # 默认量化体积和延迟都降 tflite_model converter.convert() with open(mobilenet_fv.tflite, wb) as f: f.write(tflite_model)Optimize.DEFAULT会做动态范围量化模型体积大概降到原来的四分之一推理速度提升明显精度损失通常在 1 个百分点以内。如果你要在树莓派这类设备上部署这一步基本是必做的。转完之后用tf.lite.Interpreter加载验证确认输出和原模型一致再替换到实时脚本里。5. 避坑与排查那些让我重跑训练的血泪经验5.1 类别数对不上导致 softmax 维度报错现象训练启动就报ValueError: Shapes (None, 12) and (None, 10) are incompatible。原因data_read.py里实际读到的类别数和模型输出层Dense的单元数不一致常见于你增删了类别文件夹但没改模型定义。解决先打印train_gen.class_indices确认实际类别数和映射顺序再把模型最后一层Dense(num_classes)改成一致的值同时检查class_modecategorical下标签是否做了 one-hot。5.2 图片格式不统一导致读取失败现象训练中途报UnidentifiedImageError或某些图片被跳过。原因目录里混了 jpeg、jpg、png 甚至损坏文件ImageDataGenerator对格式敏感。解决先跑jpeg2jpg.py统一格式再用remove_wrong_image.py清理打不开的文件。我一般会在训练前加一段校验遍历所有图片尝试打开把失败的路径打印出来人工确认。5.3 验证集准确率虚高其实是数据泄漏现象验证准确率 99%但拿新图片测试一塌糊涂。原因data_split.py划分时同一张图的增强版本同时进了训练集和验证集或者同一物体的多角度照片被分到了两边。解决划分前先按物体或拍摄批次分组确保同一组只出现在一边。数据量少的时候这个坑特别隐蔽混淆矩阵好看但实际不能用。5.4 显存/内存不足导致训练中断现象训练到一半进程被杀日志里出现OOM或Killed。原因BATCH_SIZE设太大或者ImageDataGenerator开了太多缓存。解决把 batch size 从 32 降到 16 或 8data_read.py里如果有cache()或prefetch()也适当调小。CPU 训练的话更要注意trash_tf2.3_cpu.iml这个文件名暗示原始工程就是在 CPU 环境跑的batch size 别贪大。5.5 界面能跑但识别结果全是同一类现象摄像头实时识别每帧都输出同一个类别置信度还很高。原因输入图像的预处理和训练时不一致比如训练时做了归一化但推理时忘了或者通道顺序从 RGB 变成了 BGR。解决把推理时的预处理代码和data_read.py里的对齐逐行比对rescale、target_size、通道顺序。这个坑排查起来费时间但一旦对上就恢复正常。6. 把 12 类果蔬识别接到 YOLOv5 检测链路上的思路这个包本身是分类工程不是检测工程但标题里带了 YOLOv5很多人是冲着检测来的。如果你确实需要「在图里框出每个果蔬的位置并分类」纯分类模型给不了边界框得走检测路线。可行的做法是用这个包里的分类数据和 MobileNet 权重做特征 backbone再套一个检测头或者直接把分类数据转成 YOLO 格式重新训。转换的核心是把「每张图一个类别标签」变成「每张图若干边界框加类别」。如果原图是单物体居中拍摄可以用简单的阈值分割或手动标注生成伪框如果原图是多物体混拍就必须人工标注。我一般会先用分类模型筛一遍把高置信度的图挑出来做半自动标注再人工修正能省不少时间。# 分类目录转 YOLO 格式的简化思路单物体居中场景 import os, cv2 def convert_to_yolo(img_path, class_id, out_label_path): img cv2.imread(img_path) h, w img.shape[:2] # 单物体居中假设框取图像中心 80% 区域 x_center, y_center 0.5, 0.5 bw, bh 0.8, 0.8 with open(out_label_path, w) as f: f.write(f{class_id} {x_center} {y_center} {bw} {bh}\n)这段只是演示格式真实场景千万别用固定框一定要按实际物体位置标注。YOLO 的标签格式是class_id x_center y_center width height全部归一化到 0-1。类别 id 要和data.yaml里的names顺序严格对应错一位整个训练就废了。转完之后用yolov5的train.py跑之前先拿几张图可视化验证标签框位置对不对这一步偷懒后面全是后悔药。验证检测模型和分类模型的指标不一样分类看准确率检测看 mAP0.5 和 mAP0.5:0.95。如果你只是想做果蔬识别演示分类加界面已经够用如果要做货架盘点、分拣计数这类需要定位的任务才值得上检测。从那以后我每次拿到带 YOLOv5 关键词的资源都先确认它是分类还是检测再决定要不要走转换这条路省得白跑一轮训练。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

【共创稿事节】HarmonyOS 7空间信息层级:焦点、景深与注意力引导 2026/10/2 20:40:43

【共创稿事节】HarmonyOS 7空间信息层级:焦点、景深与注意力引导

平面界面里,用户的眼睛被屏幕边界框着,注意力顶多在矩形内跳来跳去。空间界面没有这个框,用户能看的地方变多了,注意力反而更容易散。这时候设计的活儿就是主动引导:明确告诉用户"先看这里,再看那里&q…

阅读更多 →
言出法随系列1-用TaoToken统一Key接入Trae开发“复制EXCEL内容转MARKDOWN” 2026/10/2 20:40:43

言出法随系列1-用TaoToken统一Key接入Trae开发“复制EXCEL内容转MARKDOWN”

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Jev本地推理服务实战:Windows部署与Codex接入全指南 2026/10/2 20:40:43

Jev本地推理服务实战:Windows部署与Codex接入全指南

最近这几周,“Jev”这个名字突然在开发者圈子里密集出现。技术群、开源社区、甚至短视频里都在聊,有人问它到底是不是新出的通用大模型,有人问能不能部署在 Windows 上,还有人已经在问能不能把 Jev 接进 Codex 里当作本地推理引擎…

阅读更多 →
从零构建AI工程:拆解数据管线、模型微调与推理服务全链路 2026/10/2 20:40:43

从零构建AI工程:拆解数据管线、模型微调与推理服务全链路

如果你最近在逛 GitHub、刷技术社区,大概率会看到那个有些特别的仓库名:ai-engineering-from-scratch。这个“from scratch”不是指从零手写神经网络,也不是让你造 GPU,而是指一条几乎不靠平台封装、把 AI 应用的每个环节都自己动…

阅读更多 →
AI Agent Harness Engineering 的工具返回如何结构化:JSON 约定最佳实践与 TaoToken 统一 Key 接入 2026/10/2 20:40:36

AI Agent Harness Engineering 的工具返回如何结构化:JSON 约定最佳实践与 TaoToken 统一 Key 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Claude Code 4.8 多语言实测:Python/JS/Java 全覆盖,TaoToken 统一 Key 配置怎么搭? 2026/10/2 20:40:36

Claude Code 4.8 多语言实测:Python/JS/Java 全覆盖,TaoToken 统一 Key 配置怎么搭?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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