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

CNNs: ZFNet之CNN的可视化网络介绍

CNNs: ZFNet之CNN的可视化网络介绍

  • 导言
  • Deconvnet
    • 1. Unpooling
    • 2. ReLU
    • 3. Transpose conv
  • AlexNet网络修改
  • AlexNet Deconv网络介绍
  • 特征可视化

导言

上一个内容,我们主要学习了AlexNet网络的实现、超参数对网络结果的影响以及网络中涉及到一些其他的知识点,如激活函数dropout等。

经过前面三节关于AlexNet的学习,我们大概了解一个简单的卷积神经网络模型的工作过程和如何针对一个数据集去调参以实现我们期望的模型结果。当然,这里我们忽略了一个重要的点就是数据集,我们训练出来的模型的好坏第一步是要确认我们手头的数据集是比较好的,如我在第二篇中提供的flower数据集,如dandelion下的数据(还有其他)很差,导致我们在训练过程中很难达到我们需要的效果。所以,我们在工程中或者研究中一定要保证第一个前提:采集较好的数据集。当然,当数据集不够时,我们需要对数据集进行增强(这里先挖一个坑,关于数据集增强系列)。

从本篇开始,我们将参考文章Visualizing and Understanding Convolutional Networks基于AlexNet模型对模型训练过程中convnet模块进行探索,窥视网络不同层学习到了什么特征。

Deconvnet

首先,让我们对deconvnet进行介绍:

AlexNet中一个基础的convnet模块基本上要进行卷积ReLU池化操作。所以,对应的deconvnet模块需要进行反池化ReLU卷积的转置操作。

在这里插入图片描述

1. Unpooling

convnet模块中,最大池化的基本原理是:

  • 将输入数据分割成若干个不重叠的矩形。
  • 对于每个矩形块,取其中最大的数作为输出。
  • 将所有输出组合成一个新的矩阵作为最终的输出。

最大池化的作用是减少特征图的大小,从而减少计算量和参数数量,同时可以提取出输入数据中的最显著的特征。

convnet中,最大池化操作是不可逆的,但是我们可以通过记录一组switch变量(每个池化区域内的最大值的位置)来获得近似逆。在deconvnet中,unpooling操作使用这些switch变量将来自上层的重建放置到适当的位置。具体操作如上图所示。

2. ReLU

convnet使用ReLU非线性,为了在每一层获得有效的特征重建我们将重建的信号通过ReLU

3. Transpose conv

convnet模块使用学习后的卷积核来卷积来自前一层的特征图。为了近似地反转这一点,deconvnet使用相同滤波器的转置,应用在使用ReLU后的特征图上,而不是下面的层的输出。

AlexNet网络修改

为了能够将AlexNet可视化,我们需要对在AlexNet网络介绍中的网络进行修改:

