精准提升:从94.5%到99.4%——目标检测调优全纪录
🚀 目标检测模型调优过程记录
在进行目标检测模型的训练过程中,我们面对了许多挑战与迭代。从初始模型的训练结果到最终的调优优化,每一步的实验和调整都有其独特的思路和收获。本文记录了我在优化目标检测模型的过程中进行的几次尝试,并详细分析了每次调整带来的效果提升。🔧
一开始,我训练了一个目标检测器,目标检测任务包括了 26个类别,初始的 mAP50 在 94.5% 左右。尽管初步结果较为理想,但在混淆矩阵中仍然能看到一些类别之间存在较大的误识别和混淆,尤其是在类别间数据不平衡的情况下,部分小类别的识别效果较差。为了进一步提升模型性能,减少误识别,后续进行了几轮迭代和优化。

接下来的调优尝试,我采取了不同的策略,每次都根据前一次的分析结果,针对性地进行调整。以下是我尝试的几种方法,以及每次尝试的详细效果记录。📊
1️⃣ 第一次尝试:将目标检测拆解为单目标检测 + 图像分类
在最初的尝试中,我将原本的单一目标检测器拆解为单目标检测与图像分类的结合方式。具体可以参考我这篇文章:联合目标检测与图像分类提升数据不平衡场景下的准确率,方法的核心是将每个目标先单独识别,然后通过图像分类进一步确认类别。🎯
经过调整后,虽然 Top1的准确率 提高至 99%,但是从混淆矩阵来看,部分类别仍然存在较多的混淆,尤其是一些相似类别之间的错误识别仍然较为显著。🧐

2️⃣ 第二次尝试:统一缩放目标区域
在第一次尝试后,我发现将目标区域进行标准化处理可能会对模型训练有所帮助。因此,我采用了将目标检测出来的子图强制缩放至统一大小的策略。使用 cv2.resize(object_region, (classification_size, classification_size)) 对每个检测到的目标区域进行缩放。🔄
经过训练后,模型在一些类别上的识别效果有所改善,尤其是在一些小物体的检测上,误差略有减少。📉
3️⃣ 第三次尝试:统一缩放原始子图
在第二次尝试的基础上,我进一步扩大了缩放操作的范围,将原始图像中的所有子图按统一的缩放尺寸进行训练。这一操作提高了模型在不同尺度上的泛化能力,特别是对于不同尺寸的目标检测表现有所提升,训练过程中也能更好地对齐各类别的特征分布。📏
import os
from pathlib import Path
import cv2
from multiprocessing import Pool
from functools import partial
from tqdm import tqdmdef find_image_files(root_dir, image_extensions={'.jpg', '.jpeg', '.png', '.bmp', '.gif'}):"""递归查找根目录下所有图片文件"""root_path = Path(root_dir)image_files = [p for p in root_path.rglob('*') if p.suffix.lower() in image_extensions]return image_filesdef process_image(image_path, root_dir, output_dir, size=(224, 224)):"""处理单张图片:读取、调整大小、保存到目标目录"""try:# 计算相对路径并构造目标路径relative_path = image_path.relative_to(root_dir)target_path = Path(output_dir) / relative_path# 创建目标文件夹(如果不存在)target_path.parent.mkdir(parents=True, exist_ok=True)# 读取图像img = cv2.imread(str(image_path))if img is None:raise ValueError("图像无法读取,可能是文件损坏或格式不支持。")# 调整大小resized_img = cv2.resize(img, size)# 保存图像,保持原始格式success = cv2.imwrite(str(target_path), resized_img)if not success:raise IOError("图像保存失败。")except Exception as e:print(f"处理图片 {image_path} 时出错: {e}")def main():"""主函数:查找图片并使用多进程处理"""# 设置根目录和输出目录ROOT_DIR = "datasets/device_cls_merge_manual_with_21w_1218_train_val" # 替换为你的根目录路径OUTPUT_DIR = "datasets/device_cls_merge_manual_with_21w_1218_train_val_224" # 替换为你想保存的目标目录路径SIZE = (224, 224) # 调整后的图片大小NUM_PROCESSES = 16 # 使用的进程数# 查找所有图片文件image_files = find_image_files(ROOT_DIR)print(f"找到 {len(image_files)} 张图片。")if len(image_files) == 0:print("未找到任何图片文件,请检查根目录路径和图片格式。")return# 确保输出目录存在Path(OUTPUT_DIR).mkdir(parents=True, exist_ok=True)# 使用部分函数固定一些参数process_func = partial(process_image, root_dir=ROOT_DIR, output_dir=OUTPUT_DIR, size=SIZE)# 使用多进程处理图片,并显示进度条with Pool(processes=NUM_PROCESSES) as pool:list(tqdm(pool.imap_unordered(process_func, image_files), total=len(image_files)))print("所有图片处理完成!")if __name__ == "__main__":main()
4️⃣ 第四次尝试:引入额外数据
为了进一步提升模型的识别效果,我额外引入了一批新的数据,并使用已经训练好的模型打出类别及置信度分数,只保留置信度大于 0.9 的类别子图。这一策略显著提升了模型的准确性,特别是在一些模糊的检测任务中,置信度较高的预测结果帮助排除了很多误识别情况。📈
5️⃣ 第五次尝试:调整数据预处理和关闭自动增强
接下来,我调整了 YOLOv8 的预处理策略,并关闭了自动数据增强(auto_augment=False)。这一调整基于数据集的实际情况,考虑到某些预处理和数据增强方法可能会导致过拟合或过度处理,关闭自动增强后,模型在训练过程中更加专注于数据本身的特征,效果得到了明显的改善。💡
6️⃣ 第六次尝试:数据可视化与欠采样
最后,在进行数据可视化分析后,我发现部分类别的样本数过大,导致了模型训练时出现类别不平衡问题。因此,我对这些过多的类别进行了欠采样处理,减少了它们在训练中的占比,从而使得训练数据的分布更加均衡。📉
具体可以参考这篇文章:图像分类实用脚本:数据可视化与高数量类别截断,欠采样后,训练集中的数据分布更加合理,模型的鲁棒性也得到了提高。🔍
经过这些优化后,模型的表现有了显著提升。最终,mAP50 虽然略有提升至 99.4% 左右,但最重要的是,误识别率已经非常低,整体性能非常稳定。🎉

