基于Keras的卷积神经网络(CNN)可视化

本文介绍三种基于Keras的卷积神经网络(CNN)可视化方法:卷积核输出、卷积核本身及热度图可视化,帮助理解CNN的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于Keras的卷积神经网络(CNN)可视化

标签(空格分隔): 深度学习


卷积神经网络可视化

  • 本文整理自Deep Learning with Python,书本上完整的代码在 这里的5.4节,并陪有详细的注释。
  • 深度学习一直被人们称为“黑盒子”,即内部算法不可见。但是,卷积神经网络(CNN)却能够被可视化,通过可视化,人们能够了解CNN识别图像的过程。
  • 介绍三种可视化方法
    1. 卷积核输出的可视化(Visualizing intermediate convnet outputs (intermediate activations),即可视化卷积核经过激活之后的结果。能够看到图像经过卷积之后结果,帮助理解卷积核的作用
    2. 卷积核的可视化(Visualizing convnets filters),帮助我们理解卷积核是如何感受图像的
    3. 热度图可视化(Visualizing heatmaps of class activation in an image),通过热度图,了解图像分类问题中图像哪些部分起到了关键作用,同时可以定位图像中物体的位置。

卷积核输出的可视化(Visualizing intermediate convnet outputs (intermediate activations)

  • 想法很简单:向CNN输入一张图像,获得某些卷积层的输出,可视化该输出

  • 代码中,使用到了cats_and_dogs_small_2.h5模型,这是在原书5.2节训练好的模型,当然你完全可以使用keras.applications 中的模型,例如VGG16等。

  • 可视化结果如下图。
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 结论:

    • 第一层卷积层类似边缘检测的功能,在这个阶段里,卷积核基本保留图像所有信息
    • 随着层数的加深,卷积核输出的内容也越来越抽象,保留的信息也越来越少。
    • 越深的层数,越多空白的内容,也就说这些内容空白卷积核没有在输入图像中找到它们想要的特征

卷积核的可视化(Visualizing convnets filters)

  • 卷积核到底是如何识别物体的呢?想要解决这个问题,有一个方法就是去了解卷积核最感兴趣的图像是怎样的。我们知道,卷积的过程就是特征提取的过程,每一个卷积核代表着一种特征。如果图像中某块区域与某个卷积核的结果越大,那么该区域就越“像”该卷积核。

  • 基于以上的推论,如果我们找到一张图像,能够使得这张图像对某个卷积核的输出最大,那么我们就说找到了该卷积核最感兴趣的图像。

  • 具体思路:输入一张随机内容的图像 I I I, 求某个卷积核 F F F对图像的梯度 G = ∂ F / ∂ I G = \partial F / \partial I G=F/I,用梯度上升的方法迭代更新图像 I = I + η ∗ G I = I + \eta * G I=I+ηG η \eta η是类似于学习率的东西。

  • 代码中,使用以及训练好的VGG16模型,可视化该模型的卷积核。结果如下

    • block1_conv1 在这里插入图片描述

    • block2_conv1 在这里插入图片描述

    • block3_conv1 在这里插入图片描述

    • block4_conv1 在这里插入图片描述

    • block5_conv1 在这里插入图片描述

  • 结论:

    • 低层的卷积核似乎对颜色,边缘信息感兴趣。
    • 越高层的卷积核,感兴趣的内容越抽象(非常魔幻啊),也越复杂。
    • 高层的卷积核感兴趣的图像越来越难通过梯度上升获得(block5_conv1有很多还是随机噪声的图像)

热度图可视化(Visualizing heatmaps of class activation in an image)

  • 在图像分类问题中,假设网络将一张图片识别成“猫”的概率是0.9,我想了解到底最后一层的卷积层对这0.9的概率的贡献是多少。换句话时候,假设最后一层卷积层有512个卷积核,我想了解这512个卷积核对该图片是"猫"分别投了几票。投票越多的卷积核,就越确信图片是“猫”,因为它们提取到的特征趋向猫的特征。

  • 代码中,输入了一张大象的图片,然后获得最后一层卷积层的热度图,最后将热度图叠加到原图像,获得图像中起到关键分类作用的部分。结果如下:

    • 在这里插入图片描述
### 使用 PyTorch 实现 CNN 特征图可视化 #### 准备工作 为了实现特征图的可视化,首先需要准备必要的库和工具。这包括导入 `torch` 和 `torchvision` 库以及设置好要使用的数据集。 ```python import torch from torchvision import models, transforms from torchvision.utils import make_grid, save_image import matplotlib.pyplot as plt ``` 对于数据处理部分,可以通过定义转换操作来预处理图像数据: ```python transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), ]) dataset = datasets.ImageFolder('path_to_images', transform=transform) dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False)[^3] ``` #### 注册前向钩子 (Forward Hook) 通过注册前向传播过程中的钩子函数,可以在特定层获取激活值(即特征图)。这里展示了一个简单的例子,在 ResNet 的某一层上安装钩子以捕获其输出[^1]。 ```python def get_activation(name): activation = {} def hook(model, input, output): activation[name] = output.detach() return hook model = models.resnet18(pretrained=True).eval() # 假设我们要查看layer4的第一个残差块后的ReLU的结果 model.layer4[0].relu.register_forward_hook(get_activation('layer4_0_relu')) output = model(torch.randn(1, 3, 224, 224)) act = activation['layer4_0_relu'] print(act.shape) # 输出形状应类似于torch.Size([1, 512, H, W]) ``` #### 可视化特征图 一旦获得了所需的特征图张量,就可以利用 `make_grid()` 方法将其排列成易于观察的形式,并保存或显示出来。 ```python plt.figure(figsize=(16, 16)) for i in range(min(64, act.size()[1])): ax = plt.subplot(8, 8, i + 1) img = act[0, i, :, :] plt.imshow(img.numpy()) plt.axis("off") plt.show() save_image(make_grid(act), "feature_maps.png") ``` 上述代码片段展示了如何提取并绘制单个批次内的多个通道上的特征映射。注意实际应用中可能还需要调整绘图参数以便更好地呈现细节。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值