当前位置: 首页 > news >正文

PyTorch实战:模型训练中的特征图可视化技巧

1.特征图可视化,这种方法是最简单,输入一张照片,然后把网络中间某层的输出的特征图按通道作为图片进行可视化展示即可。

2.特征图可视化代码如下:

def featuremap_visual(feature, out_dir=None,  # 特征图保存路径文件save_feature=True,  # 是否以图片形式保存特征图show_feature=True,  # 是否使用plt显示特征图feature_title=None,  # 特征图名字,默认以shape作为titlenum_ch=-1,  # 显示特征图前几个通道,-1 or None 都显示nrow=8,  # 每行显示多少个特征图通道padding=10,  # 特征图之间间隔多少像素值pad_value=1  # 特征图之间的间隔像素):import matplotlib.pylab as pltimport torchvisionimport os# feature = feature.detach().cpu()b, c, h, w = feature.shapefeature = feature[0]feature = feature.unsqueeze(1)if c > num_ch > 0:feature = feature[:num_ch]img = torchvision.utils.make_grid(feature, nrow=nrow, padding=padding, pad_value=pad_value)img = img.detach().cpu()img = img.numpy()images = img.transpose((1, 2, 0))# title = str(images.shape) if feature_title is None else str(feature_title)title = str('hwc-') + str(h) + '-' + str(w) + '-' + str(c) if feature_title is None else str(feature_title)plt.title(title)plt.imshow(images)if save_feature:# root=r'C:\Users\Administrator\Desktop\CODE_TJ\123'# plt.savefig(os.path.join(root,'1.jpg'))out_root = title + '.jpg' if out_dir == '' or out_dir is None else os.path.join(out_dir, title + '.jpg')plt.savefig(out_root)if show_feature:        plt.show()

3.结合resnet网络整体可视化(主要将其featuremap_visual函数插入forward中,即可),整体代码如下:

resnet网络结构在我博客:
残差网络ResNet(超详细代码解析) :你必须要知道backbone模块成员之一 - tangjunjun - 博客园

"""
@author: tangjun
@contact: 511026664@qq.com
@time: 2020/12/7 22:48
@desc: 残差ackbone改写,用于构建特征提取模块
"""import torch.nn as nn
import torch
from collections import OrderedDictdef Conv(in_planes, out_planes, **kwargs):"3x3 convolution with padding"padding = kwargs.get('padding', 1)bias = kwargs.get('bias', False)stride = kwargs.get('stride', 1)kernel_size = kwargs.get('kernel_size', 3)out = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, padding=padding, bias=bias)return outclass BasicBlock(nn.Module):expansion = 1def __init__(self, inplanes, planes, stride=1, downsample=None):super(BasicBlock, self).__init__()self.conv1 = Conv(inplanes, planes, stride=stride)self.bn1 = nn.BatchNorm2d(planes)self.relu = nn.ReLU(inplace=True)self.conv2 = Conv(planes, planes)self.bn2 = nn.BatchNorm2d(planes)self.downsample = downsampleself.stride = stridedef forward(self, x):residual = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)if self.downsample is not None:residual = self.downsample(x)out += residualout = self.relu(out)return outclass Bottleneck(nn.Module):expansion = 4def __init__(self, inplanes, planes, stride=1, downsample=None):super(Bottleneck, self).__init__()self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)self.bn1 = nn.BatchNorm2d(planes)self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,padding=1, bias=False)self.bn2 = nn.BatchNorm2d(planes)self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)self.bn3 = nn.BatchNorm2d(planes * 4)self.relu = nn.ReLU(inplace=True)self.downsample = downsampleself.stride = stridedef forward(self, x):residual = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out = self.relu(out)out = self.conv3(out)out = self.bn3(out)if self.downsample is not None:residual = self.downsample(x)out += residualout = self.relu(out)return outclass Resnet(nn.Module):arch_settings = {18: (BasicBlock, (2, 2, 2, 2)),34: (BasicBlock, (3, 4, 6, 3)),50: (Bottleneck, (3, 4, 6, 3)),101: (Bottleneck, (3, 4, 23, 3)),152: (Bottleneck, (3, 8, 36, 3))}def __init__(self,depth=50,in_channels=None,pretrained=None,frozen_stages=-1# num_classes=None):super(Resnet, self).__init__()self.inplanes = 64self.inchannels = in_channels if in_channels is not None else 3  # 输入通道# self.num_classes=num_classesself.block, layers = self.arch_settings[depth]self.frozen_stages = frozen_stagesself.conv1 = nn.Conv2d(self.inchannels, 64, kernel_size=7, stride=2, padding=3, bias=False)self.bn1 = nn.BatchNorm2d(64)self.relu = nn.ReLU(inplace=True)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)self.layer1 = self._make_layer(self.block, 64, layers[0], stride=1)self.layer2 = self._make_layer(self.block, 128, layers[1], stride=2)self.layer3 = self._make_layer(self.block, 256, layers[2], stride=2)self.layer4 = self._make_layer(self.block, 512, layers[3], stride=2)# self.avgpool = nn.AvgPool2d(7)# self.fc = nn.Linear(512 * self.block.expansion, self.num_classes)self._freeze_stages()  # 冻结函数if pretrained is not None:self.init_weights(pretrained=pretrained)def _freeze_stages(self):if self.frozen_stages >= 0:self.norm1.eval()for m in [self.conv1, self.norm1]:for param in m.parameters():param.requires_grad = Falsefor i in range(1, self.frozen_stages + 1):m = getattr(self, 'layer{}'.format(i))m.eval()for param in m.parameters():param.requires_grad = Falsedef init_weights(self, pretrained=None):if isinstance(pretrained, str):self.load_checkpoint(pretrained)elif pretrained is None:for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, a=0, mode='fan_out', nonlinearity='relu')if hasattr(m, 'bias') and m.bias is not None:  # m包含该属性且m.bias非None # hasattr(对象,属性)表示对象是否包含该属性nn.init.constant_(m.bias, 0)elif isinstance(m, nn.BatchNorm2d):m.weight.data.fill_(1)m.bias.data.zero_()def load_checkpoint(self, pretrained):checkpoint = torch.load(pretrained)if isinstance(checkpoint, OrderedDict):state_dict = checkpointelif isinstance(checkpoint, dict) and 'state_dict' in checkpoint:state_dict = checkpoint['state_dict']if list(state_dict.keys())[0].startswith('module.'):state_dict = {k[7:]: v for k, v in checkpoint['state_dict'].items()}unexpected_keys = []  # 保存checkpoint不在module中的keymodel_state = self.state_dict()  # 模型变量for name, param in state_dict.items():  # 循环遍历pretrained的权重if name not in model_state:unexpected_keys.append(name)continueif isinstance(param, torch.nn.Parameter):# backwards compatibility for serialized parametersparam = param.datatry:model_state[name].copy_(param)  # 试图赋值给模型except Exception:raise RuntimeError('While copying the parameter named {}, ''whose dimensions in the model are {} not equal ''whose dimensions in the checkpoint are {}.'.format(name, model_state[name].size(), param.size()))missing_keys = set(model_state.keys()) - set(state_dict.keys())print('missing_keys:', missing_keys)def _make_layer(self, block, planes, num_blocks, stride=1):downsample = Noneif stride != 1 or self.inplanes != planes * block.expansion:downsample = nn.Sequential(nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(planes * block.expansion),)layers = []layers.append(block(self.inplanes, planes, stride, downsample))self.inplanes = planes * block.expansionfor i in range(1, num_blocks):layers.append(block(self.inplanes, planes))return nn.Sequential(*layers)def forward(self, x):outs = []x = self.conv1(x)x = self.bn1(x)x = self.relu(x)x = self.maxpool(x)x = self.layer1(x)outs.append(x)featuremap_visual(x)x = self.layer2(x)outs.append(x)featuremap_visual(x)x = self.layer3(x)outs.append(x)featuremap_visual(x)x = self.layer4(x)outs.append(x)# x = self.avgpool(x)# x = x.view(x.size(0), -1)# x = self.fc(x)return tuple(outs)def featuremap_visual(feature,out_dir=None,  # 特征图保存路径文件save_feature=True,  # 是否以图片形式保存特征图show_feature=True,  # 是否使用plt显示特征图feature_title=None,  # 特征图名字,默认以shape作为titlenum_ch=-1,  # 显示特征图前几个通道,-1 or None 都显示nrow=8,  # 每行显示多少个特征图通道padding=10,  # 特征图之间间隔多少像素值pad_value=1  # 特征图之间的间隔像素):import matplotlib.pylab as pltimport torchvisionimport os# feature = feature.detach().cpu()b, c, h, w = feature.shapefeature = feature[0]feature = feature.unsqueeze(1)if c > num_ch > 0:feature = feature[:num_ch]img = torchvision.utils.make_grid(feature, nrow=nrow, padding=padding, pad_value=pad_value)img = img.detach().cpu()img = img.numpy()images = img.transpose((1, 2, 0))# title = str(images.shape) if feature_title is None else str(feature_title)title = str('hwc-') + str(h) + '-' + str(w) + '-' + str(c) if feature_title is None else str(feature_title)plt.title(title)plt.imshow(images)if save_feature:# root=r'C:\Users\Administrator\Desktop\CODE_TJ\123'# plt.savefig(os.path.join(root,'1.jpg'))out_root = title + '.jpg' if out_dir == '' or out_dir is None else os.path.join(out_dir, title + '.jpg')plt.savefig(out_root)if show_feature:        plt.show()import cv2
import numpy as npdef imnormalize(img,mean=[123.675, 116.28, 103.53],std=[58.395, 57.12, 57.375],to_rgb=True):if to_rgb:img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img = img.astype(np.float32)return (img - mean) / stdif __name__ == '__main__':import matplotlib.pylab as pltimg = cv2.imread('1.jpg')  # 读取图片img = imnormalize(img)img = torch.from_numpy(img)img = torch.unsqueeze(img, 0)img = img.permute(0, 3, 1, 2)img = torch.tensor(img, dtype=torch.float32)img = img.to('cuda:0')model = Resnet(depth=50)model.init_weights(pretrained='./resnet50.pth')  # 可以使用,也可以注释model = model.cuda()out = model(img)

运行结果

参考:

PyTorch模型训练特征图可视化 - tangjunjun - 博客园 (cnblogs.com)

相关文章:

PyTorch实战:模型训练中的特征图可视化技巧

1.特征图可视化,这种方法是最简单,输入一张照片,然后把网络中间某层的输出的特征图按通道作为图片进行可视化展示即可。 2.特征图可视化代码如下: def featuremap_visual(feature, out_dirNone, # 特征图保存路径文件save_feat…...

有人@你!神工坊知识问答第二期中奖名单新鲜出炉

六月作为伟大的物理学家—麦克斯韦的诞辰月 神工坊特别推出 “ 辨 ‘麦克斯韦妖’,赢百元好礼” 夏日知识问答主题活动 活动一经推出 反响热烈 第二期中奖名单公布! 中奖的伙伴们速来兑奖! 听说还有同学没有参与? 活动最后…...

数据结构篇:旋转操作在AVL树中的实现过程

本节课在线学习视频(网盘地址,保存后即可免费观看): https://pan.quark.cn/s/06d5ed47e33b AVL树是平衡二叉搜索树的一种,它通过旋转操作来保持树的平衡。AVL树的特点是,任何节点的两个子树的高度最大差别…...

为什么Java默认使用UTF-16,Golang默认使用UTF-8呢?

Java 和 Go 语言在默认字符编码上做出了不同的选择,这是由它们的设计目标和使用场景决定的。下面是对 Java 默认使用 UTF-16 和 Go 默认使用 UTF-8 的原因进行的详细解释。 Java 默认使用 UTF-16 的原因 1. 历史背景和兼容性 Unicode 的发展: Java 诞生于 1995 年…...

JavaScript常见面试题(三)

文章目录 1.对原型、原型链的理解2.原型修改、重写3.原型链指向4.对闭包的理解5. 对作用域、作用域链的理解6.对执行上下文的理解7.对this对象的理解8. call() 和 apply() 的区别?9.异步编程的实现方式?10.setTimeout、Promise、Async/Await 的区别11.对…...

【Effective Modern C++】第1章 型别推导

【Effective Modern C】第1章 型别推导 文章目录 【Effective Modern C】第1章 型别推导条款1:理解模板型别推导基础概念模板型别推导的三种情况情景一 ParamType 是一个指针或者引用,但非通用引用情景二 ParamType是一个通过引用情景三 ParamType既不是…...

服装连锁实体店bC一体化运营方案

一、引言 随着互联网的快速发展和消费者购物习惯的变化,传统服装连锁实体店在面对新的市场环境下亟需转型升级。BC(Business to Consumer)一体化运营方案的实施将成为提升服装连锁实体店竞争力和顾客体验的关键举掖。商淘云详细介绍服装连锁…...

IDEA中SpringMVC的运行环境问题

文章目录 一、IEAD 清理缓存二、用阿里云和spring创建 SpringMVC 项目中 pom.xml 文件的区别 一、IEAD 清理缓存 springMVC 运行时存在一些之前运行过的缓存导致项目不能运行,可以试试清理缓存 二、用阿里云和spring创建 SpringMVC 项目中 pom.xml 文件的区别 以下…...

Python初体验

# Java基础知识学的差不多了,项目上又没什么事,学学py,方便以后对接 1、打包flask应用(好痛苦,在什么平台打包就只在那个平台可用想在linux用只能参考方法2了) pyinstaller --onefile app.py -n myapp 2…...

从零开始如何学习人工智能?

说说我自己的情况:我接触AI的时候,是在研一。那个时候AlphaGo战胜围棋世界冠军李世石是大新闻,人工智能第一次出现我面前,当时就想搞清楚背后的原理以及这些技术有什么作用。 就开始找资料,看视频。随着了解的深入&am…...

【仿真建模-anylogic】动态生成ConveyorCustomStation

Author:赵志乾 Date:2024-06-18 Declaration:All Right Reserved!!! 0. 背景 直接使用Anylogic组件开发的模型无法动态改变运输网布局;目前需求是要将运输网布局配置化;运输网配置化…...

如何使用idea连接Oracle数据库?

idea版本:2021.3.3 Oracle版本:10.2.0.1.0(在虚拟机Windows sever 2003 远程连接数据库) 数据库管理系统:PLSQL Developer 在idea里面找到database,在idea侧面 选择左上角加号,新建&#xff…...

谈谈kafaka的并行处理,顺带讲讲rabbitmq

简介 Kafka 是一个分布式流处理平台,它支持高效的并行处理。Kafka 的并行处理能力主要体现在以下几个方面: 分区(Partition)并行 Kafka 将数据存储在称为"分区"的逻辑单元中。每个分区可以独立地并行地进行读写操作。生产者可以根据分区策略,将数据写入到指定的分…...

P3056 [USACO12NOV] Clumsy Cows S

[USACO12NOV] Clumsy Cows S 题目描述 Bessie the cow is trying to type a balanced string of parentheses into her new laptop, but she is sufficiently clumsy (due to her large hooves) that she keeps mis-typing characters. Please help her by computing the min…...

智赢选品,OZON数据分析选品利器丨萌啦OZON数据

在电商行业的激烈竞争中,如何快速准确地把握市场动态、洞察消费者需求、实现精准选品,是每个电商卖家都面临的挑战。而在这个数据驱动的时代,一款强大的数据分析工具无疑是电商卖家们的得力助手。今天,我们就来聊聊这样一款选品利…...

Canal自定义客户端

一、背景 在Canal推送数据变更信息至MQ(消息队列)时,我们遇到了特定问题,尤其是当消息体的大小超过了MQ所允许的最大限制。这种限制导致数据推送过程受阻,需要相应的调整或处理。 二、解决方法 采用Canal自定义客户…...

20240621将需要自启动的部分放到RK3588平台的Buildroot系统的rcS文件中

20240621将需要自启动的部分放到RK3588平台的Buildroot系统的rcS文件中 2024/6/21 17:15 开发板:飞凌OK3588-C SDK:Rockchip原厂的Buildroot 缘起:在凌OK3588-C的LINUX R4系统启动的时候,需要拉高GPIO4_B5、GPIO3_B7和GPIO3_D0。…...

掌握数据魔方:Xinstall引领ASA全链路数据归因新纪元

一、引言 在数字化时代,数据是App推广和运营的核心驱动力。然而,如何准确获取、分析并应用这些数据,却成为了许多开发者和营销人员面临的痛点。Xinstall作为一款专业的App全渠道统计服务商,致力于提供精准、高效的数据解决方案&a…...

IIS代理配置-反向代理

前后端分离项目,前端在开发中使用proxy代理解决跨域问题,打包之后无效。 未配置前无法访问 部署环境为windows IIS,要在iis设置反向代理 安装代理模块 需要在iis中实现代理,需要安装Application Request Routing Cache和URL重…...

Flutter调用本地web

前言: 在目前Flutter 环境中,使用在线 webview 是一种很常见的行为 而在 app 环境中,离线使用则更有必要 1.环境准备 将依赖导入 2.引入前端代码 前端代码有两种情况 一种是使用打包工具 build 而来的前端代码 另一种情况是直接使用 HTML 文件 …...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

Android15默认授权浮窗权限

我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

大数据学习(132)-HIve数据分析

​​​​🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言&#x1f4…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四&#xff…...

Kafka主题运维全指南:从基础配置到故障处理

#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...

小木的算法日记-多叉树的递归/层序遍历

🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...

JDK 17 序列化是怎么回事

如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...

如何做好一份技术文档?从规划到实践的完整指南

如何做好一份技术文档?从规划到实践的完整指南 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...