首页/新闻资讯/正文详情

TensorFlow花朵识别项目实战:从源码解析到迁移学习与模型预测

发布时间:2026/9/20 23:59:18 来源:云帆数科 栏目:资讯中心
TensorFlow花朵识别项目实战:从源码解析到迁移学习与模型预测
简介基于深度学习TensorFlow框架实现的花朵识别项目源码包面向计算机视觉入门者以及需要完成毕业设计、期末大作业或课程设计的学生提供一套下载后即可运行的完整工程解决从零搭建模型和准备数据的痛点。压缩包共238个文件以196张jpeg花朵图片与19个Python脚本为主体辅以DenseNet201.h5预训练模型、flower_info.db数据库、xml标注文件及png/jpg辅助素材整体约68.89MB目录结构清晰便于按数据、模型、脚本分类查阅。目前已有1811人学习下载可作为入门深度学习的实战参照。项目包含数据读取、模型加载、推理预测与结果保存等关键环节代码完整且无需修改可在现有模型基础上替换自己的花朵图片进行验证也方便根据课程要求调整流程是一份能快速落地的高分项目模板。1. 拿到 TensorFlow 花朵识别项目源码时先确认这三件事从网上下到一个python实现基于深度学习TensorFlow框架的花朵识别项目源码.zip解压后大多数人缺的不是 Python而是“先看什么”的顺序。这个项目的核心链路很清楚用 Python 读图片用 TensorFlow 搭分类模型再对花图片做预测而源码能不能跑起来关键看点并不是模型有多深而是数据目录、依赖版本和保存格式。我一般先把 zip 解开按顺序确认三件事数据集文件夹是不是 train/valid/test 结构requirements.txt 里 TensorFlow 版本和本机 Python 版本是否匹配模型文件是.h5、.keras还是只保存了权重。这三项确认完后面的训练和推理才有处下手。适合刚接触深度学习的 Python 开发者也适合想从纯调库转向理解训练流程的工程师。2. 解压后的数据组织用 tf.data 把花朵图片变成训练集2.1 目录结构约定train/valid/test 怎么分绝大多数花朵识别项目源码会把数据集按类别分目录而不是靠文件名判断类别。原因很直接image_dataset_from_directory会把一级子目录名直接当成标签省掉手写标签映射。常见的目录结构如下目录作用示例数量data/train训练集参与梯度更新2500 张data/valid验证集每轮评估500 张data/test测试集只做最终评估200 张每个目录下再按类别英文名建一层目录例如daisy、roses、sunflowers。如果源码给的是一个包含全部图片的大文件夹加一张 CSV 标签表我会先把 CSV 里的 label 字段转成文件夹思路移动文件后再交给 TensorFlow 读取。处理完先打印一次数量确认没有类别被漏掉。import pathlib data_root pathlib.Path(data/train) for d in sorted(data_root.iterdir()): if not d.is_dir(): continue jpg_count len(list(d.glob(*.jpg))) png_count len(list(d.glob(*.png))) print(f{d.name}: {jpg_count png_count})这段代码把data/train下每个子目录当成一个类别统计其中 JPG 和 PNG 图片总数。sorted()保证输出顺序稳定避免每跑一次结果顺序都变。如果某个类别数量异常少通常不是目录建错而是子目录里混有损坏图片或隐藏文件这一步比打开文件管理器逐个翻目录可靠得多。注意别把Thumbs.db、.DS_Store这类隐藏文件放进类别目录TensorFlow 加载时会尝试解码非图片文件容易抛出UnidentifiedImageError。2.2 用 image_dataset_from_directory 生成数据集TensorFlow 2 里最省事的方案是直接用 Keras 的预处理工具生成 Dataset不需要自己写生成器。下面这段代码是一个能直接嵌进源码的最小加载方案import tensorflow as tf IMG_SIZE (224, 224) BATCH_SIZE 32 train_ds tf.keras.preprocessing.image_dataset_from_directory( data/train, labelsinferred, label_modecategorical, batch_sizeBATCH_SIZE, image_sizeIMG_SIZE, shuffleTrue, seed42, validation_split0.2, subsettraining, interpolationbilinear, ) val_ds tf.keras.preprocessing.image_dataset_from_directory( data/train, labelsinferred, label_modecategorical, batch_sizeBATCH_SIZE, image_sizeIMG_SIZE, shuffleTrue, seed42, validation_split0.2, subsetvalidation, interpolationbilinear, )这里label_modecategorical会返回 one-hot 标签形状是(batch, 类别数)后面配合CategoricalCrossentropy使用如果改成sparse标签就是整数损失函数必须换成SparseCategoricalCrossentropy显存占用略低。validation_split0.2会在每个类别内部做切分因此生成训练集和验证集时必须用同一个seed否则两个集合会出现重叠。interpolationbilinear是缩放图片时用的双线性插值默认值已经够用nearest速度更快但会有锯齿。2.3 数据增强和预处理preprocess_input 要放在哪一步花朵识别项目样本量通常不大训练集里加一些在线增强能明显降低过拟合。常见做法是构造一个Sequential增强层再通过map挂到 Dataset 上。data_augmentation tf.keras.Sequential([ tf.keras.layers.RandomFlip(horizontal), tf.keras.layers.RandomRotation(0.1), ]) def preprocess_input_batch(images, labels): images tf.keras.applications.mobilenet_v2.preprocess_input(images) return images, labels train_ds train_ds.map(lambda x, y: (data_augmentation(x, trainingTrue), y)) train_ds train_ds.map(preprocess_input_batch) val_ds val_ds.map(preprocess_input_batch) train_ds train_ds.prefetch(tf.data.AUTOTUNE) val_ds val_ds.prefetch(tf.data.AUTOTUNE)RandomFlip只做水平翻转对花朵图片不会带来不合理的语义翻转RandomRotation(0.1)的单位是弧度约等于 5.7 度旋转角度再大会把花芯裁出有效区域。preprocess_input_batch是迁移学习里最容易漏掉的一步它会把 0-255 的 RGB 像素按 ImageNet 统计值归一化到模型期望的分布。这里先增强、后归一化顺序不能反否则增强层处理的是已经标准化后的数据调色和几何变换效果都会变。prefetch(tf.data.AUTOTUNE)让数据读入和 GPU 训练重叠不需要手动指定预取数量。到这里训练集、验证集和预处理路径就齐全了接下来要看模型结构怎么接住这两个 Dataset。3. 用 TensorFlow 训练花朵识别项目迁移学习参数与回调设置3.1 自建 CNN 还是直接加载预训练模型花朵识别属于图像分类样本量常常只有几千张从零训练完整 CNN 很容易过拟合。TensorFlow 的tf.keras.applications里自带多个预训练模型MobileNetV2参数量小、CPU 上也能跑是花朵识别源码里最常见的选择之一。base_model tf.keras.applications.MobileNetV2( weightsimagenet, include_topFalse, input_shape(224, 224, 3), ) base_model.trainable False model tf.keras.Sequential() model.add(base_model) model.add(tf.keras.layers.GlobalAveragePooling2D()) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.Dense(5, activationsoftmax, nameflower_probs))weightsimagenet表示加载预训练权重include_topFalse去掉原模型顶部的全连接层只保留卷积特征提取部分。base_model.trainable False会把 ImageNet 权重冻结训练时只更新后面的分类头在小数据集上这是最稳妥的起手式。最后的Dense(5)里的 5 必须和数据集类别数一致如果写错训练第一轮就会在 loss 计算时报维度不匹配。如果源码里本身是手写几层Conv2D的 CNN也别急着删掉。预训练模型能提升准确率但手写模型更容易让你看清每个 Batch 经过卷积、池化、全连接之后形状是怎么变化的。拿同一个验证集跑 20 轮手写 CNN 通常比迁移学习低 5 到 10 个百分点但至少能帮你确认数据回路和标签逻辑没写错。3.2 compile、fit 与回调的默认参数训练参数是源码里改动最频繁的部分。下表是我对一个 5 类花朵项目常用的初始值参数初始值说明optimizerAdam(learning_rate1e-3)通用适应小数据集lossCategoricalCrossentropy()对应 one-hot 标签metrics[accuracy]分类任务常用 top-1 准确率epochs50配合 EarlyStopping 使用batch_size32显存不足时降到 16model.compile( optimizertf.keras.optimizers.Adam(learning_rate1e-3), losstf.keras.losses.CategoricalCrossentropy(), metrics[accuracy], ) callbacks [ tf.keras.callbacks.EarlyStopping( monitorval_loss, patience5, restore_best_weightsTrue ), tf.keras.callbacks.ReduceLROnPlateau( monitorval_loss, factor0.2, patience2, min_lr1e-6 ), tf.keras.callbacks.ModelCheckpoint( flower_model.keras, save_best_onlyTrue ), ] history model.fit( train_ds, validation_dataval_ds, epochs50, callbackscallbacks, )EarlyStopping的restore_best_weightsTrue会自动把模型恢复到验证损失最小的那一轮比手动保存权重更省心。ModelCheckpoint保存成.keras格式这是 TensorFlow 2.x 推荐的新格式如果源码里写的是.h5继续用也没问题load_model两种都能接。ReduceLROnPlateau在验证损失连续两轮不降时把学习率乘以 0.2能帮模型绕过损失平台期。要继续提升准确率常见做法是微调先把base_model.trainable设置为 True再把优化器学习率降到 1e-5 左右重新compile后继续训练。很多深度学习的实践教程包括《动手深度学习》里讲迁移学习的章节都推荐这个两阶段流程先冻结特征提取器训练分类头再解冻浅层卷积层低学习率微调。在花朵识别项目里我一般只解冻最后 20 层避免前层把通用特征改坏。3.3 loss 不降与显存不足的排查训练时如果看到 loss 一直停在某个值附近不动先确认标签模式。label_modecategorical配CategoricalCrossentropy是标配如果数据集类别不均衡直接在Dense层的输出上加权比频繁改模型更直接。显存不足时把BATCH_SIZE调成 16同时确认 Dataset 上已经加了prefetch。读取阶段出现UnicodeDecodeError基本是目录里混进了非图片文件把那些文件移走就能解决。迁移学习这一层的参数捋顺之后训练回路基本能跑通。下一步要看保存下来的模型怎么应用在推理代码里。4. 从训练好的 TensorFlow 模型到花朵识别预测代码4.1 load_model 和 load_weights 不要混用项目源码里如果用model.save()保存过完整模型恢复时只需要一行load_modelimport tensorflow as tf model tf.keras.models.load_model(flower_model.keras)load_model会恢复模型结构、优化器状态和编译信息适合继续训练或直接推理。如果源码保存的是model.save_weights()则必须先重建一模一样的模型结构再调用model.load_weights(weights.weights.h5)。很多人一开始会把两者搞混直接把加载权重的结果赋给一个空模型然后推理得到随机结果。区别整理成表保存方式恢复方式适用场景model.save(model.keras)tf.keras.models.load_model部署或继续训练model.save_weights(w.h5)先重建结构再 load_weights只换权重结构固定实际项目里如果源码只提供了.h5权重而没有模型架构别急着跑先找模型定义代码否则加载出来的变量名对不上。4.2 单张图片预测预处理必须和训练时一致推理代码最容易错在预处理上。第 2 章我们用了mobilenet_v2.preprocess_input预测时必须走同一个函数不能用x / 255.0替代否则模型输入的分布和训练时不一致置信度会整体偏移。下面给一个完整的单图预测函数import tensorflow as tf import pathlib data_root pathlib.Path(data/train) class_names sorted([d.name for d in data_root.iterdir() if d.is_dir()]) def predict_flower(image_path, model, class_names): img tf.keras.utils.load_img(image_path, target_size(224, 224)) arr tf.keras.utils.img_to_array(img) arr tf.expand_dims(arr, axis0) arr tf.keras.applications.mobilenet_v2.preprocess_input(arr) probs model.predict(arr, verbose0)[0] top_idx int(tf.argmax(probs).numpy()) return class_names[top_idx], float(probs[top_idx])load_img会直接把图片解码并缩放到(224, 224)返回的是 PIL 图像对象。img_to_array把它变成 float32 数组tf.expand_dims加上 batch 维最终形状是(1, 224, 224, 3)。model.predict(verbose0)不打印进度条返回的probs形状是(1, 类别数)。top_idx是最大概率下标传给class_names就得到类别名。如果训练时用的是label_modecategorical这里的类别顺序要和image_dataset_from_directory推断的顺序保持一致而它本身就是按目录名排序所以上面的sorted()是安全的。4.3 批量推理时保留真实标签很多源码只输出预测结果不保存真实类别导致后面没法做错误分析。我一般会把真实标签、预测标签和置信度一起写进 JSONimport json import pathlib test_root pathlib.Path(data/test) paths list(test_root.glob(*/*.jpg)) results [] for p in paths[:50]: pred_name, conf predict_flower(str(p), model, class_names) true_name p.parent.name results.append({ file: str(p), true: true_name, pred: pred_name, confidence: round(conf, 4), is_correct: true_name pred_name, }) with open(flower_inference.json, w, encodingutf-8) as f: json.dump(results, f, ensure_asciiFalse, indent2)这里glob(*/*.jpg)会遍历 test 目录下每个类别子目录p.parent.name拿到真实标签。paths[:50]限制数量是为了快速验证推理管线没问题完整跑一遍时再放开。JSON 里同时保存路径和标签之后画混淆矩阵或者统计置信度阈值都直接能从这份文件里取不用重新推理一遍。5. 把花朵识别项目源码改造成自己的数据集时最后这三项校验别跳过5.1 先做一次类别计数再决定要不要补数据拿到新数据集时我会先跑一遍数量统计而不是直接开始训练。复用一个实际类别只有 30 张、其他类别 500 张的数据集模型很容易把少样本类别直接忽略。对数量特别少的类别不要靠复制文件硬凑更常见的做法是在 Dataset 上给少样本类额外做更强的增强比如随机裁剪和随机色彩抖动这样每个 epoch 看到的样本都有变化训练稳定性会好很多。5.2 用 TensorBoard 看曲线别只盯着终端数字TensorBoard 能直观暴露过拟合。训练时在 callbacks 里补上callbacks.append( tf.keras.callbacks.TensorBoard(log_dirlogs/flowers, update_freqepoch) )训练结束后在项目根目录执行tensorboard --logdir logs/flowers浏览器打开 6006 端口重点看loss和validation_loss两条曲线。如果训练 loss 一路下降、验证 loss 掉头向上说明模型在记忆背景纹理而不是花形状。这时优先增强RandomRotation和RandomZoom不要急着加深卷积层。5.3 给预测结果加一个置信度阈值分支最后一个小技巧是给预测函数加 unknown 出口避免把一张不是花的图片硬预测成某种花。def predict_with_reject(image_path, model, class_names, thresh0.6): pred, conf predict_flower(image_path, model, class_names) if conf thresh: return unknown, conf return pred, conf阈值不要拍脑袋定。先跑一遍验证集把错误预测的置信度分布拉出来看大多数误判的置信度会集中在 0.4 到 0.7 区间取这个区间上沿做阈值比继续加模型层更划算。修改完阈值重新生成一次flower_inference.json确认新增的 unknown 不会影响真正类别样本的统计口径。本文还有配套的精品资源点击获取

相关推荐

git-tips 实战手册:Log 与 History 的 40 个高效命令详解
git-tips 实战手册:Log 与 History 的 40 个高效命令详解

文档教程版本控制 【免费下载链接】tips Most commonly used git tips and tricks. 项目地址: https://gitcode.com/gh_mirrors/ti/tips 点击查看 免费下载 本篇技术指南以开源仓库 ti/tips(Most commonly used git tips and tricks)中 docs… · 2026/9/20 23:59:18

Hugging Face / OpenRouter:Qwen3.7 Flash 通过 TaoToken 跑 Agent
Hugging Face / OpenRouter:Qwen3.7 Flash 通过 TaoToken 跑 Agent

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

Sails 动态内容国际化(Translating Dynamic Content)实战指南:从 JSON stringfile 到数据库驱动的多语言方案
Sails 动态内容国际化(Translating Dynamic Content)实战指南:从 JSON stringfile 到数据库驱动的多语言方案

Sails 动态内容国际化(Translating Dynamic Content)实战指南:从 JSON stringfile 到数据库驱动的多语言方案 【免费下载链接】sails Realtime MVC Framework for Node.js 项目地址: https://gitcode.com/gh_mirrors/sa/sails 导读 当… · 2026/9/20 23:58:17

2026年AI技术全景:多模态模型与神经符号系统突破
2026年AI技术全景:多模态模型与神经符号系统突破

1. 2026年AI领域技术全景扫描2026年3月的AI领域正经历着前所未有的技术迭代浪潮。作为一名跟踪AI技术演进7年的从业者,我注意到当前技术发展呈现出三个显著特征:模型架构的异构化、应用场景的垂直化以及开发工具的平民化。今天的日报将重点解析三个最具突… · 2026/9/21 1:40:40

LibreChat:面向Agent协作的MCP协议基础设施
LibreChat:面向Agent协作的MCP协议基础设施

1. LibreChat不是另一个ChatGPT前端,而是Agent时代的基础设施探针LibreChat这个名字,第一眼容易被当成又一个开源版ChatGPT网页界面——毕竟它长得太像了:左侧对话列表、右侧聊天窗口、顶部模型切换栏。但如果你真把它当“UI套壳”用上一周&a… · 2026/9/21 1:40:40

Claude API账单暴涨?三步拆解用量与成本控制实战
Claude API账单暴涨?三步拆解用量与成本控制实战

上个月底我打开 Claude API 的账单,看到那个数字的时候人直接愣住了。我自认为用量控制得还不错,结果账单比上个月翻了快两倍。点进 Anthropic Console 的 Usage 页面,满屏的 token 数字、模型名称、时间区间,说实话第一眼根本看不… · 2026/9/21 1:40:40

激光里程计+IMU融合:解决ROS小车定位漂移的实战方案
激光里程计+IMU融合:解决ROS小车定位漂移的实战方案

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

ROS2+Gazebo搭建Franka机械臂仿真环境避坑指南
ROS2+Gazebo搭建Franka机械臂仿真环境避坑指南

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

VitePress 默认主题侧边栏(Sidebar)配置完全指南:分组、多侧边栏、折叠与路径前缀
VitePress 默认主题侧边栏(Sidebar)配置完全指南:分组、多侧边栏、折叠与路径前缀

VitePress 默认主题侧边栏(Sidebar)配置完全指南:分组、多侧边栏、折叠与路径前缀 【免费下载链接】vitepress Vite & Vue powered static site generator. 项目地址: https://gitcode.com/gh_mirrors/vi/vitepress 侧边栏是 Vite… · 2026/9/21 1:39:40

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化
Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡… · 2026/9/21 0:02:39

Word表格编号全攻略:从列表编号到题注交叉引用
Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技… · 2026/9/21 0:02:39

从第一个站到第二个站:独立开发者的静态网站选型与落地实践
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&… · 2026/9/20 0:00:41

Claude Code 按智谱AI指南装完,ANTHROPIC_BASE_URL 改走 TaoToken 兼容通道行不行
Claude Code 按智谱AI指南装完,ANTHROPIC_BASE_URL 改走 TaoToken 兼容通道行不行

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

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程
agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and … · 2026/9/21 0:00:18

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,… · 2026/9/21 0:00:18

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码