ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python植物识别系统:CNN与MobileNet双模型源码全解析

Python植物识别系统:CNN与MobileNet双模型源码全解析 简介一套基于卷积神经网络的Python植物识别系统源码包面向深度学习初学者、计算机视觉方向学生及需要快速搭建图像分类演示的开发者。工程内置训练好的两组模型权重可对上传图片直接预测植物种类也可用训练脚本在自定义数据上继续调优项目提供PyQt5可视化界面、验证集准确率测试脚本及训练过程曲线记录方便对比不同网络结构效果。资源共1391个文件以1350张jpg图片数据集为主另有15个py脚本、8张png图表、4个xml标注、4个h5模型权重及少量说明文档压缩包约252.81MB目录按图片、模型、结果等模块划分便于按流程查阅。已有225人学习下载。通过models目录可加载现成模型结合mainwindow.py即可启动界面预测是理解卷积特征提取与MobileNet轻量化应用的完整示例。1. Python植物识别系统拆解CNN与MobileNet双模型这份源码能让你少走两个月弯路判断一个图像识别项目能不能直接拿来用我一般先看两点模型文件是否完整训练代码是否闭环。这套基于CNN卷积神经网络的Python植物识别系统压缩包解压后正好踩中这两点——train_cnn.py和train_mobilenet.py分别负责CNN和MobileNet两套模型的训练models目录下是训练好的四个h5权重文件数据集、训练日志和评估脚本也在项目里一并给出。results目录里放着训练过程的loss曲线图和准确率变化txttestmodel.py能独立评估模型在验证集上的表现。最外层是mainwindow.py一个基于PyQt5的桌面界面上传图片直接出预测结果。对正在做python图像分类任务、需要完整参考链路的人来说这套流程从数据到部署没有断档值得下载后仔细拆一遍。2. 项目结构与模型文件解读四个h5文件不是冗余是两条完整的技术路线拿到解压后的文件夹第一件事不是急着跑代码而是把每个目录和文件的作用对一遍。这个项目的文件层级不深但每个文件背后都有明确的职能分工。理解清楚之后后续无论是改代码还是排查问题都会快很多。2.1 目录角色拆解images、models、results各自承担什么先从顶层目录结构看起。整个项目的文件能被划成四组预测用的、训练用的、评估用的、以及界面展示用的。具体对应关系如下表文件/目录类型实际作用images/目录存放测试图片和GUI界面展示用的素材包括ccc.jpeg、tmpx.jpeg、cc.jpeg、bbb.jpeg等models/目录存放训练好的四个模型权重文件cnn_fv.h5、cnn_flower.h5、mobilenet_fv.h5、mobilenet_flower.h5results/目录保存训练过程的可视化输出两个txt是训练日志两张图是训练/验证集准确率与loss曲线train_cnn.py脚本CNN模型的训练入口train_mobilenet.py脚本MobileNet模型的训练入口testmodel.py脚本在验证集上评估模型准确率的测试脚本mainwindow.py脚本PyQt5界面负责上传图片并调用模型预测cnn_plant_identification.iml配置IDE模块识别文件不影响运行.gitignore配置git忽略规则与训练逻辑无关images目录里的图片是调试阶段随手放进去的测试样本ccc.jpeg、tmpx.jpeg这类命名明显是临时截取的图片不是精心整理的测试集。GUI界面里大概率有图片预览区域会直接引用images下的文件。真正跑通预测后你可以随时往images里丢新的测试图片只要在mainwindow.py的上传逻辑中能选到它就行。models目录存放的四个h5文件是整个项目最核心的部分。文件命名规则暴露了训练策略带_flower后缀的模型是在原始花朵图像上直接训练的版本带_fv后缀的模型则是在特征向量feature vector上训练的版本。MobileNet的两个文件对应着迁移学习的两条路线这一点在第四章详细展开。你还会注意到cnn_fv.h5和mobilenet_fv.h5两个文件它们主要服务于快速批量特征比较的场景不适合直接喂原始图片。results目录里的txt文件是训练过程中的标准输出存档。每次epoch结束模型会把当前的loss值、准确率等指标打印出来txt就是这些输出的完整记录。两张图则是准确率和loss变化曲线的可视化一个模型对应一张图可以直接判断训练过程有没有过拟合。这些信息对调参特别重要训练完先看results再决定要不要继续比瞎猜epoch数靠谱得多。2.2 CNN与MobileNet的选型逻辑为什么同一份数据要训练两套模型有人会疑惑既然最终目标是识别植物用一套CNN模型就够了为什么还要单独训练一套MobileNet这不是冗余是两条用途不同的技术路线。CNN卷积神经网络是图像分类任务的标准起点。它通过卷积层提取局部特征池化层降维全连接层完成分类。对这个项目而言先跑通CNN意味着先把基线准确率拿住后续所有优化都可以和这个基线做对比。train_cnn.py里实现的应该是一个序列式结构卷积层和池化层交替堆叠最后一层接softmax输出类别概率。这类模型在植物识别上的效果主要取决于数据量和数据多样性——数据量不大时浅层CNN反而比深层网络更稳不容易一上来就过拟合。MobileNet则是为移动端和轻量化场景设计的网络结构核心是深度可分离卷积depthwise separable convolution把标准卷积拆成逐通道卷积和1x1逐点卷积两步计算量直接下降一个量级。在同样一批植物数据上MobileNet的参数量比全连接CNN更少拟合能力不一定弱甚至在某些数据集上迭代更快。两套模型放在一起对比能直观看到模型架构对最终准确率和训练时间的影响。从实际使用角度看CNN模型适合跑本地离线预测对硬件要求低MobileNet模型则更方便后续导出为嵌入式或服务端部署。我一般会建议在PC上调试时用CNN版本因为它的训练曲线更容易读懂MobileNet版本在数据量不大时表现也不差两者互为对照改代码时不容易盲调。很多人用yolov8训练自己的数据集做目标检测而植物识别这种细粒度图像分类任务用CNN加经典分类头是更直接的路线两套模型并存恰好方便你做横向对比。2.3 四个h5文件的适用边界_fv和_flower怎么选_flower和_fv的区别本质上是“端到端学习”和“特征工程”两种思路的差异。_flower模型输入的是原始图像模型自己从像素里学习特征这也是现在深度学习的主流做法。_fv模型则是在提取好的特征向量上训练特征提取通常来自某个预训练网络的全连接层输出或池化层输出分类器只需要在这些特征上做映射。实际使用时如果你手里有一张新的植物图片优先加载_flower模型直接预测因为它接受的输入是原始图像走完预处理流程后喂进去就行。如果你手里是批量图像特征或者想快速比较不同分类器在同一特征集上的表现_fv模型更合适。还有一点要注意四个h5的输入尺寸可能不一样MobileNet一般要求224x224CNN为了适配训练数据可能用的是其他尺寸预测前最好先打印一下模型输入层确认。提示用model.summary()或者打印model.input_shape能直接看到每个h5模型期望的输入尺寸。很多人预测结果不对第一步就栽在这一行。这一章的核心结论是先把目录职责和模型边界搞清楚后续跑代码、改训练、查问题才有一个清晰的地图。接下来进入复现环节直接看GUI和预测代码怎么用起来。3. 快速复现预测从环境配置到GUI识别半小时跑通全流程把项目下载到本地后最快验证资源可用性的方式不是先看训练代码而是先把预测流程跑通。模型文件都是训练好的预测链路其实比训练链路短很多这一步能跑通后面改代码才谈得上。3.1 环境准备python版本与依赖匹配是第一个隐形门槛跑这个项目你至少需要Python 3.7以上的环境依赖项包括TensorFlow/Keras、PyQt5、NumPy、OpenCV。最常见的环境问题是直接装上最新版TensorFlow然后发现h5文件加载失败——这是历史包袱最重的一个坑。Python安装教程人人都会难在版本搭配上TensorFlow和Keras的版本兼容性直接决定项目能不能跑起来。如果你只是想先跑预测不需要装GPU版CPU版的TensorFlow完全够用。预测时单张图片在CPU上推理也不过几十毫秒到几百毫秒不影响体验。这里给一个推荐版本组合依赖包推荐版本说明Python3.8 或 3.9兼容性最稳的区间TensorFlow2.10 或 2.12CPU版即可预测不需要GPUPyQt55.15.x与Python 3.9兼容良好NumPy1.23 或 1.24配合TF 2.10/2.12不报错opencv-python4.8.x读取图片和预处理用注意TensorFlow 2.10之后的版本如果用到tf.keras.applications里的MobileNet可能因为API变更导致加载失败。这个项目里如果MobileNet是Keras内置应用类构建的2.10到2.12之间兼容性比较稳不建议直接用2.15以上的版本跑未微调的h5文件。安装完依赖后建议先跑一段最小验证代码确认TensorFlow能正常加载模型import tensorflow as tf print(tf.__version__) from tensorflow.keras.models import load_model m load_model(models/cnn_flower.h5) print(m.input_shape)这段代码如果正常输出模型输入shape说明环境基本没问题。如果这里报Unknown layer或无法恢复自定义对象说明模型里带自定义层需要用custom_objects参数加载。更稳妥的做法是先用纯Keras方式构建一个相同结构的模型再把权重load_weights进去但这是第五章要讲的排查思路这里先不展开。提前跑这段代码能帮你把环境问题和代码问题在五分钟内分开。3.2 mainwindow.py界面预测一条从点击到结果的前端链路mainwindow.py是项目的PyQt5界面入口。运行方式很直接python mainwindow.py看到窗口弹出后界面里一般有一个“上传图片”按钮和一个模型选择下拉框。你选择图片并预览后点击预测界面会调用加载好的h5模型进行前向推理把结果类别和置信度显示在界面上。这个交互流程很短但代码里涉及的前后端衔接值得拆开看。mainwindow.py的代码结构通常是这样组织的from PyQt5.QtWidgets import QMainWindow, QFileDialog, QLabel, QPushButton from tensorflow.keras.models import load_model class MainWindow(QMainWindow): def __init__(self): super().__init__() self.model load_model(models/cnn_flower.h5) self.btn_upload QPushButton(上传图片, self) self.label_result QLabel(识别结果, self) self.btn_upload.clicked.connect(self.upload_and_predict) def upload_and_predict(self): path, _ QFileDialog.getOpenFileName( self, 选择图片, images/, Image Files (*.jpg *.jpeg *.png)) if not path: return # 读取图片并预处理送入模型 result self.model.predict(preprocessed_img) # 将result映射为类别名更新label显示这段代码里的关键点在于上传流程。QFileDialog默认打开目录是images筛选后缀是jpg/jpeg/png。预测前需要对图片做与训练时一致的预处理常见包括resize到模型输入尺寸、像素归一化到0到1或-1到1、增加batch维度。很多新手直接喂原图或者忘记归一化结果预测概率全是乱的这一行是最容易翻车的地方。我在实际带项目时见过不下五次这类问题都出在预处理没有对标训练代码。3.3 命令行预测绕过GUI直接加载h5模型如果你只想快速试一张图不想启动整个GUI可以直接写一个几行的预测脚本这也是我拆任何模型资源时的第一步import numpy as np from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.image import load_img, img_to_array model load_model(models/cnn_flower.h5) # 打印输入尺寸确认预处理目标 print(input shape:, model.input_shape) img load_img(images/ccc.jpeg, target_size(model.input_shape[1], model.input_shape[2])) arr img_to_array(img) / 255.0 arr np.expand_dims(arr, axis0) # 增加batch维度 pred model.predict(arr) top_idx np.argmax(pred[0]) print(预测类别索引:, top_idx, 置信度:, pred[0][top_idx])这里用到的load_img指定了target_size会自动将图片resize到模型需要的尺寸img_to_array将PIL图像转成numpy数组除以255做归一化expand_dims后从(H,W,3)变成(1,H,W,3)。如果模型训练时用的是其他归一化方式比如ImageNet的mean/std归一化需要对照train_cnn.py里的ImageDataGenerator或预处理函数调整。我自己验证项目时习惯先跑这个最小脚本确认模型能出结果再打开GUI检查界面逻辑。这样可以把“模型问题”和“界面问题”分开排查不会出现窗口闪退却不知道是模型加载失败还是信号槽写错的情况。4. 深入训练逻辑train_cnn.py与train_mobilenet.py的完整改动指南预测跑通后下一步是把训练链路也吃透。train_cnn.py和train_mobilenet.py是项目里两个核心训练脚本代码量不大但每个环节都值得细看——因为你要换成自己的数据集时改动点就藏在这些细节里。很多学员到这一步才发现光会跑预测不算啥真正改数据训练才有价值。4.1 数据加载与预处理train_cnn.py里的关键代码train_cnn.py大致会包含数据加载、模型构建、编译和训练四个部分。数据加载一般会用到tf.keras.preprocessing.image的ImageDataGenerator或者是tf.data.Dataset具体看作者代码风格。常见做法是下面这个样子from tensorflow.keras.preprocessing.image import ImageDataGenerator datagen ImageDataGenerator( rescale1./255, validation_split0.2, rotation_range20, width_shift_range0.2, height_shift_range0.2, horizontal_flipTrue ) train_loader datagen.flow_from_directory( dataset/train, target_size(224, 224), batch_size32, subsettraining, class_modecategorical ) val_loader datagen.flow_from_directory( dataset/train, target_size(224, 224), batch_size32, subsetvalidation, class_modecategorical )这里的关键是validation_split和subset参数同一个目录被拆成训练和验证两个子集训练用training子集验证用validation子集。target_size决定模型输入尺寸batch_size决定每次迭代的样本数class_mode用categorical表示多分类的one-hot标签。如果你的数据集目录结构和flow_from_directory不一致改目录路径前最好先打印train_loader.class_indices确认类别映射否则训练出来的模型类别顺序会和你预期完全不同。模型构建部分一般是Sequential容器堆叠卷积、池化、Dropout和全连接层。末尾的Dense层数量和类别数对应激活函数一般用softmaxmodel tf.keras.Sequential([ tf.keras.layers.Conv2D(32, (3,3), activationrelu, input_shape(224,224,3)), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Conv2D(64, (3,3), activationrelu), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Conv2D(128, (3,3), activationrelu), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Flatten(), tf.keras.layers.Dropout(0.5), tf.keras.layers.Dense(128, activationrelu), tf.keras.layers.Dense(num_classes, activationsoftmax) ])Sequential里每个Conv2D的kernel size、filter数量和激活函数都是可调参数。Dropout(0.5)是防止过拟合的关键训练数据量小时尤其重要。最后一个Dense的units数量必须和你自己的数据集类别数一致。如果只是复现原项目这个结构不用动如果要换成自己的数据集只需要把num_classes改成实际类别数并确保数据目录下有对应的子文件夹。4.2 训练参数说明epochs、batch size与学习率怎么调训练代码里的核心参数主要集中在compile和fit两个调用上model.compile( optimizertf.keras.optimizers.Adam(learning_rate1e-3), losscategorical_crossentropy, metrics[accuracy] ) history model.fit( train_loader, validation_dataval_loader, epochs50, callbacks[tf.keras.callbacks.ReduceLROnPlateau(patience3)] )learning_rate设置为1e-3是Adam优化器的常用起点。如果训练中loss波动大把learning_rate降到5e-4或1e-4如果loss下降太慢可以短期用2e-3但不建议长期用。epochs的数值取决于数据量大小数据量在几千张时50个epoch基本够用数据量更大时可以设100。ReduceLROnPlateau回调的作用是验证集loss连续patience个epoch不再下降时自动降低学习率这是最省心的调参手段之一比自己手动盯着曲线改学习率高效得多。batch size设置直接影响内存或显存占用和梯度稳定性。显存不够时从32降到16但一般不建议低于8否则梯度过噪声会导致训练曲线抖动。CPU训练时batch size 32是性能与稳定性的平衡点。如果你是第一次跑这个项目建议保持原参数先完整跑一遍再根据自己的数据集规模做调整不要一上来就改多个参数否则出了问题很难定位是哪个改动引起的。4.3 训练结果如何解读results目录下的txt与曲线图对应训练结束时train_cnn.py一般会把输出保存到results目录。两个txt文件本质上是训练过程的重定向输出每一行代表一个epoch结束时的指标汇总格式大概是这样的Epoch 1/50 32/32 [] - 45s loss: 1.2837 - accuracy: 0.4818 - val_loss: 1.1072 - val_accuracy: 0.5214 Epoch 2/50 32/32 [] - 44s loss: 0.9671 - accuracy: 0.6180 - val_loss: 0.8914 - val_accuracy: 0.6711每一行包含训练集loss、训练集准确率、验证集loss和验证集准确率四项。理想状态是训练集和验证集准确率同步上升loss同步下降。如果你发现训练集准确率很高但验证集一直不动就说明过拟合了这是需要重点关注的现象。结果文件里两张曲线图是自动绘制的准确率和loss变化趋势读图有个小技巧看两条曲线之间的距离。距离越小越好差距越来越大说明过拟合正在加剧。如果看到loss曲线在后期反复震荡说明学习率偏大或batch size偏小回到4.2的调参建议调整即可。训练完成后把模型保存成h5文件就是models目录里那几个文件的操作model.save(models/cnn_flower.h5)保存时注意和load_model配合。如果保存的模型包含自定义层后续加载时需要传入custom_objects这是第五章的核心坑之一。h5格式本身不是万能保险箱它依赖的定义环境变了加载就可能出问题。5. 常见问题与排错排查这五个坑几乎每个复现的人都会踩跑训练和预测时问题集中在模型加载、图片预处理和训练收敛三块。我把最常见的五个问题按现象、原因、解决整理出来都是实测中踩过的不是网上抄来的。5.1 加载h5模型报错版本不匹配的三种现场现象一load_model时直接报错Unknown layer或者Unknown optimizer模型文件里出现了当前环境不认识的对象。原因模型是用某版本Keras定义的里面自定义了层或使用了新版本API而当前环境的TensorFlow版本过新或过旧双方对不上。这属于典型的版本玄学问题跟代码本身关系不大。解决先尝试用custom_objects指定自定义对象。如果不知道自定义层的类名可以在模型源码里搜“class”关键词找到层的定义。代码层面from tensorflow.keras.models import load_model from tensorflow.keras.utils import CustomObjectScope from tensorflow.keras.layers import Dense, Dropout with CustomObjectScope({Dense: Dense}): model load_model(models/cnn_flower.h5)如果最终确认是TensorFlow版本问题就把环境逐步降级测试优先试2.10或2.12。我见过最大的坑是环境从2.4一下升到2.16整个h5直接无法反序列化降到2.10就恢复了。现象二load_model成功但predict时输入尺寸报错。原因图片预处理尺寸和模型输入尺寸不一致。CNN模型的input_shape可能不是(224,224,3)而是(128,128,3)或其他尺寸。解决训练前打印model.input_shape确认target_size。预测代码里不要再猜直接用这个值去resize图片。现象三加载h5后模型可预测但结果准确率极低接近随机猜测。原因权重文件和模型结构不匹配或者归一化方式不一致。特别是用load_model加载时如果h5内部保存的模型结构和当前环境的默认结构有细微差异就会出现这种“能跑但不对”的情况。解决回到train_cnn.py里看训练时用的归一化和预处理步骤。ImageDataGenerator里的rescale1./255和直接在numpy里除以255等价但如果训练时用了preprocessing_function做其他处理预测时也要复制同样的逻辑。5.2 预测结果偏差大问题多半在图片预处理现象同一张图片训练集里的效果很好但自己从网上下载的图片测出来经常错。原因图片尺寸、通道顺序、归一化范围和背景噪声四方面都可能出问题。网上图片很多不是正方形直接resize会拉伸变形JPEG图可能有EXIF旋转相机拍的照片存在背景干扰。解决预测前统一做中心裁剪或resize保持宽高比给图片加白边填充成正方形减少形变对识别的影响。同时确认通道顺序是RGB还是BGR——如果你用OpenCV的cv2.imread读图得到的是BGR格式直接用会出问题。改成cv2.cvtColor(img, cv2.COLOR_BGR2RGB)转回来。import cv2 img cv2.imread(images/ccc.jpeg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_resized cv2.resize(img_rgb, (224, 224), interpolationcv2.INTER_LINEAR) img_norm img_resized.astype(float32) / 255.05.3 训练loss不降或过拟合从训练日志txt里找线索现象一训练了好几个epochloss几乎没变化准确率卡在某个数值附近不动。原因可能有三处——学习率设置过大导致loss震荡数据归一化没做好导致梯度不稳定类别分布不均匀某个类别样本特别多模型直接学偏了。解决先看results目录里上一次训练的txt前几个epoch的数据。如果loss在第一个epoch就跳到很高且后续不降把learning_rate调低一个数量级再试。如果loss能下降但准确率上不去检查数据集类别数量是否均衡。最直接的手段是给每个类做数量统计样本少的类别做数据增强或降采样。现象二训练集准确率越来越高接近100%但验证集准确率在某个epoch后开始下降。原因这是典型的过拟合信号。模型把训练集的特征死记硬背记住了但没学会泛化到新数据。解决建议采取两个选择一是减少训练轮数提前截断二是增加正则化强度。代码里Dropout从0.5提到0.6或0.7或在模型里增加L2正则化项。更实际的做法是结合results里的曲线图找那个拐点确定第一个best epoch用那个epoch的权重作为最终模型。现象三验证集准确率比训练集还高而且高得离谱。原因数据划分不够随机验证集里混入了和训练集高度相似的图片。比如同一株植物的不同角度照片一部分分到训练集一部分分到验证集这种泄漏会让验证集准确率虚高上线后立刻现原形。解决检查数据划分逻辑确认没有用同一图片的增强版本跨集出现。最稳妥的做法是按目录名划分数据集比如每个类别下划分子目录train/val/test而不是用随机split。5.4 MobileNet预训练权重加载失败现象train_mobilenet.py运行时下载预训练权重失败或者weights参数不识别直接抛异常。原因Keras内置的MobileNet在加载imagenet权重时需要网络下载网络不通时直接报错。另外weightsimagenet在部分TensorFlow版本里会使用不同的后端路径导致无法加载。解决先把权重下载到本地缓存目录再在代码中通过weights参数指向本地文件或者将include_topFalse自行搭建分类头。如果运行环境无法访问外网下载提前把权重文件放入~/.keras/models目录是最好的后悔药。5.5 GUI运行报错PyQt5界面无响应或控件不生效现象运行mainwindow.py没有任何报错但窗口空白或点击上传图片没反应。原因最常见是PyQt5界面代码中控件名不一致或信号槽的connect写错了对象。也有可能是加载模型耗时过长界面主线程阻塞导致看起来卡死。解决将模型加载尽可能放在窗口初始化时并使用两步加载策略——先在后台线程完成加载再更新界面状态。检查button.clicked.connect指定的绑定函数是否存在用print打印必要的调试信息定位self.btn_upload.clicked.connect(self.upload_and_predict) print(button connected)窗口卡死的另一个来源是predict时阻塞主线程尤其加载的是MobileNet模型且CPU较弱时推理会看到明显的界面冻结。这种情况把predict放到QThread里执行是正解。6. 进阶验证微调MobileNet模型并用testmodel.py对比验证集差异前面把CNN和MobileNet的训练流程都讲完了最后来做件更贴近实际使用的事情用迁移学习微调MobileNet再把两组模型在验证集上的表现做一个横向对比。资源里的testmodel.py正好就是为这个目标服务的。6.1 微调思路只替换分类层并冻结主干对于train_mobilenet.py如果你要把模型调整到自己的数据上最常见的方式是冻结MobileNet主干并替换顶层。典型实现from tensorflow.keras.applications import MobileNet from tensorflow.keras.models import Model from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout bottleneck MobileNet(weightsimagenet, include_topFalse, input_shape(224,224,3), poolingavg) for layer in bottleneck.layers: layer.trainable False x Dense(128, activationrelu)(bottleneck.output) x Dropout(0.5)(x) output Dense(num_classes, activationsoftmax)(x) model Model(inputsbottleneck.input, outputsoutput)冻结主干层的意图在于保留ImageNet学到的通用特征比如边缘、纹理、形状只训练新加的分类层去适配花朵数据。数据量较小时这种做法最稳。训练若干epoch后可以再解冻最后几层做细调此时学习率要降到1e-4或更低。先冻结后解冻的顺序很重要一上来就让主干和分类头一起更新数据量不够时预训练权重的特征很容易被破坏。6.2 testmodel.py输出的两组数字说明了什么跑testmodel.py时脚本会分别加载cnn和mobilenet对应的h5文件在验证集上计算准确率并输出对比结果。你可能会看到mobilenet版本在验证集上反超cnn版本也可能看到cnn版本在小数据集上反而更稳。无论哪个结果关键在于你能否解释这两组数字背后的原因——是数据量差异还是模型容量差异还是预处理尺寸不同造成的。验证集准确率只能说明模型在这个固定测试集上的表现不能代表真实场景的全部情况。通过改变测试集图片的来源比如在images测试集里加入不同背景的图片你可以看到模型泛化能力的真实边界。如果能在自己的数据集上把训练、验证、测试分好再跑一遍testmodel.py既是对这份资源的消化也是实践上的判断依据——看模型在不同的测试条件下是否稳定。我自己的习惯是下载任何模型资源后先测试模型能否加载、预测一张图然后立刻用自己的数据跑一遍testmodel.py并把txt结果存档标注日期和模型版本。这样之后模型做任何改动都能回看到“这么改是否正确”。从那以后每次复现类似项目我都要完整走一遍加载模型→单图预测→训练日志对比→testmodel验证。这套流程会帮你省掉大量“跑完不知道效果有没有提升”的困惑。希望帮到你。本文还有配套的精品资源点击获取
返回列表