多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

基于AC-YOLO的路面落叶检测:从论文到复现的完整指南

基于AC-YOLO的路面落叶检测:从论文到复现的完整指南 简介这是一份面向计算机科学与技术专业本科生的毕业设计参考资料主题为基于AC-YOLO的路面落叶检测方法适合正在准备目标检测方向毕业论文或需要小目标检测案例的学生参考。压缩包内仅含1个docx文档约33KB即完整的一万字论文正文涵盖引言、AC-YOLO算法介绍、数据集构建、检测方法设计、实验与分析及结论展望六大章节。论文系统梳理了YOLO算法原理与AC-YOLO的自适应聚类改进思路详细说明了无人机或车载摄像头采集、人工标注、图像归一化与光照校正等数据预处理流程并给出多尺度特征融合、数据增强与损失函数设计的具体方案实验部分还对比了AC-YOLO与其他目标检测方法的精度与速度表现。目前已有321人学习下载可为读者提供从选题背景到实验验证的完整写作框架与算法改进参考。1. 从一份本科毕业论文拆起AC-YOLO 路面落叶检测到底能跑通什么每年秋天市政环卫和智能交通团队都会碰到同一个问题路面积叶到底怎么快速定位。人工巡查效率低传统图像处理方案一遇到逆光、阴影、湿滑路面就翻车。这份《基于 AC-YOLO 的路面落叶检测方法》本科毕业论文恰好把从数据集构建、网络改进到实验对比的完整链路写进了一万字里适合正在做目标检测课程设计、毕业设计或者想找一个「小目标 复杂背景」练手项目的从业者。它不是一份能直接上路的工程代码而是一份结构完整、章节齐全的方法论文能帮你把 AC-YOLO 这条改进路线从概念落到实验表格。下面我按自己拆论文的习惯把这份资源里真正能复现的部分逐章拆开。2. AC-YOLO 的改进逻辑注意力机制到底加在哪一层2.1 从 YOLO 到 AC-YOLO 的改动路径论文第二章把 AC-YOLO 定位成 YOLO 的改进版本核心动作有两个一是引入注意力机制二是做多尺度特征融合。原文里提到的注意力模块用的是 SESqueeze-and-Excitation块作用是对通道做重标定——先全局池化拿到每个通道的统计量再通过两个全连接层学出一组权重最后乘回原特征图。这一步在路面落叶场景里很关键因为落叶颜色和路面灰度接近通道注意力能把「叶片纹理」这类判别性强的通道拉高把「路面底色」这类干扰通道压低。多尺度动态融合则是为了解决落叶尺寸跨度大的问题。近处的落叶可能占几百像素远处的只有十几个像素。论文里提到的做法是在不同尺度上提取特征后再融合常见实现是接一个类似 FPN 的结构把深层语义特征和浅层细节特征做横向连接。这里要注意论文原文对融合方式描述比较笼统没有给出具体的特征图层级和通道数复现时需要自己定。2.2 网络结构的关键参数怎么定论文第四章提到以 YOLOv3 作为基础架构调整输入尺寸以适应细小特征同时把输出层类别数改成只包含落叶一类。这里给出一个可参考的配置思路# AC-YOLO 网络关键参数配置参考论文第四章描述 # 输入尺寸论文强调适应细小特征常见做法是放大到 608 或 640 input_size 640 # 类别数论文明确只检测落叶所以 num_classes 1 num_classes 1 # 锚框YOLOv3 默认 9 个锚框落叶偏小目标需要重新聚类 # 常见做法是用 k-means 在自己的数据集上重新生成 anchors [ (10, 13), (16, 30), (33, 23), # 小尺度对应远处落叶 (30, 61), (62, 45), (59, 119), # 中尺度 (116, 90), (156, 198), (373, 326) # 大尺度对应近处大片落叶 ] # SE 模块的 reduction ratio论文未给出常见取值 16 se_reduction 16逻辑说明输入尺寸放大是为了让远处的小落叶在特征图上保留更多像素信息这是小目标检测的常规操作。类别数设为 1 是因为论文只做落叶单类检测不需要多分类头。锚框重新聚类是必须的——YOLOv3 默认锚框是在 COCO 上聚出来的直接拿来检测落叶小目标召回率会明显偏低。SE 模块的 reduction ratio 控制通道压缩程度取值越小注意力越精细但参数量越大16 是一个比较稳的起点。参数说明input_size 如果显存不够可以降到 416但小目标性能会掉anchors 建议用标注好的数据集跑一遍 k-means论文里没有给出具体聚类结果这一步不能省。2.3 损失函数的设计取舍论文第四章第三节提到损失函数设计考虑了定位和分类的平衡。YOLOv3 原生损失由三部分组成边界框回归损失、置信度损失、分类损失。对于落叶检测定位精度比分类精度更重要因为只有一类分类本身不难。常见做法是把边界框回归的权重调高或者把 CIOU 替换原始的 MSE 回归。论文没有明确说用了哪种但从「定位和分类平衡」这个描述看大概率是对不同损失项做了加权。# 损失函数权重配置参考论文第四章第三节思路 # 落叶检测只有一类分类损失权重可以压低 lambda_box 5.0 # 边界框回归损失权重定位优先 lambda_cls 0.5 # 分类损失权重单类任务不需要太高 lambda_obj 1.0 # 置信度损失权重保持默认 # 如果用小目标检测建议开启 CIOU # 相比原始 MSECIOU 对尺度变化更鲁棒 use_ciou True逻辑说明lambda_box 调高是因为落叶检测的核心难点在「框得准不准」而不是「是不是落叶」。lambda_cls 压低是因为单类任务的分类边界很简单给太高反而会让模型在分类头上过拟合。CIOU 相比原始回归损失多了中心点距离和宽高比的一致性约束对小目标的框回归更友好。参数说明这三个权重没有绝对标准论文也没给出具体数值建议先用上面这组跑 baseline再根据验证集上的 mAP 和定位误差做微调。如果发现漏检多优先调高 lambda_obj如果框不准优先调高 lambda_box。3. 数据集构建与预处理从采集到标注的完整链路3.1 数据采集的三种来源与标注策略论文第三章把数据采集分成手动采集和数据库获取两条路。手动采集就是在不同天气、不同路况下拍路面照片数据库获取则是找公开数据集或商用库。对于本科论文级别的项目我一般建议混合来先用手动采集保证场景覆盖再用公开数据补充样本量。标注方法论文给了两种边界框标注和像素级标注。边界框标注就是拉矩形框适合大多数情况像素级标注是逐像素分割适合落叶和路面颜色接近、边界模糊的场景。实际操作中像素级标注工作量太大本科论文级别用边界框就够了。论文还提到多人标注和定期检查这是保证标注一致性的常规手段。# 标注文件格式YOLO 标准格式每行一个目标 # 格式class_id x_center y_center width height全部归一化到 0-1 # 落叶只有一类class_id 固定为 0 # 示例一张 640x480 的图里有两个落叶 # 第一个落叶中心点在 (320, 240)宽 80 高 60 # 第二个落叶中心点在 (100, 400)宽 40 高 30 0 0.500 0.500 0.125 0.125 0 0.156 0.833 0.063 0.063逻辑说明YOLO 格式用归一化坐标好处是跟输入尺寸解耦训练时不管怎么 resize 都不用改标注。x_center 和 y_center 是目标中心点相对整图宽高的比例width 和 height 是目标框相对整图宽高的比例。这里容易翻车的地方是有些标注工具导出的是左上角右下角绝对坐标需要自己写脚本转成 YOLO 格式。参数说明class_id 从 0 开始单类任务全是 0。归一化时注意分母是图像原始宽高不是 resize 后的尺寸。如果标注时用的是绝对坐标转换公式是x_center (x_min x_max) / 2 / img_w其余同理。3.2 数据预处理的四个步骤论文第三章第二节把预处理拆成去噪、尺度统一、图像增强、数据标注四步。去噪常用中值滤波或高斯滤波路面图像里高斯噪声多高斯滤波更合适。尺度统一就是 resize 到网络输入尺寸常见做法是直接 resize 或者 letterbox 填充。图像增强包括对比度增强、直方图均衡化目的是让落叶在不同光照下都清晰可见。import cv2 import numpy as np def preprocess_road_image(img_path, target_size640): 路面落叶图像预处理流水线 img cv2.imread(img_path) # 第一步高斯滤波去噪kernel 大小根据噪声程度调 # 3x3 适合轻度噪声5x5 适合重度噪声 img cv2.GaussianBlur(img, (3, 3), 0) # 第二步letterbox 缩放保持宽高比不足部分填灰 h, w img.shape[:2] scale min(target_size / w, target_size / h) new_w, new_h int(w * scale), int(h * scale) img_resized cv2.resize(img, (new_w, new_h)) # 创建目标尺寸画布填充值 114 是 YOLO 系列常用灰度 canvas np.full((target_size, target_size, 3), 114, dtypenp.uint8) # 居中放置 top (target_size - new_h) // 2 left (target_size - new_w) // 2 canvas[top:topnew_h, left:leftnew_w] img_resized # 第三步直方图均衡化在 YUV 空间的 Y 通道上做 # 直接对 RGB 做会偏色这是血泪经验 img_yuv cv2.cvtColor(canvas, cv2.COLOR_BGR2YUV) img_yuv[:, :, 0] cv2.equalizeHist(img_yuv[:, :, 0]) canvas cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR) return canvas逻辑说明高斯滤波放在最前面先去掉传感器噪声再缩放避免噪声被放大。letterbox 而不是直接 resize是为了保持宽高比防止落叶被拉变形——变形后的目标会让锚框匹配出问题。直方图均衡化在 YUV 的 Y 通道上做只增强亮度对比度不影响色度这样落叶的黄色和路面的灰色对比会更明显。参数说明target_size 跟网络输入尺寸保持一致用 640 就传 640。高斯核大小根据实际图像噪声调可以先跑几张看效果。填充值 114 是 YOLO 官方实现里的默认值换成 0 也可以但 114 在可视化时更容易区分填充区域和真实图像。3.3 数据增强的实操参数论文第四章第二节提到用旋转、缩放、翻转扩充样本。对于落叶检测翻转和旋转是最有效的因为落叶在路面上的方向是随机的。缩放要注意放大太多会让小落叶变成大目标跟实际场景不符。# 数据增强配置参考论文第四章第二节 augment_config { hflip: 0.5, # 水平翻转概率落叶没有方向性可以高 vflip: 0.0, # 垂直翻转概率路面场景垂直翻转不自然关掉 rotate: 15, # 旋转角度范围 ±15 度太大不真实 scale: (0.8, 1.2), # 缩放范围控制在 0.8-1.2 之间 mosaic: 0.5, # Mosaic 增强概率YOLOv3 之后的标准操作 hsv_h: 0.015, # 色调扰动模拟不同光照 hsv_s: 0.7, # 饱和度扰动 hsv_v: 0.4, # 亮度扰动 }逻辑说明水平翻转概率给 0.5 是因为落叶没有固定方向翻转后仍然是合理的落叶形态。垂直翻转关掉是因为路面场景里天空在上、路面在下垂直翻转会产生不自然的图像。旋转角度控制在 ±15 度太大就跟真实拍摄角度不符。Mosaic 增强把四张图拼成一张能显著提升小目标检测性能这是 YOLO 系列的标配。HSV 扰动模拟不同天气和光照条件对路面场景很重要。参数说明hsv_h 控制色调偏移范围0.015 对应约 ±2.7 度hsv_s 和 hsv_v 是饱和度和亮度的缩放系数。这些值在 YOLOv5 的默认配置里被广泛验证过可以直接用。如果数据集本身光照变化就很丰富可以把 hsv_v 调低一点。4. 训练配置与实验对比参数怎么设、结果怎么看4.1 训练超参数的设置逻辑论文第五章实验设置部分提到了硬件配置和训练参数但原文没有给出完整数值。根据论文描述和常见实践这里给出一组可复现的配置# 训练超参数配置参考论文第五章实验设置 train_config { epochs: 300, # 总训练轮数小数据集可以适当减少 batch_size: 16, # 批大小显存不够就降到 8 learning_rate: 0.001, # 初始学习率YOLO 系列常用 1e-3 lr_scheduler: cosine, # 余弦退火比 step 更平滑 warmup_epochs: 5, # 预热轮数防止初期梯度爆炸 weight_decay: 0.0005, # 权重衰减防过拟合 momentum: 0.937, # SGD 动量YOLO 系列默认值 optimizer: SGD, # 论文未指定SGD 在检测任务上更稳 }逻辑说明epochs 给 300 是因为目标检测任务通常需要较长训练周期但如果数据集只有几千张100-150 轮也能收敛。batch_size 受显存限制16 是一个比较通用的值。学习率用余弦退火而不是阶梯下降是因为余弦退火在训练后期学习率更小模型更容易收敛到平坦极小值。warmup 是 YOLO 系列的标准操作前几轮用很小的学习率让模型先稳定下来。参数说明weight_decay 和 momentum 用的是 YOLOv5 的默认值这两个值在检测任务上被广泛验证过。如果训练 loss 震荡严重优先降学习率如果验证集 mAP 早早饱和优先加数据增强而不是加 epoch。4.2 评估指标与对比方法论文第五章用准确率和速度作为主要评估指标并跟几种流行目标检测算法做了对比。目标检测的标准指标是 mAPmean Average Precision通常看 mAP0.5 和 mAP0.5:0.95 两个值。速度指标用 FPS 或单张推理时间。指标含义论文中的关注点mAP0.5IoU 阈值 0.5 时的平均精度衡量检测准确性mAP0.5:0.95IoU 从 0.5 到 0.95 的平均衡量定位精度FPS每秒处理帧数衡量实时性Precision查准率误检多不多Recall查全率漏检多不多逻辑说明mAP0.5 看的是「框得差不多对」的情况mAP0.5:0.95 看的是「框得很准」的情况。落叶检测里如果只是提醒环卫工人哪里有落叶mAP0.5 够用如果要精确估计落叶面积就得看 mAP0.5:0.95。Precision 和 Recall 要一起看单看一个容易被误导——把阈值调高 Precision 会涨但 Recall 会掉。参数说明对比方法论文里提到了几种流行算法常见对比对象包括 YOLOv3、YOLOv4、Faster R-CNN、SSD。对比时要注意用相同的输入尺寸和训练轮数否则不公平。论文里如果只给了 mAP 没给 FPS那实时性结论就要打折扣。4.3 结果分析里容易忽略的细节论文第五章第三节的结果分析部分通常会放混淆矩阵、PR 曲线和可视化检测结果。混淆矩阵在单类任务里看起来很简单但有个坑如果背景被误检为落叶混淆矩阵上不会直接体现需要看 FP假正例的数量。PR 曲线看的是不同置信度阈值下的 Precision 和 Recall 权衡曲线下的面积就是 AP。可视化结果要重点看三类图漏检的、误检的、框不准的。漏检多说明 Recall 不够可能是锚框不匹配或者置信度阈值太高误检多说明 Precision 不够可能是背景样本太少或者分类头过拟合框不准说明回归损失权重不够或者 CIOU 没开。5. 避坑与常见问题复现时最容易翻车的五个点5.1 锚框不重新聚类小目标召回率直接崩现象训练 loss 正常下降但验证集上远处小落叶几乎检测不到mAP 比预期低十几个点。原因直接用了 YOLOv3 在 COCO 上的默认锚框那组锚框是为通用目标设计的最小锚框是 (10,13)对于只有十几像素的落叶来说还是太大匹配不上。解决用自己标注的数据集跑一遍 k-means聚类出 9 个锚框。常见做法是统计所有标注框的宽高用 IoU 作为距离度量做聚类。聚类完把锚框按面积从小到大排序分别分配给三个检测尺度。5.2 数据增强过度模型学不到真实分布现象训练集 loss 很低验证集 loss 很高mAP 上不去典型过拟合。原因旋转角度给太大、缩放范围太宽导致增强后的图像跟真实路面场景差距太大。模型在增强数据上过拟合到真实数据上就翻车。解决旋转控制在 ±15 度以内缩放控制在 0.8-1.2 之间垂直翻转直接关掉。Mosaic 增强概率不要给到 1.00.5 左右比较稳。HSV 扰动也要适度亮度扰动太大会让模型把光照变化当成目标特征。5.3 学习率设太大训练初期就发散现象训练前几个 epoch loss 直接变成 nan或者 loss 震荡非常剧烈。原因初始学习率给太大加上没有 warmup模型权重在初期被大幅更新梯度爆炸。解决加 warmup前 5 个 epoch 学习率从 1e-5 线性升到初始学习率。初始学习率从 1e-3 起步如果还发散就降到 1e-4。优化器用 SGD 比 Adam 更稳虽然收敛慢一点但不容易发散。5.4 标注格式转换出错训练时全部框错位现象训练 loss 一直很高降不下来可视化预测框全部偏移或者尺寸不对。原因标注工具导出的格式跟 YOLO 要求的格式不一致。常见的是导出绝对坐标没归一化或者导出的是左上角宽高而不是中心点宽高。解决写一个格式检查脚本随机抽几张图把标注框画出来看。归一化检查所有坐标值应该在 0-1 之间。中心点检查x_center 应该等于 (x_min x_max) / 2 / img_w。如果用的是 labelImg 之类的工具导出时选 YOLO 格式。5.5 验证集和训练集场景重叠指标虚高现象验证集 mAP 很高但实际部署到新场景上效果很差。原因训练集和验证集是从同一批图像里随机划分的同一段路、同一天的图像同时出现在训练集和验证集里。模型记住了场景特征而不是落叶特征。解决按场景划分比如不同路段、不同天气、不同时间的图像分开。如果数据量不够至少按拍摄批次划分同一批次只出现在训练集或验证集。这是学术论文里经常被忽略但工程上很致命的问题。6. 从论文到可运行项目我的复现习惯与验证技巧把这份论文变成能跑通的代码我一般会先做一件事把论文里的每个技术点映射到一个可验证的最小实验。比如 SE 模块先不加跑一个 YOLOv3 baseline记录 mAP再加上 SE其他不变再跑一次。两次结果的差值就是 SE 模块的贡献。这样做的目的是避免一次性把所有改进都堆上去最后不知道哪个模块在起作用。具体操作上我会建一个实验记录表每行是一次实验列包括实验编号、改动内容、mAP0.5、mAP0.5:0.95、FPS、备注。改动内容一次只写一个变量比如「加 SE 模块」「换 CIOU」「锚框重新聚类」。这样跑完五六次实验就能清楚知道每个改动的收益。# 实验记录表结构用 pandas 管理 import pandas as pd experiments pd.DataFrame([ {id: 1, change: YOLOv3 baseline, mAP_50: 0.72, mAP_50_95: 0.45, fps: 35}, {id: 2, change: SE 模块, mAP_50: 0.76, mAP_50_95: 0.48, fps: 33}, {id: 3, change: 锚框聚类, mAP_50: 0.79, mAP_50_95: 0.51, fps: 33}, {id: 4, change: CIOU, mAP_50: 0.81, mAP_50_95: 0.54, fps: 32}, ]) # 每次只改一个变量才能归因验证技巧方面我习惯在训练完成后做三件事。第一把验证集里 mAP 最低的十张图挑出来逐张看预测结果分析是漏检、误检还是框不准。第二用同一张图跑不同置信度阈值看 Precision-Recall 曲线怎么变确定部署时的最佳阈值。第三把模型放到一段没见过的视频上跑看帧间检测是否稳定有没有闪烁。还有一个容易被忽略的点论文里的实验结论是在特定数据集上得到的换一个城市、换一个季节性能可能会掉。所以复现时不要只盯着论文里的数字要自己构建一个小的测试集包含不同光照、不同落叶密度的场景用来验证模型的泛化能力。如果测试集上性能掉得厉害优先补数据而不是调模型。从那以后我每次复现目标检测论文都强制先跑 baseline 再逐模块加改进绝不一次性堆完。希望帮到你。本文还有配套的精品资源点击获取
返回列表