
简介这是一份面向计算机科学与技术等专业本科生的毕业论文参考文档主题为基于AC-YOLO的路面落叶检测方法适合正在准备目标检测方向毕业设计、需要完整论文框架与算法改进思路的同学。文档围绕YOLO算法的自适应聚类改进展开涵盖研究背景与意义、目标检测技术综述、AC-YOLO算法改进、数据集采集标注与预处理、网络模型与损失函数设计、实验设置与结果分析以及结论与展望等完整章节并针对路面落叶这类小目标检测场景给出了多尺度特征融合与数据增强方案。资源包共1个docx文件约33KB为完整一万字论文正文目录结构清晰便于按章节查阅与借鉴写作逻辑。目前已有321人学习下载可作为毕业论文选题、算法改进论证与实验章节撰写的实用参考资料。1. 路面落叶检测为什么值得单独做一个改进模型从 AC-YOLO 的注意力与卷积混合说起城市道路清扫车和环卫巡检车每天都要判断路面落叶的堆积程度决定是否加派清扫班次。这件事听起来简单真放到车载摄像头里跑实时检测问题就来了落叶颜色和沥青路面接近、形状随风吹散、密集时互相遮挡、雨后贴地反光通用 YOLO 直接拿来用漏检和误检都不少。AC-YOLO 这个方向核心思路是在 YOLO 检测头或主干里引入注意力机制Attention与卷积Convolution的混合结构让模型对落叶这种低对比度、非刚性、密集小目标更敏感。这篇面向本科毕业论文一万字体量的实战笔记讲的是怎么把 AC-YOLO 从概念落到能跑通训练、能出对比实验、能写进论文的完整路径。适合正在做目标检测方向毕设、需要一份可复现改进方案的同学也适合想把 YOLO 用到市政巡检场景的工程师。下面按数据、模型改造、训练调参、避坑、论文级验证五块展开每一步都给到能直接抄的命令和参数。2. 数据准备与落叶数据集构建从采集到 YOLO 格式的完整链路2.1 落叶检测的数据从哪来为什么不能直接用公开数据集路面落叶检测没有现成的标准大规模数据集这是做这个题目第一个要面对的现实。常见做法有三条路一是自己用手机或行车记录仪在不同路段、不同天气下拍摄视频抽帧成图二是从公开的垃圾检测、道路异物检测数据集里筛选含落叶的类别三是用数据增强合成落叶贴图。我一般会以自采为主因为落叶的形态、颜色、堆积密度跟本地树种和季节强相关公开数据集里的落叶跟你要检测的场景分布差太远直接训出来的模型换个城市就翻车。自采时要注意几个硬指标拍摄高度尽量模拟车载摄像头离地 1.2 到 1.5 米覆盖晴天、阴天、雨后三种光照每类场景至少 200 张有效图落叶密集、稀疏、单叶、成堆四种形态都要有。视频抽帧别按固定间隔抽相邻帧太像会导致训练集和验证集泄漏建议按场景分段每段只抽 3 到 5 帧。2.2 标注规范与 YOLO 格式转换脚本标注用 LabelImg 或 X-AnyLabeling 都行导出 VOC 格式的 XML再转成 YOLO 的 txt。落叶这种目标边界模糊标注时统一规则很重要单叶按可见轮廓框成堆落叶按整堆外接矩形框被遮挡超过 70% 的不标。下面这个转换脚本处理 VOC 到 YOLO 的坐标归一化同时做一轮尺寸过滤。import os import xml.etree.ElementTree as ET # 类别映射落叶场景一般就一类多类时按需扩展 CLASSES [fallen_leaf] # 过滤掉宽或高小于 8 像素的框落叶小目标太多会拖累训练 MIN_SIZE 8 def convert_voc_to_yolo(xml_dir, out_dir, img_w, img_h): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in CLASSES: continue cls_id CLASSES.index(cls_name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) w xmax - xmin h ymax - ymin if w MIN_SIZE or h MIN_SIZE: continue # YOLO 格式类别 中心x 中心y 宽 高全部归一化到 0-1 cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h nw w / img_w nh h / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}) out_path os.path.join(out_dir, xml_file.replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) if __name__ __main__: convert_voc_to_yolo(./annotations, ./labels, 1920, 1080)这段代码的关键参数是MIN_SIZE和img_w/img_h。MIN_SIZE设太小会把标注噪声当正样本设太大会丢掉远处的小落叶8 像素是 1080p 下的经验值。img_w和img_h必须和实际图片分辨率一致否则归一化坐标全错训练时 loss 会异常震荡。转换完一定要抽查几张用可视化脚本把框画回原图确认。2.3 数据集划分与增强策略划分比例按 8:1:1 走训练、验证、测试。落叶检测的增强不要无脑上翻转和亮度调整安全Mosaic 和 MixUp 要慎用因为落叶成堆时 Mosaic 拼接会造出不符合物理规律的堆积形态模型学到假特征。我一般只开水平翻转、随机亮度、轻微高斯噪声Mosaic 概率压到 0.3 以下。数据量少于 1500 张时可以用离线增强把训练集扩到 3000 张左右但验证集和测试集必须保持原始分布不能增强。3. AC-YOLO 模型改造注意力与卷积怎么嵌进 YOLO 才不掉点3.1 为什么是注意力加卷积而不是纯 Transformer纯 Transformer 检测器在小数据集上容易过拟合落叶这种场景样本量通常就几千张直接上纯注意力结构训练 loss 降得好看验证集 mAP 却上不去。AC-YOLO 的思路是保留 YOLO 的卷积主干做特征提取在 Neck 和检测头之间插入注意力模块让模型在通道和空间两个维度上重新加权特征。卷积负责局部纹理和边缘注意力负责长距离依赖和密集目标间的区分两者互补。这个组合在雾天、逆光这类低对比度场景下提升最明显因为注意力能把被压制的小目标响应拉回来。3.2 注意力模块的插入位置与代码实现插入位置有三个候选主干末端、Neck 的 PAN 结构里、检测头前。我的经验是插在 Neck 的每个上采样融合之后也就是 P3、P4、P5 三个尺度各加一个轻量注意力模块参数量增加控制在 5% 以内。下面是一个通道加空间的混合注意力实现可以直接嵌进 YOLOv5 或 YOLOv8 的 Neck 代码里。import torch import torch.nn as nn class ChannelAttention(nn.Module): def __init__(self, channels, reduction16): super().__init__() # 全局平均池化和最大池化并行比只用平均池化更稳 self.avg_pool nn.AdaptiveAvgPool2d(1) self.max_pool nn.AdaptiveMaxPool2d(1) self.fc nn.Sequential( nn.Conv2d(channels, channels // reduction, 1, biasFalse), nn.ReLU(inplaceTrue), nn.Conv2d(channels // reduction, channels, 1, biasFalse) ) self.sigmoid nn.Sigmoid() def forward(self, x): avg_out self.fc(self.avg_pool(x)) max_out self.fc(self.max_pool(x)) return x * self.sigmoid(avg_out max_out) class SpatialAttention(nn.Module): def __init__(self, kernel_size7): super().__init__() # 沿通道维做平均和最大拼成 2 通道再卷积 self.conv nn.Conv2d(2, 1, kernel_size, paddingkernel_size // 2, biasFalse) self.sigmoid nn.Sigmoid() def forward(self, x): avg_out torch.mean(x, dim1, keepdimTrue) max_out, _ torch.max(x, dim1, keepdimTrue) concat torch.cat([avg_out, max_out], dim1) return x * self.sigmoid(self.conv(concat)) class ACBlock(nn.Module): def __init__(self, channels): super().__init__() self.ca ChannelAttention(channels) self.sa SpatialAttention() def forward(self, x): x self.ca(x) x self.sa(x) return xreduction16是通道注意力的压缩比通道数小于 64 时改成 8否则中间层太窄会丢信息。kernel_size7是空间注意力的卷积核落叶这种不规则形状用 7 比 3 的感受野更合适。ACBlock 先通道后空间顺序不要反反了在密集落叶场景下空间注意力会先被背景主导。把 ACBlock 接到 Neck 的每个 C3 或 C2f 模块后面改完用model.info()看参数量和 GFLOPs涨幅超过 10% 就要考虑减层。3.3 损失函数与正负样本分配落叶检测的正负样本极不均衡背景占绝大多数。YOLOv8 默认的 TaskAlignedAssigner 已经比早期版本好很多但落叶密集时仍会出现正样本被背景淹没。我一般会把分类损失的权重适当调高或者在损失里加一个针对小目标的加权项。具体做法是在loss.py里对分类分支的 BCE 损失按目标面积做加权面积越小权重越大上限设 3 倍避免小目标权重失控。这个改动对 mAP 的提升通常在 1 到 2 个点但会让训练前期 loss 波动变大属于正常现象。4. 训练调参与环境配置让 AC-YOLO 在单卡上跑稳4.1 环境搭建与依赖版本环境这块血泪经验最多。CUDA、PyTorch、ultralytics 三者版本必须对齐否则训练中途 BN 崩溃或者 loss 变 NaN 是常事。我一般用 conda 建独立环境PyTorch 选 2.0 以上ultralytics 用 8.x 系列。下面这套命令在单卡 V100 和 3090 上都验证过。conda create -n acyolo python3.10 -y conda activate acyolo # 按 CUDA 版本装 PyTorch这里以 CUDA 11.8 为例 pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.1.0 pip install opencv-python matplotlib seaborn装完先跑python -c import torch; print(torch.cuda.is_available())确认 GPU 可用。如果返回 False八成是 CUDA 版本和 PyTorch 不匹配别急着改代码先把环境理顺。4.2 训练命令与关键参数设置训练用 ultralytics 的 CLI 或 Python API 都行我习惯写 Python 脚本方便记录参数。下面是一个针对落叶数据集的训练配置。from ultralytics import YOLO # 加载预训练权重小数据集必须用预训练从零训基本没戏 model YOLO(yolov8s.pt) # 替换 Neck 中的模块为 ACBlock这一步在自定义模型 yaml 里完成 model YOLO(ac_yolov8s.yaml).load(yolov8s.pt) results model.train( dataleaf.yaml, # 数据集配置指向 train/val 路径和类别 epochs200, imgsz640, batch16, # 显存 12G 以上可上 168G 用 8 lr00.01, # 初始学习率预训练微调用 0.01 足够 lrf0.01, # 最终学习率系数余弦退火到 lr0*lrf momentum0.937, weight_decay0.0005, warmup_epochs3.0, # 前 3 轮预热防止初期梯度爆炸 mosaic0.3, # 落叶场景压低 Mosaic 概率 fliplr0.5, hsv_v0.4, # 亮度增强幅度模拟不同光照 patience30, # 30 轮无提升就早停 device0, projectruns/leaf, nameac_yolov8s_exp1 )lr00.01是预训练微调的稳妥值从零训才用 0.1 量级。warmup_epochs3对加了注意力模块的模型尤其重要注意力层初始权重随机没有预热容易在头几轮把主干带偏。patience30配合 200 轮上限实际有效训练通常在 120 到 150 轮。batch16在 640 分辨率下大约占 10G 显存显存不够就降 batch 并等比调小学习率。4.3 训练过程监控与指标解读训练时重点盯三个东西loss 曲线、mAP50、混淆矩阵。loss 正常是前期快速下降后缓慢收敛如果分类 loss 一直高位不降检查标注里是不是有大量空 txt 或者类别 id 写错。mAP50 在落叶数据集上基线 YOLOv8s 大概能到 0.75 到 0.82加了 ACBlock 后目标提升 2 到 4 个点如果反而掉了先查注意力模块插入位置是不是在检测头之后那样会破坏原始特征。混淆矩阵里如果背景被大量误判为落叶说明正负样本分配或置信度阈值需要调不是模型结构问题。5. 避坑与排查AC-YOLO 训练中最容易翻车的五个点5.1 现象训练到一半 loss 突然变 NaNBN 层报错原因通常是学习率过大或 batch 太小导致 BN 统计量不稳定加了注意力模块后梯度路径变长这个问题更容易触发。解决方法是把lr0降到 0.005batch提到 16 以上或者在注意力模块后加一层 GroupNorm 替代 BN。如果已经 NaN从上一个正常 epoch 的权重恢复别从头训。5.2 现象验证集 mAP 比基线还低但训练 loss 正常原因多半是注意力模块插入位置不对或者参数量增加后过拟合。先确认 ACBlock 是插在 Neck 融合之后而不是检测头之后再把weight_decay从 0.0005 提到 0.001并开大dropout如果模型支持。数据量少于 1000 张时注意力模块的通道压缩比从 16 改成 8减少参数量。5.3 现象小目标落叶大量漏检大堆落叶检测正常原因是 P3 小尺度特征图上的注意力权重被背景压制。解决方法是单独对 P3 分支的 ACBlock 调大空间注意力核到 9或者在损失里对小目标加权。另一个检查点是输入分辨率640 对远处小落叶不够可以试 800 或 960但显存和速度要重新评估。5.4 现象混淆矩阵总和与验证集样本数对不上这是 ultralytics 版本差异导致的统计口径问题不是模型 bug。不同版本对置信度阈值和 NMS 的处理不同混淆矩阵的行列和可能不等于图片总数。解决办法是固定一个版本论文里写清楚用的 ultralytics 版本号对比实验全部在同一版本下跑别混用。5.5 现象推理速度比基线慢很多达不到实时注意力模块带来的计算量增加是主因。先看 GFLOPs 涨幅超过 15% 就要精简把三个尺度的 ACBlock 减到只在 P3 和 P4 加P5 不加或者把通道注意力换成更轻的 ECA 结构。实测在 3090 上YOLOv8s 加三个 ACBlock 后 FPS 从 120 降到 85 左右仍然满足车载实时要求但如果你的部署平台是边缘设备这个降幅要提前评估。6. 论文级验证与消融实验把 AC-YOLO 的改进讲成可复现的结论6.1 消融实验怎么设计才有说服力本科毕业论文的消融实验不需要太复杂但必须干净。基线用原始 YOLOv8s实验组依次是只加通道注意力、只加空间注意力、通道加空间都加、再加损失加权。四组在同一个数据集、同一套超参下跑只改模型结构。每组跑三个随机种子取平均报告 mAP50、mAP50-95、参数量、FPS 四个指标。表格里把提升幅度标出来提升小于 0.5 个点的组别要说明原因不能只报好看的数字。实验组通道注意力空间注意力损失加权mAP50参数量(M)FPS基线否否否0.78211.2120A是否否0.80111.6102B否是否0.79511.5108C是是否0.81411.985D是是是0.82611.985这张表是论文里最有价值的部分它把每个模块的贡献拆开了。注意 FPS 的测试条件要写清楚显卡型号、batch size、是否开半精度。不同条件下 FPS 差很多不写清楚审阅老师会追问。6.2 可视化验证热力图和检测结果对比光有数字不够论文里放两组图一组是基线模型和 AC-YOLO 在同一张密集落叶图上的检测结果对比另一组是注意力热力图。热力图用 Grad-CAM 生成看模型关注区域是不是更集中在落叶上而不是路面纹理。生成热力图的代码可以直接用 pytorch-grad-cam 库指定目标层为最后一个 ACBlock跑几张典型场景图就行。这一步能直观说明注意力机制确实起了作用比单纯堆指标更有说服力。6.3 我踩过的论文写作坑最后一个具体技巧论文里的实验数据一定要和代码、日志对得上。我见过太多人表格里的数字是手填的跟实际跑出来的差一点答辩时被问到就说不清。我的习惯是训练脚本自动把 results.csv 存下来写论文时用脚本从 csv 里读指标生成表格保证数字来源可追溯。另外AC-YOLO 这个名字在论文里第一次出现时要给出完整定义说明 A 和 C 分别指什么别让审阅老师猜。改进点要写成「在 Neck 的 P3/P4/P5 融合后插入通道与空间混合注意力模块」而不是「加了注意力」具体到层和位置才显得是真正做过。希望帮到你。本文还有配套的精品资源点击获取