基于Matplotlib的模型性能可视化工作
一、项目简介
本项目是科技考古墓葬识别工作的中间过程,因为需要大量复用所以另起一章好了。
主要涉及到数据读取、数据可视化和少量的数据处理过程。
二、相关知识
- Pandas
- Matplotlib
三、实验过程
1. 数据探索性分析
1.1 准备工作–导入模块
import pandas as pd
import os
import numpy as np
import matplotlib.pyplot as plt
1.2 数据预处理
我们首先构建一个色彩映射表,这个表将由一组自定义的颜色条构成,并且对应一个索引值,以便我们按照强度
自定义生成绘图颜色。
可以在网址 上对你想要的颜色生成色度条。
colorMap=dict(zip(range(len(ModelMap),-1,-1),["#d16ba5","#c777b9", "#ba83ca", "#aa8fd8", "#9a9ae1", "#8aa7ec","#79b3f4","#69bff8","#52cffe","#41dfff", "#46eefa", "#5ffbf1"
]))
这个优势在于手动调整,不想怎么做可以使用各种可视化模块里自带的色彩映射cmap
。
然后就是将训练的模型信息输入到一个字典中,这里k,v值分别是模型名称、(模型参数量,模型平均精度)。
ModelMap={"YOLOv5-n":[1.9,0.7],"YOLOv5-s":[7.2,0.782],"YOLOv5-m":[21.2,0.777],"YOLOv5-l":[46.5,0.746],"YOLOv5-x":[86.7,0.768],"YOLOv8-n":[3.2,0.764],"YOLOv8-s":[11.2,0.813],"YOLOv8-m":[25.9,0.7],"YOLOv8-l":[43.7,0.7],"YOLOv8-x":[68.2,0.7]
}
我们想要将模型参数量从小到大排布,以便确定最优性能,那么可以使用sort
方法进行排序:
newSort=list(ModelMap.items())
newSort.sort(key=lambda x:x[1][1],reverse=True)
这里面的reverse=True
表示降序排序,这里等于是以模型的精度进行排序。注意lambda
表达式,:
前表示输入,后表示返回值。
结果应该如下所示。
[('YOLOv8-s', [11.2, 0.813]),('YOLOv5-s', [7.2, 0.782]),('YOLOv5-m', [21.2, 0.777]),('YOLOv5-x', [86.7, 0.768]),('YOLOv8-n', [3.2, 0.764]),('YOLOv5-l', [46.5, 0.746]),('YOLOv5-n', [1.9, 0.7]),('YOLOv8-m', [25.9, 0.7]),('YOLOv8-l', [43.7, 0.7]),('YOLOv8-x', [68.2, 0.7])]
2. 可视化
为了更加直观的比较模型性能,我们选择采用二维散点图进行绘制。在此过程中,采用不同的颜色和尺寸可以让结果更加清晰直观。因此,我们选择了颜色和尺度两个额外维度,辅助可视化过程。
首先是获取尺度信息,这里采用的归一化缩放,为了让数据区间更加美观,选择采用np.clip(n,a,b)
方法将数据区间变成(a,b),并执行相应的放缩。
def getScale(x,k=9.5):return np.clip(((x-min(y))/(max(y)-min(y))),0.15,0.95)*k
2.1 绘制散点图
还记得我们之前构建的自定义色度条吗,现在我们将结合色度条和尺度信息来绘制散点图。
# 首先是设置好 Figure 大小
# 在matplotlib中,绘图将基于 figure canvas axis 进行
plt.figure(figsize=(16,8))for i,(k,v) in enumerate(newSort):# label 表示标签# s表示尺寸信息# c表示色彩信息# alpha表示透明度通道信息plt.scatter(v[0],v[1],c=colorMap[i],label=k,s=getScale(v[1])**2*np.pi,alpha=1)# 添加行列标签
plt.ylabel("AP")
plt.xlabel("Parameters (M)")# 在右上显示图例
plt.legend(loc='upper right')
# 设置标题
plt.title("AP-Params of different Model structures")# 设置 xaxis 范围
plt.xlim(0,120)
# 设置格网信息
plt.grid(alpha=0.1,linestyle="--")for i,j in zip(x,y):# 标记,用的是annotate 方法# plt.annotate(text,loc,xytext,textcoords,ha)# 常用参数 text表示文本信息 loc表示坐标点位置# xytext表示文本偏移量 textcoords表示文本以什么为坐标# ha表示文本显示位置,一般这组参数可以不动,即# xytext=(0,10),textcoords="offset points",ha='center'plt.annotate("%s"%j,(i,j),xytext=(0,10),textcoords="offset points",ha='center')
plt.savefig(r"new.jpg")plt.show()
此时图像如图所示,为了将同一类模型归类,我们还可以采用折线图进行辅助。
2.2 绘制折线图
for i,j in ModelMap.values():x.append(i)y.append(j)plt.plot(x[:5],y[:5],label="YOLO-v5",linestyle=':',alpha=0.5)
plt.plot(x[5:],y[5:],label="YOLO-v8",linestyle=':',alpha=0.5)
结果如图所示:
2.3 绘制模型过程性参数
在本阶段,我们需要做的需求为: 将训练过程中的精度、召回率以及mAP:0.5,mAP:0.5:0.95进行可视化。
可简要拆解为以下过程:
- 读取相关csv文件
- 构建文件映射,并且将每30epoch进行平均
- 基于matplotlib绘制
- 基于pyecharts进行绘制
为了方便读取csv文件,我们可以用os.listdir
方式快速获取某一路径下的所有子文件,这个方法常常结合寻找后缀来用,譬如:
[i for i in os.listdir(path) if i.endswith('.csv')]
这里我们有两个大文件夹,先获取其路径:
yolov5=r"C:\Users\Administrator\Desktop\Train_Res\YOLO_V5"
yolov8=r"C:\Users\Administrator\Desktop\Train_Res\YOLO_V8"
然后构建csv
文件列表:
data_list=[os.path.join(yolov5,i) for i in os.listdir(yolov5) if i.endswith('.csv')]+[os.path.join(yolov8,i) for i in os.listdir(yolov8) if i.endswith('.csv')]
与上述方法相同,当路径较多时,可写成迭代器形式。
接下来就是确定模型名称+csv文件了,用的是pd.read_csv
,这里如果出现中文,可能需要加上pd.read_csv(encoding="utf-8")
dataMap={}
for i in data_list:fir,sec=i.find("_V")+2,i.find(".c")-1dataMap[f"yolov{i[fir]}_{i[sec]}"]=pd.read_csv(i)
注意这样的写法不具有泛用性,甚至改个位置就会报错,但是确实很快
查看我们的结果:
dataMap.keys()# dict_keys(['yolov5_l', 'yolov5_m', 'yolov5_s', 'yolov5_x', 'yolov8_n', 'yolov8_s'])
已经拿到数据了,然后就是看看读取到的结果咋样:
dataMap['yolov5_x'].head()
成功。
下面来构造数据,由于有些模型采用了剪枝,在100epoches不收敛的情况下自动终止训练,所以数据的长度不一致。我们可以取其中最短的进行分析,不过这里用了360epoches。
请注意,确定你的模型在区间 U ( δ ) U(\delta) U(δ)内是陷入了局部最优解的,否则没有比较意义。
x=[i for i in range(0,360,15)]
# 获取列名
col=dataMap['yolov5_x'].columns
由于有多组参数需要比较,出于复用性考虑,我们采用函数的方式进行绘制:
def plotValue(idx,reset=None,ws=15):plt.figure(figsize=(20,8))for k,v in dataMap.items():v=v.iloc[:,idx]# 此时的平滑窗口是15plt.plot(x,[sum(v[i*ws:i*ws+ws])/ws for i in range(360//ws)],label=k)plt.xlabel("epoches")ylab=col[idx] if not reset else resetplt.ylabel(ylab)plt.title(f"{ylab} variation of different models")plt.legend()return plt
调整参数ws
即可获得在不同大小的滑动窗口下的平均值。reset
支持自己改名称,这都没啥
来看看结果:
plotValue(4,"Precision").show()
plotValue(5,"Recall").show()
plotValue(6,"mAP_0.5").show()
plotValue(7,"mAP_0.5:0.95").show()
看一个就好了。
相关文章:

基于Matplotlib的模型性能可视化工作
一、项目简介 本项目是科技考古墓葬识别工作的中间过程,因为需要大量复用所以另起一章好了。 主要涉及到数据读取、数据可视化和少量的数据处理过程。 二、相关知识 PandasMatplotlib 三、实验过程 1. 数据探索性分析 1.1 准备工作–导入模块 import pandas…...

KAN网络最全解析——比肩MLP和Transformer?
1 基本思路 1.1 MLP与Spline的优缺点 多层感知器 (MLP)是深度学习的基础理论模块,是目前可用于逼近非线性函数的默认模型,其表征能力已由通用逼近定理证明。但MLP也有明显的缺点,例如在 Transformer中,MLP 的参数量巨大…...

ASP.NET学生信息管理系统
摘 要 本文介绍了在ASP.net环境下采用“自上而下地总体规划,自下而上地应用开发”的策略开发一个管理信息系统的过程。通过分析某一学校学生管理的不足,创建了一套行之有效的计算机管理学生的方案。文章介绍了学生管理信息系统的系统分析部分,…...

图片改大小尺寸怎么改?几招教你搞定图片修改
在社交媒体平台上发布图片时,调整图片的尺寸大小可以确保图片适合平台的要求,不同的社交媒体平台可能对图片的尺寸有不同的要求,通过调整图片尺寸,可以更加完美的展现出来,那么有没有比较简单的图片改大小的方法呢&…...

Scala编程入门:从零开始的完整教程
目录 引言环境准备创建第一个Scala项目基本语法高阶概念进阶资源结语 引言 Scala是一种强大的、静态类型的、多范式编程语言,它结合了面向对象和函数式编程的特点。本教程将指导您如何从零开始学习Scala,并搭建一个简单的开发环境。让我们开始探索Scala…...

