(二十八)mmdetection实用工具: Visualization

news/2024/11/27 21:32:35/

目录

  • 一、基础绘制接口
  • 二、基础存储接口
  • 三、任意点位进行可视化

一、基础绘制接口

可视化器(Visualizer):可视化器负责对模型的特征图、预测结果和训练过程中产生的结构化日志进行可视化,支持 Tensorboard 和 WanDB 等多种可视化后端。

import torch
import mmcv
from mmengine.visualization import Visualizer
image = mmcv.imread('/home/mby/图片/cat_and_dog.jpg',channel_order='rgb')#可视化器初始化
visualizer = Visualizer(image=image)
# 绘制单个检测框, xyxy 格式
visualizer.draw_bboxes(torch.tensor([80, 200, 600, 650]))
# 绘制多个检测框
visualizer.draw_bboxes(torch.tensor([[640, 50, 1550, 650], [80, 200, 600, 650]]))
visualizer.show()
#为Visualizer设置绘制的图像
visualizer.set_image(image=image)
visualizer.draw_texts("cat and dog", torch.tensor([10, 20]))
visualizer.draw_bboxes(torch.tensor([80, 200, 600, 650]),edge_colors='r',line_widths=3)
visualizer.draw_bboxes(torch.tensor([[640, 50, 1550, 650]]),line_styles='--')
visualizer.show()

draw_bboxes()函数定义:

def draw_bboxes(self,bboxes: Union[np.ndarray, torch.Tensor],edge_colors: Union[str, tuple, List[str], List[tuple]] = 'g',line_styles: Union[str, List[str]] = '-',line_widths: Union[Union[int, float], List[Union[int, float]]] = 2,face_colors: Union[str, tuple, List[str], List[tuple]] = 'none',alpha: Union[int, float] = 0.8,#矩形框的透明度
) -> 'Visualizer':
import mmcv
from mmengine.visualization import Visualizer
import numpy as np
from torchvision.models import resnet18
from torchvision.transforms import Compose, Normalize, ToTensor
#预处理
def preprocess_image(img, mean, std):preprocessing = Compose([ToTensor(),Normalize(mean=mean, std=std)])return preprocessing(img.copy()).unsqueeze(0)
#模型
model = resnet18(pretrained=True)
#前向过程:
def _forward(x):x = model.conv1(x)x = model.bn1(x)x = model.relu(x)x = model.maxpool(x)x1 = model.layer1(x)x2 = model.layer2(x1)x3 = model.layer3(x2)x4 = model.layer4(x3)return x4
image = mmcv.imread('/home/mby/图片/cat_and_dog0.jpeg',channel_order='rgb')
model.forward = _forwardimage_norm = np.float32(image) / 255
input_tensor = preprocess_image(image_norm,mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])
feat = model(input_tensor)[0]visualizer = Visualizer()
drawn_img = visualizer.draw_featmap(feat, channel_reduction='select_max')
visualizer.show(drawn_img)

draw_featmap()函数定义

