尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于PyQt5与深度学习的舌苔识别系统开发实践

基于PyQt5与深度学习的舌苔识别系统开发实践 简介在计算机视觉领域图像分类是基础而核心的任务借助卷积神经网络CNN能够自动提取颜色、纹理等层次化特征。针对医学图像样本少、标注成本高的痛点迁移学习通过预训练模型微调有效缓解了过拟合。PyQt5作为成熟的桌面GUI框架可在本地搭建交互友好、响应流畅的应用界面。从中医数字化诊断的应用场景出发舌苔识别系统利用深度学习模型对舌部图像进行客观分类并通过PyQt5完成数据导入、推理展示与历史记录等全链路流程为临床辅助决策提供了可行原型。围绕系统设计、数据增强、模型训练与界面开发的关键环节分享从毕设项目到工程实践的完整经验。 答辩结束那天晚上我翻着电脑里这个项目从零到一的全部过程——乱糟糟的代码版本、二十多次模型训练的日志、以及最终跑起来的PyQt5桌面应用——突然觉得这段经历很值得写下来。起因其实很简单毕设选题清单里视觉方向的题目就那么几个目标检测烂大街人脸识别对我这种没GPU资源的学生来说门槛不低而我对中医数字化诊断这个方向一直有点兴趣。最后我选了“基于PyQt5的深度学习舌苔识别系统”一个把CNN图像分类和桌面应用结合起来的小项目。这篇博文写给正在选毕设题目的同学、想快速上手PyQt5做桌面应用的开发者以及准备做类似医学图像分类项目的朋友我会把从选题、数据、模型、界面到答辩的全部细节和踩坑经历摊开讲。1. 这个毕设到底在做什么选题动机与系统边界1.1 视觉项目那么多为什么选了舌苔识别先说选题逻辑。毕设题目难度要适中太简单答辩时没东西讲太难自己扛不住。舌苔识别这个方向有几个天然优势第一它是标准的图像分类问题深度学习CNN直接对口第二中医舌诊在临床研究里一直有数字化需求算是有应用价值第三PyQt5做桌面客户端正好补足“算法应用”的完整链路是老师喜欢看到的完整系统。舌诊的医学背景大致是这样舌头是人体健康状况的一个窗口舌质和舌苔的变化与脏腑功能密切相关。传统中医通过观察舌色、舌形、苔色、苔质来判断病情但这依赖医生的主观经验不同医生看同一个舌头可能得出不同结论。用计算机视觉做舌苔识别本质是把这种人工经验转化为可量化的客观特征这就是项目的核心价值所在。我当时给自己定的目标是做一个能运行的桌面应用用户上传舌部照片系统自动判断舌苔类别并给出置信度同时保存历史记录。这个目标不大但涉及GUI开发、图像处理、深度学习模型训练、数据持久化整个闭环做下来已经够一个毕设的分量。1.2 任务定义分类为主检测作为延伸舌苔识别严格来说有两种做法目标检测和图像分类。目标检测需要在舌头区域画边界框工作量更大需要标注框数据图像分类则假定输入图片已经是裁剪好的舌头区域只需要判断整张图属于哪一类。我最终选择的是图像分类原因很实际舌苔公开数据集极少自己采集和标注边界框成本太高。分类任务对数据标注的要求低很多按文件夹归类就行。而且对于毕设来说分类结果的展示和解释更直观——上传图片、点击识别、输出“黄厚腻苔 置信度91.2%”这个流程比画框更贴近普通用户的使用习惯。分类的类别设置也有讲究。舌苔在中医里有苔色白、黄、灰黑、苔质薄、厚、腻、腐、剥等维度如果一次性做十几类每类的样本量会被摊薄模型根本学不好。我当时压缩到5类白薄苔、白厚腻苔、黄薄苔、黄厚腻苔、剥苔这五类在中医里代表不同的身体状态区分度也比较清晰。1.3 系统功能清单和技术指标这套系统最终要交付的东西很明确我从一开始就列了一张功能清单用户登录和注册用SQLite存用户表虽然简单但毕设功能列表里好看图片导入支持jpg、png、bmp格式通过QFileDialog选择文件舌苔识别加载训练好的CNN模型对图片进行预处理并输出分类结果展示显示类别、置信度、推理耗时并把识别结果保存历史记录按时间倒序展示所有识别记录支持清空和删除性能指标上我给自己定的及格线是单张图片推理时间不超过2秒CPU环境五分类准确率不低于85%。这个指标不算高但考虑到舌苔图片本身存在光照、角度等干扰85%已经能说明模型学到了一些有效特征。说实话如果数据量不足这个指标还需要往下调。2. 技术选型推演为什么是PyQt5CNN这套组合2.1 界面层PyQt5 vs Web前后端 vs Tkinter技术选型是很多同学最纠结的部分网上资料又杂又乱。我说说我的思考过程。毕设界面层有三个主流选择PyQt5、Tkinter、Web前端FlaskVue或者纯Flask页面。Tkinter是Python自带的GUI库学起来简单但界面风格停留在Windows 98时代做不出像样的视觉效果。用Web前端做界面交互体验确实现代但相当于写了一个Web应用还需要处理浏览器端和Python后端的通信开发链路更长。PyQt5正好处在中间位置——它是Qt框架的Python绑定控件丰富、界面美观、和OpenCV/深度学习库的配合很丝滑而且信号槽机制写事件处理非常顺手。我之前用过一段时间的PyQt5对这个库的脾气比较熟所以选它没有犹豫。如果你完全没接触过PyQt5也不要慌这个库的写法非常套路化创建QWidget/QMainWindow往上面放控件连接信号槽写业务逻辑整个流程一周就能上手。2.2 模型层自建CNN和迁移学习的取舍深度学习模型的选择是另一个关键决策。我当时考虑过三条路从零训练一个自定义CNN、用预训练模型做迁移学习、直接调用现成API比如阿里云或百度的图像识别接口。用现成API最省事但毕设答辩时老师让你打开代码讲原理你直接傻眼而且舌苔属于医学图像普通API对这类垂直领域的分类效果大概率还不如自己训的模型。我的方案是双轨并行先用自建CNN跑通完整流程再用ResNet18做迁移学习提高精度。自建CNN的好处是结构完全可控每一层的作用都能讲清楚应对答辩“这个网络为什么这么设计”这种问题时特别有优势。ResNet18的优势则是特征提取能力强收敛更快最终效果上限更高。具体的自建CNN结构我后面会展开这里先给结论输入224x224的RGB图片经过三组“卷积BatchNormReLU最大池化”的特征提取然后展平接全连接层和Softmax分类器。2.3 环境配置版本组合与安装顺序PyQt5的环境问题说大不大说小不小网上很多人在这上面卡了一整天才装好。我用的环境是Python 3.9 PyQt5 5.15.9 PyTorch 1.13CPU版这套组合运行稳定。安装顺序比较推荐先装PyTorch再装PyQt5。这里说一个经验PyQt5安装最怕的是和sip版本冲突。如果你执行pip install pyqt5之后导入PyQt5时提示sip相关错误解决方法很简单先卸载再重装pip uninstall pyqt5 pyqt5-sip pip install pyqt55.15.9 pyqt5-sip12.11.0不要直接装最新版PyQt5 6.x除非你愿意忍受和教材教程完全不兼容的API差异。我就是用5.15版本省去了很多不必要的麻烦后面排错章节会单独讲这部分坑。3. 数据集准备舌苔图片的采集、清洗与增强3.1 数据从哪来公开数据集与自采的组合方案数据集是所有医学图像项目最大的痛真实舌苔数据不是你想找就能找到的。我最终的数据来源有三个网上能搜到的零散舌象图片、开源医学影像平台上的少量舌象样本、以及一些中医书籍电子版里扫描的舌象图。虽然这些数据很零散但整理下来凑了600多张每类100多张勉强能支撑一个简单的分类实验。如果镜像量再大一些还可以考虑从医学图像竞赛平台找相关数据集国内外的中文舌诊研究其实有少数学者开源过部分数据。重点提醒一下数据来源一定要在论文里写清楚注明出处和版权说明避免学术不端的麻烦。数据清洗这一步非常关键。我过了一遍所有图片后把三类不合格的图片踢掉了光线过暗导致舌色完全失真的、舌体被遮挡超过三分之一无法判断苔质的、清晰度太低连肉眼都看不了的。清洗后实际用于训练的有效图片大约520张说句实话这个量偏少了所以后面数据增强成了抢救模型的必要手段。3.2 预处理关键操作去光照干扰与统一尺寸舌苔识别的核心特征包括颜色和纹理。苔色判断依赖颜色苔质判断依赖纹理细节因此预处理要尽量保留这两类信息同时消除光照、角度、阴影等噪声干扰。我的预处理流程分四步。第一步把所有图片统一缩放到224x224不管原图是多大这个尺寸是输入模型的标准尺寸也兼顾了CPU推理速度。第二步做光照归一化用OpenCV的直方图均衡化把舌体区域的亮度分布拉回正常范围这样不同环境光线下的照片在颜色上更具可比性。第三步对图片做轻微的锐化让苔质的纹理细节更清晰帮助模型区分厚苔和薄苔。第四步标准化到模型需要的格式也就是转换为浮点数张量并按ImageNet的均值方差归一化。完整处理函数可以参考这个框架import cv2 import numpy as np def preprocess_image(image_path): img cv2.imread(image_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (224, 224)) # 光照归一化 img cv2.createCLAHE(clipLimit2.0, tileGridSize(8, 8)).apply(cv2.cvtColor(img, cv2.COLOR_RGB2LAB))[:, :, 0] # 锐化 kernel np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]) img cv2.filter2D(img, -1, kernel) return img / 255.0这一步的效果在实验对比里也很明确不做光照归一化时低光照图片的预测结果分布非常随机做了之后同样的图片在大多数轮次里能稳定输出正确类别。3.3 数据增强策略针对颜色敏感任务的控制数据增强是力挽狂澜的一步。因为只有500多张原始图片如果不做增强自建CNN大概率严重过拟合——训练集准确率99%验证集准确率60%这种戏剧性的差距老师一眼就能看出来。做增强要注意一个矛盾舌苔分类对颜色极其敏感因此幅度过大的颜色抖动会直接把样本变成另一个类别。比如“黄厚腻苔”这个类别的图像如果把色相往绿色偏移模型很可能会学到错误的颜色关联。我的增强组合是随机水平翻转、-10度到10度随机旋转、10%以内的亮度调整、2%以内的饱和度调整、随机裁剪一定的比例后再缩放回224x224。综合应用后相当于每张原图扩展出了多种不同角度的变形模型见过的样本形态从五百多张变成了五千多张。用PyTorch的transforms库实现代码很简洁from torchvision import transforms train_transform transforms.Compose([ transforms.RandomHorizontalFlip(p0.5), transforms.RandomRotation(10), transforms.ColorJitter(brightness0.1, saturation0.02), transforms.RandomResizedCrop(224, scale(0.85, 1.0)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])这里特别强调一点val和test集的变换不要包含Random翻转、Random裁剪这类随机操作只需要Resize、ToTensor和Normalize确保验证时的输入是可复现的。4. 模型训练过程从基线CNN到ResNet微调4.1 第一版模型自建CNN的完整结构自建CNN的意义在于让你彻底理解一个神经网络是怎么从输入图片一步步提取特征并输出类别概率的。这个理解在答辩中非常重要因为老师一定会问“你的网络为什么这样设计”。我的基线网络结构如下输入3x224x224的RGB图像第一层卷积Conv2d(3, 16, kernel_size3, padding1)接BatchNorm2d(16)和ReLU然后最大池化输出变为16x112x112第二层卷积Conv2d(16, 32, kernel_size3, padding1)接BatchNorm2d(32)和ReLU然后最大池化输出变为32x56x56第三层卷积Conv2d(32, 64, kernel_size3, padding1)接BatchNorm2d(64)和ReLU然后最大池化输出变为64x28x28展开为64282850176维向量通过全连接层映射到128维Dropout(0.5)减少过拟合最后全连接映射到5个类别第一层卷积负责提取边缘、纹理等低级特征后面各层逐步组合出对类别有区分力的高级语义特征。最大池化的作用是下采样和增大感受野同时让模型对位置不敏感。BatchNorm的作用则是稳定训练过程、加速收敛尤其是小数据集上效果明显。虽然这个基线网络不算深但对五分类任务来说已经在及格线附近训练50轮能到75%左右的测试准确率。它会作为之后迁移学习的对照组用来证明微调后的模型性能提升。4.2 迁移学习ResNet18的接入方式当基线模型准确率停在75%上不去时我决定切到迁移学习。选择ResNet18的原因是它最小、速度最快、对CPU推理友好而且残差结构能有效解决深层网络梯度消失问题在小数据集上也能稳定收敛。迁移学习的接入方式很简单PyTorch官方早就集成好了import torchvision.models as models model models.resnet18(pretrainedTrue) num_features model.fc.in_features model.fc nn.Linear(num_features, 5)关键在于微调策略需要决定只训练最后一层分类头还是微调全部参数。我的实测结果是只冻结Backbone训练最后的全连接层虽然训练飞快但模型只学到ImageNet特征和舌苔类别之间的简单映射准确率约80%提升有限。全部参数微调初始学习率用0.0001训练20轮后准确率能爬到86%以上效果明显更好。需要注意的是迁移学习的输入归一化必须使用预训练模型对应的均值方差也就是[0.485, 0.456, 0.406]和[0.229, 0.224, 0.225]。如果忘了归一化模型的表现会莫名其妙地差。这个坑我后来排查了很久才找到属于典型的“看起来没错但就是不准”的隐藏错误。4.3 训练参数、评估指标与过拟合排查训练参数我最终确定为优化器AdamWweight_decay设0.0001防止过拟合学习率0.0001batch_size为16训练轮数30轮损失函数CrossEntropyLoss。学习率策略用的是ReduceLROnPlateau验证集loss连续3个epoch不下降时学习率减半。评估指标不能只看准确率还要看每个类别的精确率、召回率和F1值。尤其是样本不均衡时比如“剥苔”类图片很少即使模型把所有样本都预测为“白薄苔”整体准确率也可能不低但这个模型实际是废的。我在测试集打印classification_report之后才发现了这个问题然后通过给稀缺类别在损失函数里加类别权重来处理。过拟合的判断标准也分享一个实用方法训练过程中记录每轮的训练loss和验证loss。如果训练loss持续下降、验证loss先降后升这就是典型的过拟合信号模型开始“背诵”训练样本。这时候优先减少模型复杂度或增强正则化而不是急着加数据。整套训练日志我用TensorBoard保存每一轮的准确率、loss曲线、混淆矩阵都清清楚楚。这些图表在论文和答辩PPT里直接就能用一下子就把整个实验过程的工作量拉满了。5. PyQt5客户端开发界面到推理的完整链路5.1 主窗口布局与QSS美化界面设计上我放弃了花哨的皮肤引擎直接用QSSQt样式表实现了一套简洁的医学风格界面白灰配色加一个深绿色主题按钮看起来不会显得太学生气。整体布局采用左右分栏左侧是图片选择与展示区域右侧是识别结果和历史记录区域。主窗口基于QMainWindow搭建控件分工如下中间的QSplitter分割左右两个QWidget左半部分放QPushButton“打开图片”和一个QLabel用于显示图片右半部分放一个QGroupBox展示识别结果里面是类别标签、置信度、推理耗时的QLabel下方再放一个QListWidget展示历史记录。顶部菜单栏加一个“退出”Action底部QStatusBar显示“模型加载成功”等状态信息。QSS美化只需要给主窗口和关键控件设置样式例如设置按钮背景色和悬停颜色QLabel字体大小QListWidget的边框圆角等。整体代码量不大却能极大提升观感。毕设答辩时第一眼界面好看是有隐性加分的。5.2 图像导入与格式转换的细节PyQt5和OpenCV的图像格式互相转换是初学者最容易踩坑的点。QFileDialog选中的图片路径是字符串你要先用cv2.imread读成OpenCV格式之后又要把OpenCV格式转成QImage才能显示在QLabel上。这个转换有个很容易犯的错误OpenCV默认读进来的是BGR通道顺序而QImage显示时按RGB理解如果直接转显示的图片颜色就会偏蓝偏红舌苔颜色一错这个系统就完全失去了诊断意义。正确做法是先用cv2.cvtColor转换通道再构造QImagergb_image cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) h, w, ch rgb_image.shape bytes_per_line ch * w qimage QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888)这里还有一个隐蔽的坑QImage构造时的bytesPerLine参数必须填ch * w如果省略或填错图片在显示时会出现奇怪的拉伸错位。因为QImage需要知道每一行像素占多少字节默认值对连续内存的ndarray通常没问题但经过某些resize裁剪操作后数据步长可能不同会导致画面撕裂。同样的道理也适用于预处理后的图像矩阵经过torchvision的ToTensor转成CHW后你要通过permute转回HWC再转QImage显示。5.3 QThread异步推理避免界面卡死如果你的系统跑推理时界面直接变成“未响应”状态等几秒才弹出来结果那就是典型的同步阻塞问题。推理是在主线程执行而主线程同时还要负责窗口重绘和事件响应。我把模型推理放到QThread子线程后界面立刻恢复流畅用户体验完全不是一个档次。具体做法是写一个继承QThread的推理线程类通过信号把结果传回主线程from PyQt5.QtCore import QThread, pyqtSignal class InferThread(QThread): finish_signal pyqtSignal(dict) def __init__(self, model, image): super().__init__() self.model model self.image image def run(self): label, confidence, cost single_predict(self.model, self.image) self.finish_signal.emit({ label: label, confidence: confidence, time: cost })在主界面里点击“开始识别”按钮时先禁用按钮防止重复点击然后创建并启动线程线程结束的信号会触发一个槽函数来更新界面并恢复按钮状态。如果模型一直挂在内存里CPU推理一次大约0.3到0.8秒UI完全保持流畅。GPU版推理更快几十毫秒就能完成不过CPU版已经满足2秒的指标要求了。5.4 SQLite历史记录与报表导出历史记录模块我用SQLite实现代码量不大但功能完整。数据库文件放在程序主目录下首次运行自动建表。表结构如下CREATE TABLE IF NOT EXISTS history ( id INTEGER PRIMARY KEY AUTOINCREMENT, image_path TEXT, result TEXT, confidence REAL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );每次识别完成后把图片路径、识别类别、置信度、当前时间插入到表里。主界面右侧的QListWidget每次启动时从数据库读取最近20条记录展示用户双击某条记录可以重新查看当天识别的图片。另外还加了一个“导出报告”按钮把所有历史记录写入csv文件用Excel直接打开这对毕设验收演示很有用——你可以现场演示一批图片的识别结果再展示导出的报告表格。6. 联调排错实录四类高频坑与排查思路6.1 模型权重路径与打包路径问题这个坑几乎每个做PyQt5深度学习的同学都会遇到开发环境里代码运行正常但用PyInstaller打包成exe后程序点击识别直接崩溃错误提示找不到模型文件。原因很简单——打包后当前工作目录变化了程序还在用相对路径找模型权重。后来我用的是PyInstaller的sys._MEIPASS机制处理资源路径。打包后的exe运行时外部资源文件会被解压到一个临时目录你需要判断程序是否处于打包状态如果是就切换到临时目录找资源import sys, os def resource_path(relative_path): if hasattr(sys, _MEIPASS): base_path sys._MEIPASS else: base_path os.path.abspath(.) return os.path.join(base_path, relative_path) model_path resource_path(models/best_model.pth)这里再提醒一个实践建议模型文件动辄几十MB甚至上百MB不建议打进exe包应该在首次启动时让用户指定模型文件路径或者把模型放在exe同级的models目录下。这样打包出来的程序体积小模型也方便更新。6.2 OpenCV、PyQt5、模型输入的格式不统一三种格式混在一起真的会让人头皮发麻。OpenCV读取的图像是BGR顺序的numpy数组PyTorch模型要求的输入是CHW顺序、归一化到0到1的RGB张量PyQt5显示时又要转成QImage的RGB格式。牵一发动全身一个环节错了结果可能表现为颜色混乱、识别准确率暴跌或者直接报维度错误。我把格式转换流程做成一个固定的pipeline每次开发新功能都走这条流程cv2读取BGR - 转为RGB - 转为CHW张量 - Normalize - 模型推理 - 输出类别。任何需要显示原始图片的地方都从最开始的RGB数据构造QImage不要从CHW张量再转回来多绕一步。模型加载时也要注意model.eval()必须在推理前调用。有一次我忘了设置eval模式结果模型保留训练时的Dropout随机性同一张图片每次预测结果都不一样。这个问题特别隐蔽因为代码不会报错只有当你拿同一张图测两次发现结果不同时才能想到。6.3 PyQt5不同版本API差异PyQt5和PyQt6的差异按说应该在开始时避免但网上很多教程的代码是不同版本混着写的照抄很容易出问题。例如PyQt5里QDesktopWidget在PyQt6已经被移除按钮点击信号在PyQt5里是button.clicked.connect()在PyQt6里QAction的位置和构造方式也变了。这些改动虽然不大但一报错就会浪费大量时间。我建议锁定PyQt5 5.15系列版本。装完后验证一下python -c from PyQt5.QtCore import QT_VERSION_STR; print(QT_VERSION_STR)如果输出的Qt版本是5.x基本就没问题了。还有PyQt5的sip版本问题和Qt插件丢失问题后者多出现在重装后官方库路径没刷新。这类环境问题在开发机上的解法比较粗暴创建一个干净的虚拟环境重新安装所有依赖能解决85%莫名其妙的问题。6.4 模型推理耗时与内存占用不规范CPU推理虽然满足2秒指标但一开始因为模型输入尺寸和线程管理没做对推理耗时会飘到3秒以上。后来排查出两个原因一是每次推理都重新加载模型权重白白浪费了I/O时间二是预处理部分为了偷懒把图像保持原尺寸输入模型大图直接拖慢了卷积计算。解决方案是模型常驻内存只加载一次图片统一缩放到224x224。另一个内存问题出现在多次推理后内存占用不断上升原因是QImage和numpy数组在转换过程中没有及时释放。这种问题用del和gc.collect能缓解但关键是不要在循环里反复创建临时副本尽量复用同一个numpy数组。我还对模型做了推理速度的基准测试自建CNN在CPU上大约0.2秒ResNet18大约0.45秒都在可接受范围内。如果还想更快可以用torch的quantization做INT8量化速度能再提升一倍但准确率会有轻微下降这个取舍要看项目需求。7. 从代码到论文毕设文档的编排与答辩准备7.1 功能性图表的制作建议毕设论文里图表是老师最先看的内容之一也是最容易拉开差距的地方。按我的经验必须准备的图包括系统总体架构图、系统功能模块图、程序流程图、数据库ER图、模型网络结构图、训练过程中的loss和准确率曲线图、测试集混淆矩阵图。这些图不用画得多精美但要清晰、规范、逻辑自洽。绘图工具我用的是draw.io免费且在线就能用架构图和流程图都能快速上手。网络结构图可以用PyTorch官方工具库Torchviz画出模型的计算图把它作为论文里的网络结构图非常专业。混淆矩阵直接通过sklearn的confusion_matrix计算再用matplotlib画热力图。所有图表在论文里的边缘要留白统一字体和配色整体观感会非常加分。7.2 实验对比表格的呈现方式实验部分论文的“含金量”主要通过对比表格来体现我建了一张总表横向列出所有实验方案包括自建CNN基线、ResNet18冻结Backbone微调、ResNet18全参数微调、带数据增强与不带数据增强的对比。纵向记录每个方案的准确率、宏平均F1值、模型参数量、单张推理耗时。这张表能让答辩老师快速看到你对实验设计的系统性思考。每张表旁边记得配一段文字分析比如“为什么全参数微调明显好于冻结Backbone”“数据增强对小样本任务的关键作用”。不要只罗列数据分析才是展示能力的部分。另外各个类别的分类效果差异也很值得写比如“白厚腻苔”和“黄厚腻苔”之间容易混淆因为两者在纹理上接近主要区别体现在颜色上这能说明硬件和光照条件对系统的影响。7.3 答辩常被追问的几个问题答辩前我把老师可能问到的问题列了一个清单现场基本没有超出这个范围的。高频问题大概是这几个第一“为什么用分类而不是目标检测”回答思路分类任务已经满足系统的核心需求且标注成本低检测可以作为后续扩展方向用YOLO定位舌体再切分到分类模型形成一个两阶段系统。第二“数据量这么小模型泛化能力能保证吗”回答思路承认数据量确实是局限但同时说明已经使用迁移学习、数据增强、严格的数据清洗和交叉验证来缓解这个问题未来的方向是扩展更大规模的临床数据集。第三“你的系统在真实临床场景能用吗”回答思路这是一个研究原型能为中医舌诊的客观量化提供辅助参考但距离临床落地还有距离需要更大规模的数据验证和医生的专业标注参与。顺着这条线说老师会觉得你有边界意识不是乱吹功能。第四“为什么选ResNet18而不是更深网络”回答思路数据量有限深层网络容易过拟合CPU部署上ResNet18的推理速度和内存占用更友好ResNet18的精度已满足项目指标要求。第五“有哪些指标可以优化”回答思路优化光照校正算法、增加舌体分割预处理、更大规模数据下的多标签分类、模型轻量化部署、加入摄像头实时检测能力这些都能体现你的思考深度。除此之外答辩现场还有一个特别实用的技巧准备一段3分钟以内的现场演示脚本从打开软件、选择图片、点击识别、展示结果到查看历史记录一气呵成。演示时一旦出错不要说太多废话去圆直接说明这是因为环境问题然后在PPT里准备好结果截图作为补充。我现场演示时就遇到过一次模型加载缓慢的情况等了将近两秒我顺势讲解了一下模型加载机制把尴尬转化为展示内容。最后再分享一个我做毕设最大的体会这类项目最忌一开始就想把功能做全一定要走通最小闭环再逐步优化。第一周哪怕只用命令行跑通一次训练和预测整个项目就有了确定性接下来再叠GUI、叠历史记录、叠打包发布每一步都是在前一步的稳定基础上往前走。先让“图片进、结果出”这条主线动起来后面的一切都顺了。本文还有配套的精品资源点击获取
返回列表