深度卷积神经网络(CNN)特征层的可视化

目录

简介

一、可视化原理

二、项目配置

2.1 配置环境 

2.2 代码运行

总结


简介

对CNN有所了解的同学应该知道,网络内部的特征层,随着越靠近最终输出,其特征所代表的语义信息就越明显。我们能够通过中间层的信息,直观的看到网络学习过程中,哪些像素的权重比较高,这些权重高的像素集中在什么区域,进而知道网络对数据理解的基本过程。


一、可视化原理

在CNN的重要工作Alexnet中就已经介绍过了,利用CNN网络在ImageNet上进行分类学习,如果按照最后一层输出的向量为标注,建立一个向量的度量,然后将不同的图像按照该度量,实现匹配,其结果会有高度语义一致性,如图1所示。

图1,基于特征向量计算的近似结果显示。可以看到每一行图像的语义内容关联。

这让人不禁去想,这种相似度与网络对各个节点的激活情况有一种相关性。在网络的最后一层,即马上就有直接输出语义标签的前一层,其特征表示已经具有高度的语义信息。那么,如果我们能够找到一种方法,能够将这种语义信息向前传导,以了解到底是那些像素为语义信息的表示提供了较大的权重,那些像素是可有可无的。那么当向前传导后,我们就可以推出每一层针对像素的一个权重分布。按照这个分布,我们可以直接对图像做一些变换,进而得到特征层对于这些像素的直接影响,用来表达可视化效果。

我们以LayerCAM为例,来介绍可视化实现的基本思路。LayerCAM目标是建立具有更好语义对应的色差图,以表示分类标点对应的语义信息。其核心的想法是重新思考了特征图以及梯度的关系。和其他方法不同的是,LayerCAM利用了梯度来标识在特征图中每一个位置的重要性。看到这里我们就知道了,在判断图像中哪个点对于分类问题的权重更大时,我们只需要将梯度变化作为一个参考,融合进特征向量的反向传递表达,以判断像素的权重即可。具体实现有兴趣的同学可以阅读论文以学习。

论文:LayerCAM: Exploring Hierarchical Class Activation Maps for Localization

 二、项目配置

我们使用Github项目pytorch-grad-cam作为我们的平台。该项目获得6.4k星标,在同类项目里算是比较具有代表性的,且集成了许多CNN可视化的经典方法,包括:​​​​​​

MethodWhat it does
GradCAMWeight the 2D activations by the average gradient
GradCAM++Like GradCAM but uses second order gradients
XGradCAMLike GradCAM but scale the gradients by the normalized activations
AblationCAMZero out activations and measure how the output drops (this repository includes a fast batched implementation)
ScoreCAMPerbutate the image by the scaled activations and measure how the output drops
EigenCAMTakes the first principle component of the 2D Activations (no class discrimination, but seems to give great results)
EigenGradCAMLike EigenCAM but with class discrimination: First principle component of Activations*Grad. Looks like GradCAM, but cleaner
LayerCAMSpatially weight the activations by positive gradients. Works better especially in lower layers
FullGradComputes the gradients of the biases from all over the network, and then sums them

Project Link:https://github.com/utkuozbulak/pytorch-cnn-visualizations

2.1 配置环境 

需要配置基于python3.7版本的torch与torchvision,我在网上找到的安装代码为:

pip install torch==1.7.1+cu110 
torchvision==0.8.2+cu110 -f 
https://download.pytorch.org/whl/torch_stable.html

之后仅需要使用conda安装cudatoolkit就可以。注意,对应的cuda版本为11.0。随后安装对应的cudnn(cudnn不用再指定版本号,系统会自动根据安装cudatoolkit自动选择对应的cudnn版本)。

conda install -c anaconda cudatoolkit=11.0
conda install -c anaconda cudnn

到此,最重要的环境配置已经完成了。为了验证配置,需测试pytorch的GPU模式是否可用:

import torch
flag = torch.cuda.is_available()
if flag:
    print("CUDA可使用")
else:
    print("CUDA不可用")

ngpu= 1
# Decide which device we want to run on
device = torch.device("cuda:0" if (torch.cuda.is_available() and ngpu > 0) else "cpu")
print("驱动为:",device)
print("GPU型号: ",torch.cuda.get_device_name(0))

2.2 代码运行

代码如下(示例):

Usage: python cam.py --image-path <path_to_image> --method <method>
To use with CUDA: python cam.py --image-path <path_to_image> --use-cuda

Instance:
python cam.py --image-path examples\both.png --method gradcam++

指定cam.py并执行对应的方法,就要能够得到特征层的示意图,程序默认使用resnet50作为网络结构来输出特征层数据。也可以通过参数调用可视化显示的方法,包括:GradCAM,ScoreCAM,GradCAM++,AblationCAM,XGradCAM,EigenGradCAM,LayerCAM,FullGrad。作者也实现了根据其他经典网络的实现,具体可以参看下面的代码,这里用VGG来做表示:

#默认
model = models.resnet50(pretrained=True)
target_layers = [model.layer4]

#替换VGG,这里的-1指的是最后一层的意思。VGG19共有37层,你可以指定任意一层来查看输出
model = models.vgg19(pretrained=True)
target_layers = [model.features[-1]]

图2展示一个示例,基于VCG网络和layercam方法。第一列为原始图像,第二列为输出第11层特征结果,第三列最后一层结果。

  图2,深度特征可视化,基于VGG19。


总结

深度神经网络的特征层能够被可视化,并且具有不错的语义一致性信息。通过对这些信息进行可视化,可以清楚的知道网络在学习过程中是如何”看“图片,并识别出有效内容的。特征层的可视化对于我们深入理解神经网络的特征学习机制具有及重要的作用。

  • 3
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习模型,广泛应用于图像识别、语音识别和自然语言处理等领域。在训练CNN时,网络会自动学习到图像的特征,这些特征可以帮助我们更好地理解图像,并且可以可视化出来。 在Keras中,我们可以使用`model.layers`属性来获取CNN的每一。其中,卷积和池化通常会提取出图像的特征,全连接则会将这些特征映射到具体的分类。 我们可以通过以下步骤来可视化CNN特征提取过程: 1. 加载CNN模型,并选择需要可视化的卷积或池化。 2. 加载需要进行特征提取的图像,并对其进行预处理。 3. 使用`K.function`方法来获取所选的输出结果。 4. 将输出结果可视化出来。 下面是一个简单的示例代码,可供参考: ```python import numpy as np import matplotlib.pyplot as plt from keras.models import load_model from keras.preprocessing import image from keras import backend as K # 加载模型 model = load_model('my_model.h5') # 选择需要可视化 layer_name = 'conv2d_1' layer = model.get_layer(name=layer_name) # 加载图像并进行预处理 img_path = 'my_image.jpg' img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) # 获取所选的输出结果 get_activations = K.function([model.input, K.learning_phase()], [layer.output]) activations = get_activations([x, 0])[0] # 可视化结果 plt.imshow(activations[0, :, :, 0], cmap='gray') ``` 在上面的示例代码中,我们可视化了模型中名为`conv2d_1`的卷积的输出结果。我们加载了一张图像,并将其输入到模型中,然后使用`K.function`方法获取该卷积的输出结果。最后,我们使用`plt.imshow`方法将第一个特征可视化出来。 通过这种方法,我们可以更好地理解CNN是如何对图像进行特征提取的,并且可以帮助我们更好地优化模型的性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿老甘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值