总结
通过这几轮的调优和实验,我在目标检测任务中取得了较为显著的进展。从最初的 94.5% 到最终的 99.4%,虽然提升幅度不算极其惊人,但每一轮的调整都有其明确的目的和成效,尤其是在类别不平衡、尺度差异、数据增强等方面的优化。最终,模型在实际测试中的误识别问题大幅度减少,几乎达到了理想状态。✨
在后续的工作中,我还将继续关注数据集的多样性与模型的泛化能力,进一步探索更多的调优方案。🔮
相关文章:
精准提升:从94.5%到99.4%——目标检测调优全纪录
🚀 目标检测模型调优过程记录 在进行目标检测模型的训练过程中,我们面对了许多挑战与迭代。从初始模型的训练结果到最终的调优优化,每一步的实验和调整都有其独特的思路和收获。本文记录了我在优化目标检测模型的过程中进行的几次尝试&#…...
【LLM论文日更】| 训练大型语言模型在连续潜在空间中进行推理
论文:https://arxiv.org/pdf/2412.06769代码:暂未开源机构 :Meta领域:思维链发表:arxiv 研究背景 研究问题:这篇文章要解决的问题是如何在大语言模型(LLMs)中实现一种新的推理范式&…...
智能家居实训室中,STC单片机驱动的“互联网+”智能家居系统设计
一、引言 随着经济的快速发展,人们对家居环境的智能化、网络化需求日益增强,智能家居的研究也因此受到了国内外相关机构的广泛关注。STC单片机凭借其卓越的性能和广泛的应用领域,成为了智能家居系统设计的优选方案。作为一种先进的微控制器&…...
《C++ 赋能强化学习:Q - learning 算法的实现之路》
在当今科技飞速发展的时代,人工智能无疑是最热门的领域之一,而强化学习作为其中的重要分支,正逐渐改变着我们解决复杂问题的方式。Q - learning 算法作为强化学习中的经典算法,在众多领域如游戏、机器人控制、资源管理等有着广泛的…...
三维模型中的UV展开是什么意思?它有什么优势?
UV展开涉及将三维模型的表面展开为一个或多个二维区域,以便将纹理图像正确地映射到模型上。这个过程类似于将一个立体物体的表面切割并平铺开来。UV坐标是用于在二维纹理图像中定位颜色和细节的坐标系统,U和V分别代表纹理图像的水平和垂直轴。 UV展开它…...
怎么在ubuntu系统上安装qt项目的打包工具linuxdeployqt
引言 安装linuxdeployqt方案一方案二 在ubuntu系统上开发的项目最后需要完成打包,qtcreator本身就用一个打包工具,在ubuntu系统上是linuxdeployqt。本文主要记录一下怎么在ubuntu系统上安装qt打包工具linuxdeployqt。 安装linuxdeployqt 前提是已经安装…...
SQL语句整理五-StarRocks
文章目录 查看版本号:SPLIT:insert 和 update 结合 select:报错:1064 - StarRocks planner use long time 3000 ms in memo phase:字段增删改: 查看版本号: select current_version(); current…...
【C#】try-catch-finally语句的执行顺序,以及在发生异常时的执行顺序
try-catch-finally语句 执行顺序 执行 try 块:程序首先尝试执行 try 块中的代码。如果在此期间没有发生异常,则跳过 catch 块,直接执行 finally 块(如果存在)。 发生异常时的处理: 如果在 try 块中发生了…...
【vue】vite + ts +vue3 安装pinia
vue3 TS 安装使用pinia状态管理_vue3 ts pinia-CSDN博客...
PointPillars:数据预处理
在 PointPillars 算法中,将点云划分为点柱(Pillars)是核心步骤之一,用于将稀疏点云数据转换为规则的张量表示,方便后续 2D 卷积操作。以下是点云划分为点柱的具体方法和实现步骤: 1. 点云划分为网格 将 3D…...
node.js的异步工作之---回调函数与回调地狱
回调函数:在 Node.js 中,很多 API 都是异步的,通常通过回调函数来处理操作完成后的结果。这种回调模式虽然非常高效,但会导致代码逐渐变得难以维护,尤其是当有多个异步操作嵌套时(即回调地狱)。…...
Mac Android studio 升级LadyBug 版本,所产生的bug
当Build 出现,这样的文字以后: Your build is currently configured to use incompatible Java 21.0.3 and Gradle 7.3.3. Cannot sync the project. We recommend upgrading to Gradle version 8.9. The minimum compatible Gradle version is 8.5. …...
stm32 hex文件烧写
STM32的HEX文件烧写是将编译后的程序代码(以HEX格式存储)下载到STM32单片机中的过程。以下是对STM32 HEX文件烧写的详细解释: 一、HEX文件简介 HEX文件,即Intel HEX文件,是一种由文本行组成的ASCII文件,每…...
【编译原理】编译原理知识点汇总·属性文法和语法制导翻译
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀编译原理_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …...
【unity c#】深入理解string,以及不同方式构造类与反射的性能测试(基于BenchmarkDotNet)
出这篇文章的主要一个原因就是ai回答的性能差异和实际测试完全不同,比如说是先获取构造函数再构造比Activator.CreateInstance(type)快,实际却相反 对测试结果的评价基于5.0,因为找不到unity6确切使用的net版本,根据c#9推测是net5…...
VSCode 插件开发实战(八):创建和管理任务 Task
前言 VSCode 的扩展能力使得开发者能够根据个人需求定制工作环境,自定义插件和任务管理是 VSCode 强大功能的一部分,通过这些功能,开发者可以自动化常见工作流,简化日常开发任务,提高整体开发效率。本文将详细介绍如何…...
在 Node.js 中正确处理 `async/await` 及数组迭代
在使用 Node.js 开发应用程序时,我们常常需要处理异步操作。例如,当我们从数据库获取数据、调用外部API或执行文件读取时,这些操作都可能需要一些时间才能完成。在这种情况下,我们通常会使用 async/await 语法来简化异步编程的复杂…...
本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——13使用Resnet-Bin
本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——13使用Resnet-Bin 根据前面的内容,目前已经可以获取到resnet的bin模型 1 .Resnet的bin测试 这里给大家一个测试视频里面黑线的demo,大家可以用来测试自己的黑线识别精度 …...
FFmpeg第三话:FFmpeg 视频解码详解
FFmpeg 探索之旅 一、FFmpeg 简介与环境搭建 二、FFmpeg 主要结构体剖析 三、FFmpeg 视频解码详解 FFmpeg第三话:FFmpeg 视频解码详解 FFmpeg 探索之旅前言一、视频解码基础二、FFmpeg 关键 API 深度剖析(一)avformat_open_input()ÿ…...
解决 vue3 中 echarts图表在el-dialog中显示问题
原因: 第一次点开不显示图表,第二次点开虽然显示图表,但是图表挤在一起,页面检查发现宽高只有100px,但是明明已经设置样式宽高100% 这可能是由于 el-dialog 还没有完全渲染完成,而你的 echarts 组件已经开始尝试渲染图…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
ubuntu清理垃圾
windows和ubuntu 双系统,ubuntu 150GB,开发用,基本不装太多软件。但是磁盘基本用完。 1、查看home目录 sudo du -h -d 1 $HOME | grep -v K 上面的命令查看$HOME一级目录大小,发现 .cache 有26GB,.local 有几个GB&am…...
