精准提升:从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 组件已经开始尝试渲染图…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