import torch
import torch.nn as nn
from collections import OrderedDictclass AlexNet(nn.Module):def __init__(self, class_num = 5):super(AlexNet, self).__init__()self.features = nn.Sequential(# input[3, 227, 227]  output[96, 55, 55]nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=0),nn.ReLU(inplace=True),# output[96, 27, 27]nn.MaxPool2d(kernel_size=3, stride=2, return_indices=True),# output[256, 27, 27]nn.Conv2d(96, 256, kernel_size=5, padding=2),nn.ReLU(inplace=True),# output[256, 13, 13]nn.MaxPool2d(kernel_size=3, stride=2, return_indices=True),# output[384, 13, 13]nn.Conv2d(256, 384, kernel_size=3, padding=1),nn.ReLU(inplace=True),# output[384, 13, 13]nn.Conv2d(384, 384, kernel_size=3, padding=1),nn.ReLU(inplace=True),# output[256, 13, 13]nn.Conv2d(384, 256, kernel_size=3, padding=1),nn.ReLU(inplace=True),# output[256, 6, 6]nn.MaxPool2d(kernel_size=3, stride=2, return_indices=True),)self.classifier = nn.Sequential(nn.Linear(256 * 6 * 6, 4096),nn.ReLU(inplace=True),nn.Dropout(p=0.5),nn.Linear(4096, 4096),nn.ReLU(inplace=True),nn.Linear(4096, class_num),)# index of convself.conv_layer_indices = [0, 3, 6, 8, 10]# feature mapsself.feature_maps = OrderedDict()# switchself.pool_locs = OrderedDict()def forward(self, x):for idx, layer in enumerate(self.features):if isinstance(layer, nn.MaxPool2d):x, location = layer(x)self.pool_locs[idx] = locationself.feature_maps[idx] = xelse:x = layer(x)self.feature_maps[idx] = xx = torch.flatten(x, start_dim=1)x = self.classifier(x)return x

首先,我们在执行最大池化时,将最大池化的位置需要返回,以便我们可以记录下来,所以nn.MaxPool2d中参数return_indices置为true

nn.MaxPool2d(kernel_size=3, stride=2, return_indices=True),

然后,我们在执行forward方法时,需要将最大池化层的位置和每一层的feature map都记录下来。

AlexNet Deconv网络介绍

import sys
sys.path.append('.')import torch
import torch.nn as nn
from utils_module import param_settingsclass AlexNetDeconv(nn.Module):def __init__(self):super(AlexNetDeconv, self).__init__()self.features = nn.Sequential(# deconv1nn.MaxUnpool2d(kernel_size=3, stride=2),nn.ReLU(inplace=True),nn.ConvTranspose2d(256, 384, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.ConvTranspose2d(384, 384, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.ConvTranspose2d(384, 256, kernel_size=3, padding=1),# deconv2nn.MaxUnpool2d(kernel_size=3, stride=2),nn.ReLU(inplace=True),nn.ConvTranspose2d(256, 96, kernel_size=5, padding=2),# deconv3nn.MaxUnpool2d(kernel_size=3, stride=2),nn.ReLU(inplace=True),nn.ConvTranspose2d(96, 3, kernel_size=11, stride=4, padding=0))self.conv2deconv_indices = { 0:12, 3:9, 6:6, 8:4, 10:2 }self.unpool2pool_indices = { 10:2, 7:5, 0:12 }self.init_weight()def init_weight(self):model_path = param_settings.SAVE_PATHalexnet_model = torch.load(model_path)for idx, layer in enumerate(alexnet_model.features):if isinstance(layer, nn.Conv2d):self.features[self.conv2deconv_indices[idx]].weight.data = layer.weight.datadef forward(self, x, layer, activation_idx, pool_locs):if layer in self.conv2deconv_indices:start_idx = self.conv2deconv_indices[layer]else:raise ValueError('layer is not a conv feature map')for idx in range(start_idx, len(self.features)):if isinstance(self.features[idx], nn.MaxUnpool2d):x = self.features[idx]\(x, pool_locs[self.unpool2pool_indices[idx]].cpu())else:x = self.features[idx](x)return x

首先,我们做Deconv模块时,需要从convnet模块的最底层反向进行操作。

其次,我们需要记录convdeconv的相对关系以及unpoolingpooling之间的相对关系。

接着,我们需要将conv模型的feature参数记录下来,并对其进行初始化。

forward方法定义了模型的前向传播过程。给定输入x、层索引layer、激活索引activation_idx和池化位置pool_locs,它根据指定的层开始进行反卷积操作,直到模型的最后一层。

特征可视化

首先,获取指定层的特征图,并选择其中最大激活的特征。

然后,将其他层的特征图置为0,并将激活值设置为0,以便反卷积模型能够还原出原始图像。

接着,使用反卷积模型对处理后的特征图进行反卷积操作,得到原始图像。

def layer_viewer(layer, model, model_deconv):feat_num = model.feature_maps[layer].shape[1]new_feat_map = model.feature_maps[layer].clone().cpu()# 选择最大激活特征act_lst = []for i in range(0, feat_num):choose_map = new_feat_map[0, i, :, :]activation = torch.max(choose_map)act_lst.append(activation.item())act_lst = np.array(act_lst)mark = np.argmax(act_lst)choose_map = new_feat_map[0, mark, :, :]max_activation = torch.max(choose_map)# 将其他层的特征图置为0if mark == 0:new_feat_map[:, 1:, :, :] = 0else:new_feat_map[:, :mark, :, :] = 0choose_map = torch.where(choose_map == max_activation,choose_map, torch.zeros(choose_map.shape))# 将激活值设置为0new_feat_map[0, mark, :, :] = choose_mapprint(max_activation)deconv_output = model_deconv(new_feat_map, layer, mark, model.pool_locs)# (H, W, C)new_img = deconv_output.data.numpy()[0].transpose(1, 2, 0)  # normalizenew_img = (new_img - new_img.min()) / (new_img.max() - new_img.min()) * 255new_img = new_img.astype(np.uint8)# cv2.imshow('reconstruction img ' + str(layer), new_img)# cv2.waitKey()return new_img, int(max_activation)

项目地址:
https://gitee.com/jiangli01/dl-practice/tree/master/AlexNet-Visualizing

相关文章:

CNNs: ZFNet之CNN的可视化网络介绍

CNNs: ZFNet之CNN的可视化网络介绍 导言Deconvnet1. Unpooling2. ReLU3. Transpose conv AlexNet网络修改AlexNet Deconv网络介绍特征可视化 导言 上一个内容,我们主要学习了AlexNet网络的实现、超参数对网络结果的影响以及网络中涉及到一些其他的知识点&#xff0…...

云原生之深入解析Airbnb的动态Kubernetes集群扩缩容

一、前言 Airbnb 基础设施的一个重要作用是保证我们的云能够根据需求上升或下降进行自动扩缩容,我们每天的流量波动都非常大,需要依靠动态扩缩容来保证服务的正常运行。为了支持扩缩容,Airbnb 使用了 Kubernetes 编排系统,并且使…...

Django框架之模板其他补充

本篇文章是对django框架模板内容的一些补充。包含注释、html转义和csrf内容。 目录 注释 单行注释 多行注释 HTML转义 Escape Safe Autoescape CSRF 防止csrf方式 表单中使用 ajax请求添加 注释 单行注释 语法:{# 注释内容 #} 示例: {# 注…...

安装Maven 3.6.1:图文详细教程(适用于Windows系统)

一、官网下载对应版本 推荐使用maven3.6.1版本,对应下载链接: Maven3.6.1下载地址 或者,这里提供csdn下载地址,点击下载即可: Maven3.6.1直链下载 其他版本下载地址: 进入网址:http://mave…...

计算机图形学 | 实验八:Phong模型

计算机图形学 | 实验八:Phong模型 计算机图形学 | 实验八:Phong模型Phong模型光源设置 光照计算定向光点光源聚光 华中科技大学《计算机图形学》课程 MOOC地址:计算机图形学(HUST) 计算机图形学 | 实验八&#xff1a…...

第三十一回:GestureDetector Widget

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了ListView响应事件的内容t,本章回中将介绍 GestureDetector Widget.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里介绍的GestureDetector是一个事件响应Widget,它可以响应双击事件&#xff0…...

Java面试知识点(全)-Java并发-多线程JUC三- JUC集合/线程池

Java面试知识点(全) 导航: https://nanxiang.blog.csdn.net/article/details/130640392 注:随时更新 JUC集合类 为什么HashTable慢? 它的并发度是什么? 那么ConcurrentHashMap并发度是什么? Hashtable之所以效率低下主要是因为其实现使用了synchro…...

Android 如何获取有效的DeviceId

目录 前言官方唯一标识符建议使用广告 ID使用实例 ID 和 GUID不要使用 MAC 地址标识符特性常见用例和适用的标识符 解决方案DeviceIdANDROID_IDMac地址UUID补充 总结 前言 从 Android 10 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 特许权限才能访问设备的不可…...

<SQL>《SQL命令(含例句)精心整理版(2)》

《SQL命令(含例句)精心整理版(2)》 跳转《SQL命令(含例句)精心整理版(1)8 函数8.1 文本处理函数8.2 数值处理函数8.3 时间处理函数8.3.1 时间戳转化为自定义格式from_unixtime8.3.2 …...

完全自主研发,聚芯微发布3D dToF图像传感器芯片!

日前,由中国半导体行业协会IC设计分会(ICCAD)、芯原股份、松山湖管委会主办的主题为“AR/VR/XR元宇宙”的“2023松山湖中国IC创新高峰论坛”正式在广东东莞松山湖召开。武汉市聚芯微电子有限责任公司发布了完全自主知识产权的3D dToF图像传感…...

MySQL 事物(w字)

目录 事物 首先我们来看一个简单的问题 什么是事务 为什么会出现事务 事务的版本支持 事务提交方式 事务常见操作方式 设置隔离级别 事物操作 事物结论 事务隔离级别 理解隔离性 隔离级别 查看与设置隔离性 注意可重复读【Repeatable Read】的可能问题&#xff…...

字节跳动测试岗四面总结....

字节一面 1、 简单做一下自我介绍 2、 简要介绍一下项目/你负责的模块/选一个模块说一下你设计的用例 3 、get请求和post请求的区别 4、 如何判断前后端bug/3xx是什么意思 5、 说一下XXX项目中你做的接口测试/做了多少次 6、 http和https的区别 7、 考了几个ADB命令/查看…...

基于.NetCore开源的Windows的GIF录屏工具

推荐一个Github上Start超过20K的超火、好用的屏幕截图转换为 GIF 动图开源项目。 项目简介 这是基于.Net Core WPF 开发的、开源项目,可将屏幕截图转为 GIF 动画。它的核心功能是能够简单、快速地截取整个屏幕或者选定区域,并将其转为 GIF动画&#x…...

PCB 基础~典型的PCB设计流程,典型的PCB制造流程

典型的PCB设计流程 典型的PCB制造流程 • 从客户手中拿到Gerber, Drill以及其它PCB相关文件 • 准备PCB基片和薄片 – 铜箔的底片会被粘合在基材上 • 内层图像蚀刻 – 抗腐蚀的化学药水会涂在需要保留的铜箔上(例如走线和过孔) – 其他药水…...

Python logging使用

目录 logging模块 logging核心组件 logger handler StreamHandler:把日志内容在控制台中输出 FileHandler:把日志内容写入到文件中 filter formatter 注意日志级别的继承问题 logger.exception 上述样例的整体代码 日志的配置文件及其模板 lo…...

红黑树的实现原理和应用场景

红黑树的实现原理和应用场景; 有如图所示的表,现在希望查询的结果将列成行 建表语句如下: CREATE TABLE TEST_TB_GRADE2 ( ID int(10) NOT NULL AUTO_INCREMENT, USER_NAME varchar(20) DEFAULT NULL, CN_SCORE float DEFAULT NU…...

idea插件完成junit代码生成,和springboot代码示例

在idea环境下,可以用过插件的方式自动生成juint模板代码。不过具体要需要自己手动编写。 1、安装插件 打开idea,file–settings–plugins,搜索和安装插件(JunitGenerator V2.0和JUnit),安装后,后…...

【Redis面试点总结】

1、缓存 1.1、穿透 查询一个空数据,mysql也查不到也不会写入缓存可能导致多次请求数据库 方案一:缓存设空即可(可能发生数据不一致就是这条数据有了但此时缓存是空,消耗内存) 方案二:布隆过滤器&#x…...

打卡智能中国(五):博士都去哪儿了?

《打卡智能中国》系列更新了几期,有读者表示,很爱看这类接地气的真实故事,也有读者反映,不是电工,就是文员、农民、治沙人,人工智能不是高精尖学科吗?那些学历很高的博士都去哪儿了?…...

[Nacos] Nacos Client获取调用服务的提供者列表 (四)

文章目录 1.Nacos Client获取调用服务的提供者列表1.1 从Ribbon的负载均衡入手到Nacos Client获取调用服务的提高者列表1.2 getServers方法返回分析1.3 通过selectInstances方法查找Instances实例1.4 获取到要调用服务的serviceInfo Nacos Client 从Ribbon负载均衡调用服务。 …...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

GitHub 趋势日报 (2025年06月08日)

📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Android15默认授权浮窗权限

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

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

微服务通信安全:深入解析mTLS的原理与实践

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...