def draw_featmap(featmap: torch.Tensor,		#特征图(C, H, W).overlaid_image: Optional[np.ndarray] = None,#显示的图像,特征图会叠加到 image 上绘制channel_reduction: Optional[str] = 'squeeze_mean',# 多个通道压缩为单通道的策略topk: int = 20,# 可选择激活度最高的 topk 个特征图显示arrangement: Tuple[int, int] = (4, 5),# 多通道展开为多张图时候布局resize_shape: Optional[tuple] = None, # 可以指定 resize_shape 参数来缩放特征图alpha: float = 0.5					#特征图的透明度) -> np.ndarray:

官方解释:
输入的 Tensor 一般是包括多个通道的,channel_reduction 参数可以将多个通道压缩为单通道,然后和图片进行叠加显示
squeeze_mean 将输入的 C 维度采用 mean 函数压缩为一个通道,输出维度变成 (1, H, W)
select_max 从输入的 C 维度中先在空间维度 sum,维度变成 (C, ),然后选择值最大的通道
None 表示不需要压缩,此时可以通过 topk 参数可选择激活度最高的 topk 个特征图显示
在 channel_reduction 参数为 None 的情况下,topk 参数生效,其会按照激活度排序选择 topk 个通道,然后和图片进行叠加显示,并且此时会通过 arrangement 参数指定显示的布局
如果 topk 不是 -1,则会按照激活度排序选择 topk 个通道显示
如果 topk = -1,此时通道 C 必须是 1 或者 3 表示输入数据是图片,否则报错提示用户应该设置 channel_reduction来压缩通道。
考虑到输入的特征图通常非常小,函数支持输入 resize_shape 参数,方便将特征图进行上采样后进行可视化。

二、基础存储接口

任何一个可视化器都可以配置任意多个存储后端,可视化器会循环调用配置好的多个存储后端,从而将结果保存到多后端中。
本地后端存储:

visualizer = Visualizer(image=image,vis_backends=[dict(type='LocalVisBackend')],save_dir='temp_dir')
visualizer.draw_bboxes(torch.tensor([[33, 120, 209, 220], [72, 13, 179, 147]]))
visualizer.draw_texts("cat and dog", torch.tensor([10, 20]))
visualizer.draw_circles(torch.tensor([40, 50]), torch.tensor([20]))# 会生成 temp_dir/vis_data/vis_image/demo_0.png
visualizer.add_image('demo', visualizer.get_image())
其中生成的后缀 0 是用来区分不同 step 场景# 会生成 temp_dir/vis_data/vis_image/demo_1.png
visualizer.add_image('demo', visualizer.get_image(), step=1)
# 会生成 temp_dir/vis_data/vis_image/demo_3.png
visualizer.add_image('demo', visualizer.get_image(), step=3)

其他后端存储:
这里需要注意,如果没有存储成功,需要安装下面两个库
文件保存位置:temp_dir/vis_data/events.out.tfevents.xxx

pip install tensorboard
pip install wandb

WandbVisBackend后端可能使用失败,因为需要你在wandb网站创建一个帐户。使用的时候需要指定你的Wandb API密钥

# TensorboardVisBackend
visualizer = Visualizer(image=image,vis_backends=[dict(type='TensorboardVisBackend')],save_dir='temp_dir')
# 或者 WandbVisBackend
visualizer = Visualizer(image=image,vis_backends=[dict(type='WandbVisBackend')],save_dir='temp_dir')

保存标量数据:
会将内容追加到 temp_dir/vis_data/scalars.json

# 保存 loss
visualizer.add_scalar('loss', 0.2, step=0)
visualizer.add_scalar('loss', 0.1, step=1)
# 保存 acc
visualizer.add_scalar('acc', 0.7, step=0)
visualizer.add_scalar('acc', 0.8, step=1)
#也可以一次性保存多个标量数据
visualizer.add_scalars({'loss': 0.3, 'acc': 0.8}, step=3)

保存配置文件:

from mmengine import Config
cfg=Config.fromfile('tests/data/config/py_config/config.py')
# 会生成 temp_dir/vis_data/config.py
visualizer.add_config(cfg)

多后端存储:

visualizer = Visualizer(image=image,vis_backends=[dict(type='TensorboardVisBackend'),dict(type='LocalVisBackend')],save_dir='temp_dir')
# 会生成 temp_dir/vis_data/events.out.tfevents.xxx 文件
visualizer.draw_bboxes(torch.tensor([[33, 120, 209, 220], [72, 13, 179, 147]]))
visualizer.draw_texts("cat and dog", torch.tensor([10, 20]))
visualizer.draw_circles(torch.tensor([40, 50]), torch.tensor([20]))visualizer.add_image('demo', visualizer.get_image())

如果多个存储后端中存在同一个类的多个后端,那么必须指定 name 字段,否则无法区分是哪个存储后端。

visualizer = Visualizer(image=image,vis_backends=[dict(type='TensorboardVisBackend', name='tb_1', save_dir='temp_dir_1'),dict(type='TensorboardVisBackend', name='tb_2', save_dir='temp_dir_2'),dict(type='LocalVisBackend', name='local')],save_dir='temp_dir')

三、任意点位进行可视化

MMEngine 设计的可视化器支持在任意点位获取同一个可视化器然后进行可视化的功能。 用户只需要在初始化时候通过 get_instance 接口实例化可视化对象,此时该可视化对象即为全局可获取唯一对象,后续通过 Visualizer.get_current_instance() 即可在代码任意位置获取

# 在程序初始化时候调用
visualizer1 = Visualizer.get_instance(name='vis',vis_backends=[dict(type='LocalVisBackend')]
)# 在任何代码位置都可调用
visualizer2 = Visualizer.get_current_instance()
visualizer2.add_scalar('map', 0.7, step=0)assert id(visualizer1) == id(visualizer2)

通过字段配置方式全局初始化

from mmengine.registry import VISUALIZERSvisualizer_cfg = dict(type='Visualizer',name='vis_new',vis_backends=[dict(type='LocalVisBackend')])
VISUALIZERS.build(visualizer_cfg)

http://www.ppmy.cn/news/1121461.html

相关文章

计算机和编程语言初见

学习程序设计的目的是什么呢? 不一定要做出一个软件或系统出来,更重要的是理解计算机是如何工作的以及它的长处和短处。 计算机本身是无意识的,因此我们要求它为我们做事时:应该将步骤细化、“直”化(规律化&#xf…

02强化学习基本概念

强化学习基本概念 前言1、State、Action、Policy等① State② Action③ State transition④ State transition probability⑤ Polity 2、Reward、Return、MDP等① Reward② Trajectory and return③ Discounted return④ Episode⑤ MDP 总结: 前言 本文来自西湖大学…

走心分享!天津诚筑说Java大数据培训我该如何选择?

随着互联网的发展,IT行业变得越来越炙手可热,其中较为火热的当属大数据和Java了,许多学员都很纠结,Java和大数据我应该如何选择呢?今天小编带大家了解一下Java和大数据之间的区别! Java和大数据的关系 Java是一种面…

Android WebSocket

WS Android WebSocket 资源 名字资源AAR下载GitHub查看Gitee查看 Maven 1.build.grade allprojects {repositories {...maven { url https://jitpack.io }} }2./app/build.grade dependencies {implementation com.github.RelinRan:WS:2022.2023.9.23.1 }初始化 配置权…

day-60 代码随想录算法训练营(19)单调栈 part 03

84.柱状图中最大的矩形 思路一&#xff1a;单调栈 class Solution { public:int largestRectangleArea(vector<int>& heights) {heights.insert(heights.begin(),0);//头加0&#xff0c;防止刚开始heights.push_back(0);//尾巴上加0&#xff0c;防止一直递增最后丢…

Docker没有vim如何安装,apt-get update报ERR404解决方案

问题描述 docker容器中安装vim报错执行apt-get install vim后报错&#xff1a; E: Unable to locate package vim 更新安装源也报错docker容器中执行apt-get update后报错&#xff1a; #进入镜像命令#docker exec -it 镜像Id或镜像name /bin/bash [roottdengine ~]# docker …

用selenium和xpath定位元素并获取属性值以及str字符型转json型

页面html如图所示&#xff1a; 要使用xpath定位这个div元素&#xff0c;并且获取其属性data-config的内容值。 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Optionshost127.0.0.1 port10808 …

三叠云电梯维保系统,全面提升电梯维保管理效率与质量

随着城市化进程的不断加速&#xff0c;电梯已成为现代建筑中不可或缺的交通工具。然而&#xff0c;电梯的安全和正常运行对于居民和物业公司来说至关重要&#xff0c;同时电梯维保一直是一个困扰物业管理公司和维保企业的难题。传统的维保方式因纸质记录的繁琐和错误频发&#…