Proxmox VE 8 SDN创建VLAN隔离用户网络
作者:田逸(formyz) 在上一篇文章中,我们用SDN的Simple对租户(用户)网络实现了隔离功能,但它有个限制,仅仅能在单个物理节点上进行通信,而不能跨越物理节点(除…...

API低代码平台介绍3-异构数据源的数据查询功能
异构数据源的数据查询功能 在上一篇文章中我们通过API平台定义了一个最基本的数据查询接口,本篇文章我们将上升难度,在原有接口的基础上,实现在MySQL数据库和Oracle数据库同时进行数据查询。 什么场景会需要同时对异构数据源进行查询&…...

【Linux】-网络请求和下载、端口[6]
目录 一、网络请求和下载 1、ping命令 2、wget命令 3、curl命令 二、端口 1、虚拟端口 2、查看端口占用 一、网络请求和下载 1、ping命令 可以通过ping命令,检查指定的网络服务器是否可联通状态 语法:ping [ -c num ] ip或主机名 选项&…...

Github2024-05-10开日报 Top10
根据Github Trendings的统计,今日(2024-05-10统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4TypeScript项目4JavaScript项目1Lua项目1C项目1Rust项目1Dart项目1 RustDesk: 用Rust编写的开源远…...

2016-2021年全国范围的2.5m分辨率的建筑屋顶数据
一、论文介绍 摘要:大规模且多年的建筑屋顶面积(BRA)地图对于解决政策决策和可持续发展至关重要。此外,作为人类活动的细粒度指标,BRA可以为城市规划和能源模型提供帮助,为人类福祉带来好处。然而…...

Gitea 上传用户签名
在 Gitea 的用户管理部分,有一个 SSH 和 GPG 的选项。 单击这个选项,可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户,可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。 单击这个导出,…...

【原创】springboot+mysql物资库存管理系统设计与实现
个人主页:程序猿小小杨 个人简介:从事开发多年,Java、Php、Python、前端开发均有涉猎 博客内容:Java项目实战、项目演示、技术分享 文末有作者名片,希望和大家一起共同进步,你只管努力,剩下的交…...

vulnhub靶场之FunBox-5
一.环境搭建 1.靶场描述 Lets separate the script-kids from script-teenies.Hint: The first impression is not always the right one!If you need hints, call me on twitter: 0815R2d2 Have fun...This works better with VirtualBox rather than VMwareThis works bett…...

1分钟搞定Pandas DataFrame创建与索引
1.DataFrame介绍 DataFrame 是一个【表格型】的数据结构,可以看作是【由Series组成的字典】(共用同一个索引)。DataFrame 由按一定顺序排列的多列数据组成。设计初衷是将 Series 的使用场景从一维扩展到多维。DataFrame 既有行索引ÿ…...

【贪心算法】哈夫曼编码Python实现
文章目录 [toc]哈夫曼编码不同编码方式对比前缀码构造哈夫曼编码哈夫曼算法的正确性贪心选择性质证明 最优子结构性质证明 总结 Python实现时间复杂性 哈夫曼编码 哈夫曼编码是广泛用于数据文件压缩的十分有效的编码方法,其压缩率通常为 20 % 20\% 20%到 90 % 90\%…...

【RAG 博客】RAG 应用中的 Routing
Blog:Routing in RAG-Driven Applications ⭐⭐⭐⭐ 根据用户的查询意图,在 RAG 程序内部使用 “Routing the control flow” 可以帮助我们构建更实用强大的 RAG 程序。路由模块的关键实现就是一个 Router,它根据 user query 的查询意图&…...

鸿蒙ArkUI:【编程范式:命令式->声明式】
命令式 简单讲就是需要开发用代码一步一步进行布局,这个过程需要开发全程参与。 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 Objective-C ObjectiveC 复制代码 UIView *cardView …...

【练习2】
1.汽水瓶 ps:注意涉及多个输入,我就说怎么老不对,无语~ #include <cmath> #include <iostream> using namespace std;int main() {int n;int num,flag,kp,temp;while (cin>>n) {flag1;num0;temp0;kpn;while (flag1) {if(kp<2){if(…...

oracle 新_多种块大小的支持9i
oracle 新_多种块大小的支持 conn sys/sys as sysdba SHOW PARAMETER CACHE ALTER SYSTEM SET DB_CACHE_SIZE16M; ALTER SYSTEM SET DB_4K_CACHE_SIZE8M; CREATE TABLESPACE K4 DATAFILE F:\ORACLE\ORADATA\ZL9\K4.DBF SIZE 2M BLOCKSIZE 4K; CREATE TABLE SCOTT.A1 TABLESP…...
Collections工具类
类java.util.Collections提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。 方法名说明void sort(List)对List容器内的元素排序,排序规则是升序void shuffle(List)对List容器内的元素进行随机排列void reverse(List)对List容器内的元素进行逆序排列void…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...