基于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…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
探索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 数据…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...
【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器
从本章节开始,进入到函数有多个参数的情况,前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参,ECX是整型的第一个参数的寄存器,那么多个参数的情况下函数如何传参,下面展开介绍参数为整型时候的几种情…...
JavaScript性能优化实战大纲
性能优化的核心目标 降低页面加载时间,减少内存占用,提高代码执行效率,确保流畅的用户体验。 代码层面的优化 减少全局变量使用,避免内存泄漏 // 不好的实践 var globalVar I am global;// 好的实践 (function() {var localV…...
Java严格模式withResolverStyle解析日期错误及解决方案
在Java中使用DateTimeFormatter并启用严格模式(ResolverStyle.STRICT)时,解析日期字符串"2025-06-01"报错的根本原因是:模式字符串中的年份格式yyyy被解释为YearOfEra(纪元年份),而非…...
SAP学习笔记 - 开发24 - 前端Fiori开发 Filtering(过滤器),Sorting and Grouping(排序和分组)
上一章讲了SAP Fiori开发的表达式绑定,自定义格式化等内容。 SAP学习笔记 - 开发23 - 前端Fiori开发 Expression Binding(表达式绑定),Custom Formatters(自定义格式化)-CSDN博客 本章继续讲SAP Fiori开发…...
