简介:面向计算机、人工智能等专业课程设计与毕业设计场景,这套资料包提供了一整套深度学习舌苔检测系统。项目以Python实现,包含可运行的检测脚本、模型权重与训练日志,能够帮助学习者理解图像识别任务从数据准备、模型训练到结果评估的完整流程;同时附带开题报告和论文文档,适合直接作为毕设课题参考或在此基础上二次开发。
资源压缩包共110个文件,总大小约105.46MB。主要文件类型包括26个Python源码、6个.pth权重文件、7张样本图片、2个Word文档以及TensorBoard events训练日志等;权重文件和日志可用于复现训练、观察loss变化,docx文档则对口开题和论文写作,目录划分直观,便于按需查找。
目前已有71人学习下载。除核心检测代码外,资源还包含界面UI文件、标注/配置JSON等辅助材料,方便从界面展示、数据处理到模型推理多个层面进行调试。对于入门深度学习的同学,可以作为完整项目范例逐步拆解学习;对有基础的同学,也能快速替换数据或调整网络结构,迁移到其他医学图像检测场景。
1. 深度学习舌苔检测系统:毕设课设的完整工程,不是一份能跑的代码那么简单
每年一到毕设季,后台私信问得最多的就是“有没有一个能跑通的深度学习项目”,尤其像舌苔检测这种自带中医交叉属性的课题,听着有亮点,做起来却最容易翻车。很多人卡在同一个地方:数据不会标、环境装不上、论文没素材。这份深度学习舌苔检测系统资源,把代码、开题报告和论文三件套一起打包了,你拿到的不是一个孤零零的模型文件,而是一整套能直接复现、能写进毕设材料里的工程闭环。适合三类人:做深度学习课程设计或毕业设计的本科生,想快速补齐实验数据的在职读研党,以及想参考目标检测工程结构的中医信息化方向开发者。第一章先把话说明白:这资源解决的核心问题不是“教你什么是深度学习”,而是“让你在两周内把舌苔检测实验跑通,并且有素材写论文”。
2. 系统拆解与选型逻辑:为什么舌苔检测必须走目标检测路线,而不是单纯分类
拿到任何毕设级别的深度学习资源,我习惯第一步不是跑代码,而是先拆工程结构、核对技术选型。这套系统从课题定位上就不是“图像分类”而是“目标检测”,因为舌苔检测的实际需求是框出舌苔区域并且判断状态,单纯给整张舌图打一个标签写不了定位结论、也画不了可视化的框。你在答辩时最有利的证据就是一张标注好检测框的舌象图,这恰恰是分类模型给不了的效果。
2.1 任务定性与模型选型:检测框架为什么更适合这个课题
舌苔检测从任务本身看,输入是一张舌象照片,输出是“舌苔区域在图片哪个位置 + 这个区域属于哪一类”。细分下来有两种主流做法:一种是两阶段检测器,像 Faster R-CNN,先由区域提议网络找出候选框再逐框分类,精度高但训练和推理都比较慢;另一种是单阶段检测器,像 YOLO 系列,直接在特征图上回归边框和类别,速度快,结构也更简单直观,特别适合本科课设这种时间紧、算力有限、需要快速出图的场景。
常见的深度学习课程设计资源里,绝大多数目标检测系统都采用 YOLO 系框架。原因很现实:一是生态成熟,网上能搜到的踩坑经验多,数据集格式、训练参数调整、loss 曲线异常排查都有前人记录;二是模型结构相对透明,论文里画网络结构图、写特征提取流程都比较容易;三是显存占用可控,一张普通显卡就能跑起来,不用非去租服务器。当然,如果你的课题指导老师对两阶段检测有执念,工程内换成 Faster R-CNN 也合理,但时间紧的情况下我不建议在选型上过度纠结。
这套系统的整体流程是一条完整的检测流水线:输入舌象图片,经过数据处理进入卷积骨干网络提取特征,再通过检测头输出候选框坐标、置信度和类别概率,最后用非极大值抑制去掉重复框。你拿到压缩包解压后,大概率会看到训练脚本、检测脚本、模型定义目录、数据目录和配置文件这几个部分。先别急着双击训练,建议按接下来的顺序,把环境、数据、训练、推理四步走完。
2.2 环境搭建与依赖确认:CPU也能跑,但GPU才是正常体验
深度学习项目百分之八十的初筛报错都出在环境上。舌苔检测这种影像类任务,依赖核心就四个:Python 解释器、PyTorch 深度学习框架、OpenCV 图像处理库,以及 NumPy 等科学计算基础库。建议用 conda 建一个独立环境,避免把系统 Python 搞乱,也方便以后删了重建。
conda create -n tongue_det python=3.9 -y conda activate tongue_det pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install opencv-python numpy pandas matplotlib pyyaml tqdm代码的逻辑很简单:第一条命令创建 conda 环境并指定 Python 3.9,第二条激活它,第三条安装带 CUDA 11.8 编译版本的 PyTorch 和配套的 torchvision,第四条补上图像处理、数值计算和训练过程可视化需要的库。这里有个关键参数是--index-url,它告诉 pip 去 PyTorch 官方源下载对应 CUDA 版本的包,如果你直接用pip install torch,装到的是 CPU 版本,训练速度会慢到怀疑人生。
装完之后别急着跑训练,先执行一条验证命令:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"torch.cuda.is_available()返回True说明 GPU 可用,返回False也不是世界末日,项目照样能跑 CPU 推理,只是训练一个完整模型可能需要几小时甚至更久。我一般建议至少看一眼机器显卡显存:4GB 显存可以跑小 batch 训练,2GB 显存只建议做推理验证,训练规模就得大幅压缩。
提示:如果你用的是 Apple Silicon 芯片的 Mac,安装命令换成
pip install torch torchvision,PyTorch 会默认走 MPS 后端,某些环节反而比入门级 NVIDIA 显卡更平稳。
存储和日志的组织在毕设里也很重要。我在环境配好后会习惯性创建一个项目目录骨架,把训练日志、权重文件、标注数据和原图分开,后面做论文实验数据统计会省很多事。这个习惯在执行实验时能让你少走弯路:当答辩老师问“你这个实验跑了几组、精度波动多少”时,你随手就能调出训练回忆录,而不是翻聊天记录回忆参数。
3. 数据集与预处理:舌苔图片标注格式与数据增强的三个规矩
数据是舌苔检测项目里最容易被低估的一环。很多人以为下载一份现成数据集就能开工,真正跑起来才发现格式对不上、类别比例失衡、图片尺寸不统一,训练出来的模型精度离谱,最后还得回头补数据工程。这部分没有捷径,但可以按标准化流程走,把坑提前堵住。
3.1 数据来源与目录组织:先定结构再谈训练
舌苔图片数据的来源,实践中最常见的有三种:公开数据集、自己采集、网络爬取。无论哪一种,第一件事就是整理成统一的目录结构。目标检测任务的数据必须包含两类文件:图片本体和对应的标注文件。图片通常是 JPG 或 PNG,标注文件则记录“哪个框属于哪个类别”。
tongue_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── classes.txt这是一份非常典型的目标检测数据集结构。图片放在images下并按用途划分训练集、验证集和测试集,标注文件放在labels下且划分逻辑与图片一一对应,classes.txt里写类别名,一行一个。为什么 demo 阶段也要强制做三集划分?因为深度学习实验最忌讳拿训练过的数据再验证,会得到虚高的精度。舌苔检测这种样本相似度极高的任务,如果划分不当,验证集里混入训练集同源图片,训练过程看着 loss 降得很漂亮,一换新图片立刻现原形。
我一般会把训练集占比定在 70%,验证集 20%,测试集 10%。舌苔检测的类别通常不多,常见设置是三到六类,比如“正常、白苔、黄苔、厚腻苔”之类,取决于课题定义。类别数量直接影响模型复杂度:类别少,模型很小也能收敛得很好;类别多,就得考虑加深网络。
3.2 标注格式转换:最容易踩坑的坐标系归一化问题
课程设计项目中经常遇到的情况是:拿到的公开数据是 VOC 格式的 XML 标注,而训练脚本读的是 YOLO 格式的 TXT 标注。这两种格式的区别是很多人的第一个大坑。VOC 标注里存的是绝对像素坐标,比如<xmin>128</xmin> <ymin>96</ymin> <xmax>256</xmax> <ymax>192</ymax>;而 YOLO 格式要求的是相对于图片宽高的归一化坐标,格式是类别编号 cx cy w h,其中 cx、cy 是中心点坐标,w、h 是框宽高,所有值都在 0 到 1 之间。
import os import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_path, img_path, out_dir, class_list): tree = ET.parse(xml_path) root = tree.getroot() img_w, img_h = Image.open(img_path).size out_lines = [] for obj in root.findall("object"): name = obj.find("name").text if name not in class_list: continue cls_id = class_list.index(name) box = obj.find("bndbox") xmin = float(box.find("xmin").text) ymin = float(box.find("ymin").text) xmax = float(box.find("xmax").text) ymax = float(box.find("ymax").text) cx = (xmin + xmax) / 2.0 / img_w cy = (ymin + ymax) / 2.0 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h out_lines.append(f"{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") txt_name = os.path.splitext(os.path.basename(xml_path))[0] + ".txt" with open(os.path.join(out_dir, txt_name), "w") as f: f.write("\n".join(out_lines))这段脚本的核心逻辑是把 XML 里的绝对坐标读出来,再用图片宽高把它归一化到 0 到 1 区间。注意两个细节:一是中心点的计算用的是(xmin + xmax) / 2.0,不要错写成(xmax - xmin) / 2.0,那是宽度;二是所有除法都要保留浮点,Python 里整数相除会丢精度。这段脚本里class_list是类别列表,顺序必须和后续训练时的classes.txt严格一致,否则类别编号错位会让模型学到错误映射。
标注转换完成之后要做一次质量抽检:随机挑十张图片,把标注框按坐标画回到原图上,肉眼确认框位置和类别是否匹配。这一步至关重要,我在日常工作时称之为“标注可视化验证”,能过滤掉百分之八十的低级错误,切记不要跳过。
3.3 数据增强:别让你的增强操作毁掉标注框
舌苔图片数据集通常规模不大,几百张到一千张左右属于正常区间。在这个量级下,不做数据增强,模型几乎必然过拟合。但增强不是越狠越好,尤其目标检测任务,任何几何变换都必须同步修改标注框坐标,否则训练时模型看到的框就是错位的。
import albumentations as A from albumentations.pytorch import ToTensorV2 train_transform = A.Compose([ A.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, p=0.5), A.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=20, val_shift_limit=20, p=0.3), A.HorizontalFlip(p=0.5), A.Rotate(limit=15, p=0.5), A.RandomResizedCrop(size=(640, 640), scale=(0.8, 1.0), ratio=(0.9, 1.1), p=0.4), ], bbox_params=A.BboxParams(format="yolo", label_fields=["class_labels"]))这段增强管线选了四个操作:随机亮度对比度模拟不同光源下的舌象差异,色相饱和度轻微扰动模拟舌体颜色偏移,水平翻转增加样本多样性,随机旋转与裁剪增强模型对拍摄角度的鲁棒性。关键参数在bbox_params里:format="yolo"告诉 Albumentations 当前传入的标注是 YOLO 归一化格式,库会自动在应用旋转、裁剪等变换后同步更新框坐标。这正是选择 Albumentations 而不是手写增强函数的原因,它把“增强后标注框怎么办”这个黑匣子封装好了。
需要特别提醒的是两种增强操作在舌苔检测里要慎用。一是随机遮挡(CoarseDropout),如果遮挡区域正好覆盖舌苔中心,模型会被迫学习不完整的特征,加重误检;二是过强的 HSV 扰动,舌色本身就是诊断依据之一,把颜色改成不符合常理的范围,就等于给模型注入了错误语义。这类任务里,保持舌象颜色语义的轻微扰动即可,病态颜色和正常颜色之间的边界本来就细微,增强过度会把这条边界彻底抹掉。
数据准备到这一步,已经能进入训练了。如果你解压资源后发现自带数据集不是这种标准结构,建议抽一个小时做一次清洗和重排,这会在训练时省下大把排查时间。
4. 训练与推理:把损失曲线降下来,把检测框画出来
模型训练是深度学习项目里最像“玄学”的阶段,同时也是最有规律可循的阶段。舌苔检测这种单类别少样本任务,训练策略的核心不是把网络调得多复杂,而是控制好过拟合与收敛节奏。这一章给出一个可以直接抄作业的训练启动方式,以及一个完整的推理可视化脚本。
4.1 训练启动与参数含义:先跑 30 个 epoch 看趋势
我向来不建议一上来就跑上百个 epoch。第一次训练请先设一个较短的迭代轮次,用验证集判断模型有没有在收敛,再决定是继续加轮还是调整超参数。启动训练的命令形如:
python train.py --data data/tongue.yaml --weights yolov8n.pt \ --epochs 30 --batch-size 8 --imgsz 640 \ --device 0 --project runs/train --name tongue_experiment_01逐项拆解这些参数:--data指向数据配置文件,内部写明了训练集、验证集路径和类别数量;--weights是预训练权重,使用 COCO 预训练模型做初始化是毕设项目的常规操作,能大幅缩短收敛时间;--batch-size 8表示每个训练批次放 8 张图,这个值要结合显存调整,显存不够就降到 4 或 2;--imgsz 640是把输入图片统一缩放到 640×640;--device 0指定使用第一块 GPU;--project和--name控制输出目录。
下表是几个关键超参的推荐范围与调整逻辑,训练时照着设基本不会出大问题:
| 参数 | 推荐值 | 设定逻辑 |
|---|---|---|
| epochs | 50-100(首次 30) | 先用 30 轮验证收敛趋势 |
| batch-size | 4-16 | 受显存约束,越大梯度越稳 |
| imgsz | 640 | 过小丢细节,过大显存不够 |
| lr0 | 0.01(SGD)/ 0.001(Adam) | 学习率过高会导致 loss 震荡 |
| optimizer | SGD 或 AdamW | 数据量小时 AdamW 更好收敛 |
| patience | 20 | 验证集精度连续 20 轮不涨就早停 |
训练开始后,你需要盯住两个输出:终端里实时刷新的 loss 值和每个 epoch 结束后的验证精度。第一个 epoch 的 loss 值通常会偏大,之后会快速下降,这是正常的。真正需要警惕的是两种异常:loss 在前 10 个 epoch 内不降反升,通常是学习率太大或数据没对齐;验证精度从高位往下掉,说明模型开始过拟合,应该提前终止或加强增强。训练日志会写到--project指定的目录里,后续画 loss 曲线、写论文实验章节都用得上这批记录。
4.2 推理与可视化:模型效果怎么变成论文中的检测图
训练完成后,你要输出一批检测效果图,这批图是论文“实验结果”章节最重要的素材。推理脚本的核心逻辑是加载权重、读入图片、前向传播、解析检测结果、画框保存。
import torch import cv2 from PIL import Image model = torch.load("runs/train/tongue_experiment_01/weights/best.pt", map_location="cpu") model.eval() img_path = "data/test/sample_001.jpg" img_bgr = cv2.imread(img_path) img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) results = model.predict(source=img_rgb, imgsz=640, conf=0.25, device="cpu") for r in results: boxes = r.boxes for box in boxes: x1, y1, x2, y2 = map(int, box.xyxy[0].tolist()) cls_id = int(box.cls[0]) conf = float(box.conf[0]) label = f"tongue {conf:.2f}" cv2.rectangle(img_bgr, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img_bgr, label, (x1, y1 - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite("output/sample_001_result.jpg", img_bgr)这段脚本的工作流程分三步:第一步把训练时保存的best.pt权重加载进来并切换到评估模式,map_location="cpu"允许在没有 GPU 的机器上推理;第二步对输入图片做推理,conf=0.25是置信度阈值,低于 0.25 的框会被过滤,这个值可以在 0.15 到 0.5 之间微调,调低会召回更多框但误检也增多;第三步遍历检测结果,用 OpenCV 画出绿色的边界框和标签文本,写回磁盘。逻辑上需要注意的是box.xyxy[0]为左上角和右下角坐标,画矩形时直接使用即可,不要把检测框坐标再归一化回原图尺寸,因为推理框架输出的已经是原图坐标了。
推理验证这一步我会额外做一组“难例测试”:专挑拍摄光线差、角度偏、舌体部分遮挡的图片跑一遍推理,观察模型在这些样本上的表现。别小看这个习惯,它决定你论文里“局限性分析”部分有没有话可写。我见过太多人只挑效果好的图放进论文,答辩时老师随机传一张实时拍的舌象,模型直接翻车,场面极其被动。自己先曝光问题,反而是答辩时的加分项。
到这里,工程主流程已经通了。接下来的一章我认为是全篇含金量最高的部分:那些让你一夜之间推翻重来的隐藏坑。
5. 避坑指南:舌苔检测训练最容易翻车的五个地方
实践项目区别于理论学习的最大特征,就是你会反复踩进同一个坑里。以下五条是我拆解类似目标检测项目时最常遇到的故障,按“现象 → 原因 → 解决”的方式整理,每一条都是真金白银换来的教训。
5.1 训练没有报错,但检测框全部偏到图片角落
现象:训练过程 loss 正常下降,验证精度也在涨,但跑推理时画出来的框全部缩在图片边缘或者完全错位。
原因:标注坐标在预处理阶段被错误归一化。最常见的情况是,代码把 VOC 的绝对坐标直接当成了 YOLO 的归一化坐标喂给模型,或者图片在训练前被缩放到 640×640,但标注没有同步按缩放比例调整。
解决:回到 3.2 节的转换脚本,打印一张图中标注的原始坐标和转换后坐标,人工验算换算关系。检查训练脚本里letterbox处理有没有返回缩放比例参数,如果有,需要在送入 loss 计算时把坐标映射回原图尺寸。这类问题的本质是“训练时模型看到的坐标是对的,推理时还原坐标时少了一步逆变换”。
5.2 验证集精度很高,换新图检测效果一塌糊涂
现象:验证集上的 mAP 达到 0.9 以上,但你随手拍一张新舌象,检测框要么漏检要么误检严重。
原因:这是典型的数据泄漏。公开的舌苔数据集通常来源于同一批采集设备、同一环境光照,数据间相似度太高。验证集与训练集虽然文件不同,但图片背景、拍摄角度、色彩分布高度同质,模型实际学的是“这个背景下的舌头”,而不是“舌头本身”。
解决:去网上找一些不同设备拍摄的舌象图,混入验证集重新测试;再不行就做跨域数据增强,把亮度扰动幅度调大、加入高斯噪声模拟手机拍摄的压缩伪影。如果条件允许,用手机在真实环境下拍 30 到 50 张舌象作为外部测试集,这个外部集不进训练、只做最终评估,能真实反映系统的泛化能力。
5.3 训练 loss 前几个 epoch 暴涨,然后一直不降
现象:启动训练后,第一个 epoch 的 loss 值高得离谱,后面既不下降也不震荡,像一条水平线。
原因:学习率与优化器不匹配。舌苔检测的骨干网络如果加载了预训练权重,初始学习率设到 0.01 配合 Adam 优化器,会出现梯度爆炸;如果没用预训练权重、数据量又小,模型在随机初始化状态下很难快速收敛。
解决:换用 AdamW 优化器并把初始学习率降到 0.001;或者维持 SGD 但增加一个 3 个 epoch 的 warmup 预热阶段,让学习率从 0 线性升到目标值。同时检查数据配置文件里的类别数量是否与标注文件的类别编号上限一致,类别数写错也会出现 loss 无法收敛的诡异情况。
5.4 显存不足,直接 OOM 中断训练
现象:训练大概十几个 step 后,报错CUDA out of memory,进程直接崩掉。
原因:批量大小和输入图片尺寸的乘积超过了显存容量。很多人的习惯是照抄别人的 batch-size 设 16,结果自己的显卡只有 6GB 显存,vram 直接被输入张量和中间特征图填满。
解决:把--batch-size降到 4,--imgsz降到 640 甚至 512。注意,改小imgsz后标注坐标不需要重新转换,因为训练脚本会自动做归一化,你只需要接受精度可能下降的现实。如果 batch-size 降到 2 还爆显存,那这张卡只适合跑推理,训练请改用云 GPU。4GB 显存的显卡跑这个项目,batch-size 4、imgsz 640 是安全组合,别挣扎。
5.5 同样的代码和参数,隔一周跑结果不一致
现象:昨天训练精度 0.87,今天相同参数重新跑变成 0.82,论文里的实验数据没法复现。
原因:深度学习框架里有大量随机因素,包括模型权重初始化、数据加载顺序、CUDA 算子的非确定性执行。如果你在代码里没有固定随机种子,每一次训练都是不同的实验。
解决:训练入口处固定所有能固定的随机源:
import random import numpy as np import torch def set_seed(seed=42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False代码逻辑很直接:把 Python 随机库、NumPy、PyTorch CPU 和 GPU 的随机种子全部固定,同时关闭 cuDNN 的自动调优模式。注意torch.backends.cudnn.deterministic = True会牺牲少量训练速度来换取结果可复现,这是论文实验阶段必须付出的代价。如果你跑实验发现固定了种子结果还有微小浮动,属于正常现象,可以在论文实验描述里注明“结果基于固定随机种子,重复实验波动小于 0.5%”,这句话足以应对答辩质疑。从那以后我每次训练前都会强制走一遍“设种子 + 打印配置”的固定流程,避免后期写论文时发现实验数据互相矛盾。
6. 开题报告与论文:从工程复现到答辩材料的关键技巧
很多同学以为代码跑通就万事大吉,实际答辩时被批得最惨的恰恰是论文写法。这份资源里附带开题报告和论文初稿,但你不能直接照着交,需要按自己的实验数据重写。核心原则是:论文的每一个结论,都要能从你跑实验留下的日志和曲线里找到出处。
论文结构通常包含五个核心部分,每一部分对应不同的工程材料:
| 论文章节 | 内容要点 | 工程对应物 |
|---|---|---|
| 绪论 | 舌苔检测的研究背景与意义 | 开题报告中的文献综述 |
| 相关技术 | CNN、目标检测框架原理 | 网络结构图和训练框架 |
| 系统设计 | 数据预处理与模型选型 | 数据增强代码与训练配置 |
| 实验与结果 | 数据集描述、训练细节、精度指标 | loss 曲线、PR 曲线、检测效果图 |
| 总结与展望 | 方法局限性与改进方向 | 难例检测图的失败分析 |
图表方面,有三个图是答辩老师必看的。第一张是典型检测结果图,选 6 到 8 张不同舌象状态的图片拼接,要求每张图片里的检测框和类别标签清晰可见;第二张是 loss 曲线,横轴是 epoch,纵轴是损失值,用来展示训练收敛过程;第三张是 PR 曲线或 mAP 柱状图,这是你的精度最直观的表述。画图工具就用 Matplotlib,训练日志里记录的 loss 和 mAP 数据直接读出来绘图,不要手工编造数据——答辩现场一键复现实验的能力,比纸面数字更能让老师信服。
开题报告和论文里的语言要避免口语化。工程里你写“我试了好几个参数发现 0.001 最好”,论文里得改成“经过多次实验对比,本文最终将初始学习率设置为 0.001,该参数下模型收敛速度与最终精度达到最佳平衡”。再者,查重处理上,不要只替换同义词,而是把整个句子按你自己的实验数据重写。比如“实验采用 800 张舌象图片,按 7:2:1 划分为训练集、验证集和测试集,训练集 560 张,验证集 160 张,测试集 80 张”,这类具体数字写得越细,越不容易和别人的模板撞车。最后提醒一个细节:训练阶段的超参数表必须列全,包括显存占用、单轮训练耗时,这些细节会让论文整体显得非常扎实。
这套流程走完之后,你手里应该有三件东西:能跑通的舌苔检测系统、一套完整的训练与推理记录、一份改好的开题报告和论文。答辩前两周,建议把 5.2 节提到的外部测试集再跑一遍,把几个失败案例也写进论文的展望部分,这比回避问题更能赢得认可。希望帮到你。
本文还有配套的精品资源,点击获取