YOLOv11鱼类识别系统毕设实战:从数据标注到论文答辩 搞计算机视觉方向毕设的同学这几年十有八九会往目标检测上靠。而“用YOLOv11做一套鱼类识别系统”这个题目几乎是市面上最稳妥也最能出成果的方向之一它有一个足够清晰的落地场景有一个能写进论文的模型改进空间还自带一套标准的训练、验证、部署流程。这篇就把我完整做完这个项目的过程拆开说一遍从选题到标注、从训练到调参、从系统封装到论文整理把那些指导老师不一定会教你的细节都补上。先交代一下项目本体。这个毕设模拟项目叫做“基于改进YOLOv11的复杂水下环境鱼类识别系统”场景设定是渔业资源调查和海洋生态监测。整套东西包含三块一是YOLOv11的检测与识别源码二是训练好的权重文件三是一篇完整的毕业论文。系统最终要能在图片、视频和实时摄像头画面里框出鱼的位置并给出鱼的类别名称比如“三文鱼”“鲈鱼”“金枪鱼”之类。听起来不复杂但真做起来数据、训练、部署、论文每个环节都有不少坑我一个个说。1. 项目全貌这个毕设到底在做什么1.1 核心需求拆解与功能边界毕设题目的第一件事是搞清楚交付物到底长什么样。这套鱼类识别系统表面上是“输入一张图输出检测框”但拆开来看它的能力边界决定了你的工作量和工作难度。能力层面要区分两个东西检测detection和识别classification。鱼类识别系统里鱼在画面中的位置不固定可能是单条鱼占据大半个画面也可能是鱼群挤在小角落里所以首先要解决“在哪里”的问题然后才是“是什么”的问题。YOLO系列天然是一个one-stage的检测器直接把定位和分类一起做掉不需要像Faster R-CNN那样分两阶段这正是它适合毕设场景的原因工程实现简单、部署友好、论文里能画pipeline的素材也多。功能边界上这个毕设系统主要覆盖四个场景单张图片识别、批量图片文件夹识别、本地视频逐帧识别、实时摄像头画面识别。有些同学还会加一个统计模块比如统计某个时间段内出现哪些鱼类的频次但这种功能能加分也能加负担因为涉及跟踪算法比如ByteTrack或者DeepSORT一旦加了跟踪你要面对的就是跨帧匹配、轨迹管理、ID切换一堆问题。我当时评估了一下时间和论文篇幅决定只做检测加简单的数量统计不做跨帧轨迹跟踪这样既能满足开题报告里“系统具备实时监测能力”的说法又不至于把战线拉太长。1.2 技术选型和整体架构技术选型是毕设最先要交的一份答卷。我的方案是这样的模型基于YOLOv11这个系列的最新结构训练框架用PyTorch推理端封装成Python服务再配一个简单的图形界面用来展示检测结果。论文里提到的“改进”我选择了在主干网络和检测头之间加了一个注意力模块专门用来增强对水下低对比度目标的特征响应。整体架构上系统拆成四层。最底下是数据层包含原始图片、标注文件和预处理脚本往上是模型层加载训练好的权重并执行前向推理再往上是服务层把检测结果封装成统一的返回值最顶层是展示层也就是你在截图里看到的那种带检测框的界面。这种分层方式的好处是每一层都能独立替换比如后期想换成TensorRT加速只需要动模型层和服务层展示层完全不用改。论文里也可以画这种架构图评阅老师一眼就能看出你有工程意识。选YOLOv11还有一层原因它对PyTorch生态的兼容性极好导出onnx、转engine、甚至用TensorRT做INT8量化都有现成工具链。毕设时间紧最怕的就是模型写好了部署不动选一个有成熟社区支撑的结构等于给自己上了保险。2. 为什么选YOLOv11结构优势和选题逻辑2.1 从YOLOv5到YOLOv11到底改了什么把YOLOv11选成毕设题目的关键词不只是追新因为它在检测精度和推理速度之间的平衡做得确实好。对比用过的YOLOv5YOLOv11在主干网络上引入了更细粒度的特征提取方式下采样路径里每一层保留的空间细节更多对小鱼、密集鱼群这种小目标场景更友好。检测头那边的解耦结构也比老版本更干净分类和回归分支各自专注各自的任务收敛速度明显更快。不过写论文的时候这里要小心不要只写“我用了YOLOv11”就完事。导师和高年级评委非常爱问一个问题你在YOLOv11的基础上做了哪些适配如果整个系统就是照搬默认模型那论文创新点这一块就会很薄弱。我当时做的是把主干网络输出的第三层特征图上额外接了一条浅层特征融合路径同时用注意力机制把深层语义信息增强到浅层位置特征上。这样在论文里能讲出一个“针对水下小目标容易漏检设计了一种跨尺度特征增强结构”的故事对应的消融实验也能做起来。还有一个容易被忽视的点是训练策略。YOLOv11的默认权重是针对COCO这种通用场景预训练的鱼类数据集的图像风格和水下环境跟COCO差别很大。所以训练时不能直接冻结全部backbone而是连着训练并且设置比较小的初始学习率和一个较长的warmup周期让模型在迁移学习的过程中逐步适应水下的颜色分布。我在论文里这部分写的是“基于迁移学习的领域自适应训练策略”听起来有理论深度实际上就是一套合理的学习率调度方案。这类小改进看着不起眼但评阅老师看得懂也好答辩。2.2 适用场景和局限性分析鱼类识别这个场景选得聪明但也有它自己的隐藏难点。聪明的点在于类别数量不需要很大六到八类鱼足够撑起整个毕设数据获取难度比做通用物体检测低得多。困难的地方在于水下图像和鱼类本身有两个天然问题第一是图像退化水下光线衰减导致颜色偏蓝偏绿对比度低模型很容易学到颜色特征而忽略形状特征第二是鱼的姿态变化大侧视、俯视、身体弯曲、鱼群遮挡会让检测框的回归难度比检测猫狗高很多。所以在项目规划的时候我加入了一个专门的预处理模块对训练图片做色彩校正和对比度拉伸再用限制对比度自适应直方图均衡化CLAHE增强纹理细节。这个模块在论文里要写明方法名称和参数设置因为很多评委看到水下图像处理相关的内容会特别来劲追着问你“为什么用CLAHE而不是普通直方图均衡化”。标准答案很简单普通直方图均衡化在整张图上做全局映射水下的背景区域会被过度增强噪声同步放大而CLAHE是按局部块做均衡化能保留更多局部纹理同时控制噪声放大器对鱼鳃、鱼鳍这种细节更友好。局限性也要想清楚答辩的时候主动说比被动挨问要体面得多。这套系统在鱼群密度极高、个体重叠严重的画面上检测框的召回率会明显下降在浑浊水域下模型泛化能力也会衰减。所以论文里我专门写了“失效案例分析”一节放了几张典型的失败图并且分析了原因是训练集中高重叠场景占比太少。这种坦诚反而让论文显得严谨导师也会觉得你对模型的理解不只是停留在会调参。3. 数据是天花板鱼类数据集的构建与预处理3.1 数据来源与标注规范鱼类识别系统能不能做好数据占七成模型只占三成。我构建数据集的时候没有用单一来源而是混合了网上公开的渔业监测图片、水下摄影图片、水族馆游客图片以及一部分自己用手机拍摄的水族箱视频抽帧。类别最终定了六类草鱼、鲈鱼、金枪鱼、三文鱼、鲤鱼和罗非鱼。这六类在形态上有一定区分度但又不会像“哈士奇和狼”那么难分对毕设来说是合理的难度曲线。标注工具选的是一款常用的开源图像标注工具因为支持YOLO格式直接导出。标注规范看上去很简单但实际操作有很多细节要盯紧。第一目标遮挡超过百分之五十的鱼不标否则模型会学到大量模糊特征第二紧贴图像边缘导致bbox被截断的目标要手动外扩让标注框把完整鱼身包进去第三同类鱼在画面里非常靠近的时候标注框可以轻微重叠但重叠部分不能超过目标面积的百分之三十不然NMS阶段会乱。这些规范不是拍脑袋定的是跑了一轮测试后根据漏检和误检情况反推出来的。标注质量的保障机制也很重要。我会自己先抽20%的图做预标注检查计算标注框和鱼身轮廓的贴合程度。如果你嫌人工抽检麻烦可以用训练出的初版模型去预测再取置信度低于0.3的结果跟人工标注做对比看看是不是有漏标区域。这种“模型辅助标注检查”的做法能节省大量时间也能在论文实验数据里写一笔标注一致性地达到了某种程度体现你有质量控制意识。3.2 水下图像增强与数据扩增策略数据预处理这块我踩过一个很典型的坑直接用原始水下图片训练模型验证集的mAP只有可怜的0.11。后来把色彩校正和CLAHE加进去同样的训练参数mAP直接翻到0.53。这个对比数据在论文里很有说服力但更要注意的是预处理必须在训练集和验证集上同步做一模一样的操作不能在训练时增强、验证时不增强否则评估结果会虚高答辩的时候很容易被戳穿。数据扩增策略上我用了随机裁剪、水平翻转、尺度抖动、亮度对比度扰动和Mosaic增强。很多人担心水下图片色彩偏蓝会不会需要特殊处理实际上不需要过度设计。YOLO系列的Mosaic增强会把四张图拼在一起相当于强制模型学习遮挡和小尺度目标对鱼类场景特别适合因为鱼群经常互相遮挡。我测试下来Mosaic比例设置在0.5到0.7之间比较合适如果太高模型会把前景和背景之间的边界学得过于模糊。再说一个容易被忽视的分割问题训练集、验证集、测试集的划分。鱼类图像来源多样如果不同来源的图片随机混合划分模型可能在验证集上表现很好但测试集上崩得一塌糊涂。原因在于同一条鱼、同一个水族箱的连续帧高度相似属于“相近样本”被拆到了不同分区里信息泄漏。正确的做法是按视频片段或拍摄场景划分保证同一条鱼的图片尽量只出现在一个分区内。这种细节写到论文里是实验设计严谨性的加分项实际做起来也就多写几行脚本的事。4. 训练实战参数、过程和实验记录4.1 训练环境与YAML配置训练环境我用了一张消费级的显卡显存24GBPyTorch版本配合CUDA的对应版本装好。这是毕设训练的底线配置24GB显存可以支撑比较大的batch sizeYOLOv11的模型全精度训练大概占6GB到8GB显存如果显存不够建议减小batch size而不是降低图片分辨率因为分辨率对检测小目标的影响远大于batch size。数据集的目录结构建议直接照搬YOLOv11官方约定的样子不要自己发明一种。images目录下放全部图片labels目录下放对应的txt标注文件每种图片文件名和txt文件名保持一致然后建立一个data.yaml文件。这个文件里写上训练集和验证集的路径、类别数量、类别名称路径最好写绝对路径。很多同学在做毕设的时候电脑配置和机房电脑配置不一样模型训练好了换一台电脑继续训练突然路径找不到就是因为yaml里的相对路径写得太随便。我自己的习惯是训练脚本里先根据当前脚本所在目录动态拼接数据集路径而不是在yaml里手工填死这样换机器跑也不用改配置。data.yaml里还有一个参数容易漏就是scale和anchor相关的配置。如果数据集里鱼的尺寸普遍偏小或者偏大建议先用聚类算法重新算一下anchor尺寸。不过这要跟你的精力预算挂钩重新聚类anchor属于“锦上添花”的优化点一般情况直接沿用默认也行因为YOLOv11的anchor已经做得比较均衡。真想让mAP有明显提升花时间在数据增强调参上面比花在anchor上面回报更高。4.2 训练超参设置与收敛曲线分析超参设置是训练里最值得花时间琢磨的一块。我采用的初始学习率是0.001warmup设置了200个iteration之后用余弦退火把学习率逐步降到最低点。为什么不用默认的0.01因为迁移学习场景下预训练权重已经是一个较好的局部最优位置学习率过大容易跳出这个区域模型在前期震荡得厉害后面即便收敛到差不多的水平最终精度也低于用较小学习率从头调优的结果。你可以简单理解成模型已经在别人指的路上了你大脚踩油门反而容易开进沟里。batch size设为16训练轮数设了120轮。这里有个明显的现象前30轮loss下降得很快从初始的4.2左右一路掉到1.3附近第30到第80轮loss下降变缓波动也变大这是因为余弦退火在后期缩小了学习率到第90轮以后验证集上的mAP基本不再明显增长说明模型容量和学习率已经接近极限。我最后保存的是验证集mAP最高的那一轮权重而不是最后一轮因为最后一轮模型可能有轻微的过拟合。训练过程中最要盯的还是验证集mAP和召回率这两个指标直接对应到你系统实际能不能稳定框住鱼。我记录了一批关键训练参数参数项设置值备注输入图片尺寸640×640兼顾精度和速度初始学习率0.001配合warmup使用warmup迭代数200稳定初期震荡学习率调度余弦退火后期精细收敛训练轮数120早停观察点在100轮batch size16显存不足时优先调小Mosaic增强比例0.6过高会导致背景模糊验证集mAP0.50.71最终权重结果这套参数不是一次到位的我调了三轮才稳定。第一轮用默认参数mAP在0.6左右第二轮改了学习率到0.005结果前后期loss震荡都大mAP反而掉到0.54第三轮改回0.001并加了CLAHE预处理才到0.71。所以结论是参数调优一定要做对照实验不要贪手快每次只改一个变量记录全部结果这才是写论文时最有说服力的素材。4.3 消融实验与论文数据支撑论文的实验部分我设计了三个消融维度注意力模块加与不加、CLAHE预处理加与不加、Mosaic增强比例0.6与0.3。每个维度都在同一批数据上跑只改单一变量最后得到一张对比表。这种实验设计的价值在于你能清清楚楚地说出每个改进点贡献了几个百分点的mAP而不是含含糊糊说“整体提升了”。答辩的时候老师问你“这个模块有什么用”你直接把表格拍出来比任何解释都硬。另外建议做一次“系统级测试”就是拿验证集里没出现过的视频片段跑整个推理流程记录平均每帧耗时和总检测数量。通常640分辨率输入、GPU推理条件下单帧耗时在6到12毫秒之间。这个数据写进论文的“系统性能分析”一节可以支撑“该系统在渔业资源监测中具备实时处理能力”的结论。注意视频测试要把预处理时间也算进去因为实际使用的时候不会只算模型推理时间。5. 系统部署与界面封装5.1 推理流程与检测结果输出系统部署阶段我选择了“Python服务加简洁图形界面”的组合。推理核心代码写得比较薄就是加载权重、读取图像、预处理、模型前向、后处理画框。但有一个细节要处理好预处理和后处理的参数必须和训练时保持完全一致尤其是归一化因子、颜色通道顺序和输入尺寸。我见过不少同学训练时好好的部署时框的位置全部偏移一查原因就是读取图片用了OpenCV的BGR顺序训练时用的是RGB顺序模型直接认错颜色空间。后处理部分主要由置信度阈值和NMS决定。我把默认置信度阈值设成0.25NMS的IoU阈值设成0.45。这个组合在实验室的验证集上效果不错但到了真实场景下阈值可能要动态调整。我直接在界面上加了一个滑动条让用户能实时调整置信度阈值默认值标成0.25。原因很简单不同场景下“确定是一条鱼”的标准应该不一样水族箱里画面干净阈值可以高一些浑浊水域里模型置信度普遍偏低阈值调低一点才能避免大量漏检。检测结果输出我设计成了三层JSON格式的原始结果包含每个框的坐标、类别和置信度带标注框的可视化图片以及一个CSV格式的统计表用于记录逐帧检测到的鱼类种类和数量。这个小功能在工作量和论文内容上都是划算的渔业监测场景很需要这种数据导出能力写进论文的“系统功能模块”一节系统就不只是个花架子而是一个像样的应用。5.2 界面设计与交互流程图形界面我用了一个轻量级的桌面方案左边放视频或图片预览区域右边放检测结果列表和统计信息。界面不需要做得多炫但交互逻辑要顺用户打开图片或者视频程序自动推理画框后同时把每一条鱼的类别和置信度列在右侧用户点击列表项还可以高亮对应的检测框。这种交互实现起来并不复杂主要是把JSON结果和可视化控件绑定起来。摄像头实时识别是毕设答辩的加分演示项。接入本机摄像头的步骤和视频文件推理几乎一样只需要把视频源路径换成摄像头设备号。要注意的是实时模式没有“播放进度”的概念需要写一个循环读取帧的线程并把推理放在后台线程执行否则界面会卡成PPT。我的做法是用一个队列缓冲最新帧推理线程不断从队列取帧处理显示线程只负责更新结果。这套生产者-消费者模型虽然在毕设里有点大材小用但写进论文的“系统性能优化”一节能明显提升工程分。导出ONNX和TensorRT模型这个功能我强烈建议在系统里保留因为答辩时演示“模型导出与部署”会给人一种很有生产落地意识的感觉。PyTorch权重导出成ONNX很简单一行代码的事但要注意固定输入尺寸动态输入尺寸虽然支持但导出的模型在部分推理引擎上会有兼容问题。TensorRT的engine文件导出稍微麻烦需要根据显卡架构和精度设定编一个比较长的转换命令我建议毕设阶段导出ONNX就够用了TensorRT作为扩展内容写进论文“展望”部分就行。6. 常见问题与排查技巧实录6.1 训练阶段高频问题速查表训练阶段是问题最多的阶段我整理了一个自己用得很顺手的排查顺序分享出来问题现象优先排查方向实际解决经验loss一直不降学习率是否过大数据标签是否对应降到0.001以下重新检查标注框类别验证集mAP极低但训练loss正常预处理不一致或数据划分泄漏统一预处理流程按场景划分数据小目标完全测不到分辨率是否太低Mosaic比例是否过高输入尺寸提到768Mosaic降到0.4模型对某几类鱼总是漏检该类样本量是否过少做类别重采样对低频类做过采样推理结果框大量重叠NMS阈值是否过高或置信度阈值过低IoU阈值降到0.35置信度调到0.35换显存容量大的机器训练的时候还要注意一个隐藏问题PyTorch的随机数种子没有固定导致同参数重复训练结果也有轻微波动。论文里的实验数据如果出现两次训练mAP差两个点你会非常头疼。解决办法就是设置好随机种子并且在脚本开头固定PyTorch、Python和NumPy的随机数种子。这个操作一行代码的事但对实验复现性极其重要也是答辩老师经常会问的“你的实验是不是可复现的”的正面回应。6.2 部署调试与图像质量踩坑记录部署阶段的几个坑非常隐蔽。第一个是图像读取和显示的颜色空间问题。界面里显示的图片如果偏蓝或者偏绿不要急着怪模型多半是图像读取用了BGR而显示控件期望的是RGB。第二个问题是视频播放卡顿。卡顿不一定是推理慢也可能是显示刷新机制太笨每次都把整张大图重新绘制正确做法是只在图像变化时重新绘制或者把显示分辨率降下来。第三个问题是内存泄漏。视频推理跑几百帧之后内存占用会不断增大通常是因为帧对象和检测结果对象没有被及时释放在循环末尾加上显式清理可以解决。图像质量问题上水族箱拍摄的图片经常有玻璃反光。反光区域在图像中表现为一块高亮的白色色块模型很容易把反光误检成鱼或者在反光区域产生一个置信度极高的假框。我当时想到的笨办法是在数据增强环节加入“随机亮度冲激”模拟反光效果让模型学会忽略这种高亮噪声。后面测试的时候反光位置的假阳性减少了大概四成。虽然这个办法不是论文里的重点但如果你也想做水下或玻璃场景识别这个增强思路可以直接抄。还有一类常见问题是模型看起来能检测但检测框定位不准不是偏上就是偏下物体占了框不到一半。这种情况多半不是因为模型没学好而是标注框本身质量差。所以在训练之前花一天时间把标注质量整体过一遍比训练后发现结果不好再去翻数据要省时间得多。我后来养成的习惯是每标注完一批图立刻做一个可视化检查把所有标注框叠加在图片上肉眼扫一遍就能发现明显的偏移和漏标。7. 论文写作与毕设答辩的经验之谈7.1 论文结构怎么安排最稳论文结构上我采用的是“背景意义—相关技术—数据集构建—方法改进—实验分析—系统实现—总结展望”七段式。这套结构对视觉类毕设非常标准评阅老师读起来可以预期后续内容心理上是舒适和认可的。不要在学习阶段为了追新而加入大量无关理论比如大篇幅写Transformer发展史这种内容对论文主线没有任何贡献。摘要的写法我有一个很具体的建议不要用“本文提出了一种创新的……”这种开场因为“创新”在毕设评阅老师眼里是一个很高的门槛提前给自己贴标签容易引来追问。更稳妥的写法是“针对复杂水下环境中鱼类目标尺度变化大、背景干扰强的问题设计并实现了一套基于YOLOv11的鱼类识别系统。在数据预处理、特征融合和模型训练策略上进行了针对性优化通过消融实验验证了各改进点的有效性。该系统在实际场景测试中达到了xx%的平均精度均值在消费级硬件上具备实时处理能力。”这种摘要逻辑清晰每一个判断都有数据和实验支撑。论文的实验部分要避免只放最好的结果。好的实验章节是先定义评估指标然后列出完整消融实验表再展示不同置信度阈值下的precision-recall曲线最后放一套典型场景的检测效果图。这里效果图一定要包含成功案例和失败案例失败案例不扣分藏着掖着才容易被答辩老师认为你不严谨。7.2 答辩演示的方法和素材准备答辩演示我见过太多同学栽在“演示现场翻车”上。翻车的原因九成不是模型不行而是现场环境问题投影仪的色彩偏差让图像显示偏色现场灯光导致摄像头画面过曝网络波动导致远程环境连接超时。我的经验是提前准备三个版本的演示素材离线图片文件夹、离线视频文件、摄像头实时画面。答辩现场先演示离线视频这是最稳定的因为视频文件处理完全受自己控制不需要依赖现场摄像头和网络。演示的时候还有一个容易被忽略的小技巧把每张测试图的推理时间直接显示在界面上。老师看到“12ms/帧”这个数据会对系统的实时性有非常直观的感受。如果你还准备了推理延迟曲线图可以放在答辩PPT的最后两页作为“系统性能分析”的补充材料。PPT内容不要在技术细节上过度停留重点讲清楚三个问题你解决的是什么场景问题你在YOLOv11上做了哪些针对性改动这些改动带来多少量化提升这三条能讲透答辩就成功了八成。剩下两成看提问环节你能不能沉住气遇到暂时答不上来的问题就说“您提的这个问题非常有价值我在数据增强部分确实没有做这方面的全面对比这也是后续工作可以深入的方向”优雅地承认边界并展示思考方向比硬着头皮编答案要稳得多。8. 写在最后的实操心得整个项目从确定题目到交论文我大概用了两个半月。最大的体会是这类视觉毕设能不能做好根本不在于你会不会写模型而在于是不是有耐心把数据、标注、预处理、调参数这些看起来“不够酷”的环节做扎实。我第一版模型效果稀烂问题不是模型选得不好而是训练数据里有一类鱼的样本只有三十张怎么调都救不回来后来老老实实补数据加增强mAP就上去了。还有一个非常实际的建议每一轮训练结果都要记录包括超参配置、数据集版本、预处理方式、mAP、loss曲线文件名。我当时是用一个简单的Markdown表格记录的后来写论文的时候实验数据直接可以从表格里搬不用再去回忆。很多人忽视这个习惯到了论文阶段才发现“之前那个最好的模型是用什么参数跑的”已经记不清了那种痛苦我经历过一次不想你也经历。最后再说一个小技巧系统里保留一条测试脚本输入一张新图片就能跑完整训练和推理链路并把结果自动保存到指定目录。答辩前老师如果想看现场演示你不需要在摄像头前手忙脚乱地配置环境直接跑这条脚本几十秒内就能出一个带框的结果图。这个小工具不写进论文都行但它是你所有工作成果的“总开关”有了它你展示项目的时候永远是从容的。