《python深度学习》第五章-6(可视化类激活图)读书笔记(代码片段)

Paul-Huang Paul-Huang     2022-12-15     699

关键词:

《Python深度学习》第五章-6(可视化类激活图)读书笔记

卷积神经网络学到的表示非常适合可视化,很大程度上是因为它们是 视 觉 概 念 的 表 示 \\colorred视觉概念的表示 。接下来介绍3种可视化方法。

  • 事 中 \\colorblue事中 可 视 化 卷 积 神 经 网 络 的 中 间 输 出 ( 中 间 激 活 ) \\colorred可视化卷积神经网络的中间输出(中间激活) 有助于理解卷积神经网络连续的层如何对输入进行变换,也有助于初步了解卷积神经网络每个过滤器的含义。
  • 事 前 \\colorblue事前 可 视 化 卷 积 神 经 网 络 的 过 滤 器 \\colorred可视化卷积神经网络的过滤器 有助于精确理解卷积神经网络中每个过滤器容易接受的视觉模式或视觉概念。
  • 事 后 \\colorblue事后 可 视 化 图 像 中 类 激 活 的 热 力 图 \\colorred可视化图像中类激活的热力图 有助于理解图像的哪个部分被识别为属于某个类别,从而可以定位图像中的物体。

5.4.3 可视化类激活的热力图

5.4.3.1 类激活热力图的相关定义

  1. What ?——什么是类激活热力图的可视化?
    • 类激活图(Class activation map,简称CAM),指 对 输 入 图 像 \\colorred对输入图像 生成类激活的热力图。它是 与 特 定 输 出 类 别 \\colorred与特定输出类别 相关的 二 维 特 征 分 数 网 格 \\colorred二维特征分数网格 网 格 每 个 位 置 表 示 对 该 类 别 的 重 要 程 度 \\colorred网格每个位置表示对该类别的重要程度
    • 对于一张输入到CNN模型且被分类成 " 狗 " \\colorblue"狗" ""的图片,该技术 可 以 以 热 力 图 形 式 告 诉 我 们 图 片 中 的 每 个 位 置 \\colorred可以以热力图形式告诉我们图片中的每个位置 " 狗 " \\colorblue"狗" ""类的 相 似 程 度 \\colorred相似程度
  2. Why ?——为什么使用类激活热力图的可视化?
    有助于了解一张原始图像的哪一个局部 位 置 \\colorred位置 让CNN模型做出了最终的 分 类 决 策 \\colorred分类决策
  3. How ?——如何实现类激活热力图的可视化?
    • 来自佐治亚理工、脸书AI研究团队的Ramprasaath R.Selvaraju等人于2017年ICCV发表的《 G r a d − C A M \\colorredGrad-CAM GradCAM: visual explanations from deep networks via grtadient based localization》,提出了一种可视化类激活热力图的解决方案。
    • 论文地址:http://openaccess.thecvf.com/contentICCV_20l7/papers/SelvarajuGrad-CAM_Visual_ExplanationsICCV_20l7-paper.pdf
  4. 举例说明
    • 促使模型对左图做出自行车分类预测的主要特征区域集中在车把手。
    • 促使模型对左图做出棒球棒分类预测的主要特征区域集中在棒腹部。

5.4.3.2 类激活热力图的基本解决思路

  1. Grad-CAM基本原理(可以概括为 3 个 变 量 \\colorred3个变量 3+ 2 种 运 算 \\colorred2种运算 2
    • 给定一张输入图像,对于一个 卷 积 层 的 输 出 特 征 图 \\colorred卷积层的输出特征图 ,用 类 别 \\colorred类别 相对于 通 道 \\colorred通道 梯 度 \\colorblue梯度 对这个特征图中的每个通道进行 加 权 \\colorblue加权
    • 以VGG16模型为例
  2. 简要概括 3 个 变 量 \\colorred3个变量 3+ 2 种 运 算 \\colorred2种运算 2
    • 3 个 变 量 \\colorred3个变量 3
      • 卷积层输出特征,conv-layer.output
      • 卷积层输出特征中的每个通道,conv-layer.output[i]
      • 特定输出类别,model.output[i]
    • 2 种 运 算 \\colorred2种运算 2
      • 求梯度,K.gradients(y,x), K.mean(gradients)
      • 乘梯度,conv-layer.outputL[i]* gradients

5.4.3.3 类激活热力图的任务流

  1. 基本步骤

    • s t e p    1    指 定 入 \\colorredstep\\;1 \\;指定入 step1指定一张待分类图片输入到模型并预处理
    • s t e p    2    求 梯 度 \\colorredstep\\;2\\;求梯度 step2获取模型输出相对于最后一卷积层激活输出的梯度
      k.gradients(模型输出,最后一个卷积层激活输出)
      k.function(模型输入,(梯度均值,最后一个卷积层激活输出))
      
    • s t e p    3    乘 梯 度 \\colorredstep\\;3\\;乘梯度 step3表征出最后卷积层激活输出各点位对模型决策分类的重要程度,并进行预处理,记得到类激活图
      最后一个卷积层输出 *= 梯度均值
      再求均值
      
    • s t e p    4    染 画 布 \\colorredstep\\;4\\;染画布 step4将调节后的卷积激活输出渲染为热力效果
      cv2.applyColorMap
      
    • s t e p    5 可 视 化 \\colorredstep\\;5可视化 step5将原始图像与渲染后的热力图叠加后再可视化
  2. 步骤图形化

5.4.3.4 类激活热力图的代码

步骤 指 定 入 − − > 定 损 数 − − > 求 梯 度 − − > 乘 梯 度 − − > 染 画 布 − − > 可 视 化 \\colorred指定入-->定损数-->求梯度-->乘梯度-->染画布-->可视化 >>>>>

  1. 指 定 入 \\colorred指定入

    from tensorflow.keras.applications.vgg16 import VGG16
    from tensorflow.keras import backend as K
    K.clear_session()
    # 特别注意,在之前的实验中,我们都把顶层的分类器丢弃掉了,include_top = False
    ## 加载预训练模型
    model = VGG16(weights='imagenet')
    
    ## 加载指定分类图片
    from tensorflow.keras.preprocessing import image
    from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions
    import numpy as np
    
    # The local path to our target image
    img_path = 'C:\\\\Users\\\\Administrator\\\\HQR_Python_learning\\\\creative_commons_elephant.jpg'
    
    ## 图片预处理
    # `img` is a PIL image of size 224x224
    img = image.load_img(img_path, target_size=(224, 224))
    
    # 一转,`x` is a float32 Numpy array of shape (224, 224, 3)
    x0 = image.img_to_array(img)
    
    # 二扩,We add a dimension to transform our array into a "batch"
    # of size (1, 224, 224, 3)
    x1 = np.expand_dims(x0, axis=0)
    
    # 三标,Finally we preprocess the batch
    # (this does channel-wise color normalization)
    x = preprocess_input(x1)
    
    • 预测图片分类
      >>>preds = model.predict(x)
      >>>print('Predicted:', decode_predictions(preds, top=3)[0])
      Predicted: [('n02504458', 'African_elephant', 0.909421), ('n01871265', 'tusker', 0.086182885), ('n02504013', 'Indian_elephant', 0.0043545826)]
      
  2. 求 梯 度 \\colorred求梯度

    import tensorflow as tf
    tf.compat.v1.disable_eager_execution()
    
    #获取非洲象预测输出
    african_elephant_output = model.output[:,386]
    
    #获取最后一个卷积层激活输出
    last_conv_layer = model.get_layer('block5_conv3')
    #求模型输出针对最后一个卷积层激活输出的梯度
    #非洲象类别相对于 block5_conv3输出特征图的梯度
    # grad is (None,14,14,512)
    grads= K.gradients(african_elephant_output,
    					last_conv_layer.output)[0]
    # 均值化处理梯度
    # 形状为 (512,) 的向量,每个元素是特定特征图通道的梯度平均大小
    pooled_grads = K.mean(grads, axis=(0,1, 2))
    
    #建立模型输出、最后一个卷积层激活输出、梯度均值三者之间的函数关系
    #访问刚刚定义的量:对于给定的样本图像,pooled_grads 和 block5_conv3 层的输出特征图
    # model.input:(None, 224, 224, 3);last_conv_layer.output[0]:(14, 14, 512)
    iterate =K.function([model.input], [pooled_grads,last_conv_layer.output[0]])
    # pooled_grads:(512,);conv_layer_output_value:(14, 14, 512)
    pooled_grads_value,conv_layer_output_value =iterate([x])
    
  3. 乘 梯 度 \\colorred乘梯度

    import matplotlib.pyplot as plt
    for i in range(512):
        # conv_layer_output_value[:, :, i]:(14*14);pooled_grads_value[i]:()
        conv_layer_output_value[:, :, i] *= pooled_grads_value[i]
    
    # 得到的特征图的逐通道平均值即为类激活的热力图
    # heatmap:(14*14)
    heatmap = np.mean(conv_layer_output_value, axis=-1)
    # 为了将热力图可视化,去除所有负数
    heatmap = np.maximum(heatmap, 0)
    # 归一化处理
    heatmap /= np.max(heatmap)
    # 展现
    plt.matshow(heatmap)
    

  4. 染 画 布 、 可 视 化 \\colorred染画布、可视化
    安装cv2:

    • pip install opencv-python (如果只用主模块,使用这个命令安装)
    • pip install opencv-contrib-python (如果需要用主模块和contrib模块,使用这个命令安装)
    import cv2
    # 用 cv2 加载原始图像
    # img:(600, 899, 3)
    img = cv2.imread(img_path)
    # 将热力图的大小调整为与原始图像相同
    #heatmap为[0,1]之间的浮点数,特别注意:cv2.resize(img, (x轴向长度,y轴向长度))
    # heatmap:(600, 899, 3)
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    # 将热力图应用于原始图像
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
    # 将热力图转换为 RGB 格式
    heatmap = np.uint8(255 * heatmap)
    # 将热力图与原始图像叠加,0.5表示渲染强度,
    # 有超出(0,255)范围的,如果需要可视化,则需要clip裁剪
    superimposed_img = heatmap * 0.5 + img
    cv2.imwrite('C:\\\\Users\\\\Administrator\\\\HQR_Python_learning\\\\elephant_cam.jpg', superimposed_img)
    

    通过梯度类激活热力图可以看到“非洲象”分类决策依据主要来自于图片中象

    《python深度学习》第五章-5(可视化过滤器)读书笔记(代码片段)

    5.4 卷积神经网络的可视化卷积神经网络学到的表示非常适合可视化,很大程度上是因为它们是视觉概念的表示\\colorred视觉概念的表示视觉概念的表示。接下来介绍3种可视化方法。事中\\colorblue事中事中:可视化卷积神... 查看详情

    《python深度学习》第五章-1(cnn简介)读书笔记(代码片段)

    第五章深度学习用于计算机视觉5.1 卷积神经网络简介5.1.1卷积神经网络对MNIST分类使用卷积神经网络对MNIST数字进行分类,在第2章用密集连接网络做过(当时的测试精度为97.8%)。它是Conv2D层和MaxPooling2D层的堆叠。实... 查看详情

    《python深度学习》第五章-3(预训练)读书笔记(代码片段)

    5.3 使用预训练的卷积神经网络预训练网络(pretrainednetwork):是一个之前已在大型数据集(通常是大规模图像分类任务)上训练好、保存好的网络\\colorred训练好、保存好的网络训练好、保存好的网络。预训... 查看详情

    《python深度学习》第五章-2(cats_vs_dogs)读书笔记(代码片段)

    5.2 在小型数据集上从头开始训练一个卷积神经网络5.2.1深度学习与小数据问题的相关性深度学习的一个基本特性就是能够独立地在训练数据中找到有趣的特征,无须人为的特征工程,而这只在拥有大量训练样本时才能实... 查看详情

    第五章无向概率图模型学习

    马尔科夫随机场(MarkovRandomFields,MRFs)MRFs与Gibbs分布等价。  条件随机场(ConditionalRandomFields,CRFs): CRFs的训练方法:迭代梯度法(IterativeScaling)和L-BFGS迭代梯度法包括:GIS(GeneralizedIterativeScaling),IIS(ImprovedIterat 查看详情

    第五章学习小结

    ...点树的度:结点度的最大值(结点的子树数为结点的度)深度:最大层次数森林:m课不相交树的集合课本上关于树只说明了定义和一些术语,重点内容在于二叉树部分二:二叉树二叉树的性质:深度为k的二叉树最多有2^k-1个结点... 查看详情

    第五章学习小结

    ...:树、二叉树、完美二叉树、偏二叉树,节点关系,树的深度,叶节点等等的定义二,树(二叉树)的基本储存结构(1)用数组,适用于满二叉树(2)链式结构(3)数组加链表式:双亲孩子表示法(代码如下)tyepdefstructcNode ... 查看详情

    第五章学习小结

    ...,也学习了什么是结点的度(即结点的孩子个数),树的深度(即结点度的最大值),但还是主要学习了二叉树,比如二叉树的性质:性质1在二叉树的第i层上至多有2^(i-l)个结点(i>=1)。性质2深度为K的二叉树至多有2^k-1个结点... 查看详情

    神经网络和深度学习笔记-第五章深度神经网络学习过程中的梯度消失问题

    之前的章节,我们利用一个仅包含一层隐藏层的简单神经网络就在MNIST识别问题上获得了98%左右的准确率。我们于是本能会想到用更多的隐藏层,构建更复杂的神经网络将会为我们带来更好的结果。就如同在进行图像模式识别的... 查看详情

    第五章学习小结(代码片段)

    ...径和路径长度、祖先结点、子孙结点、结点的层次、树的深度(注意根结点深度为1,而不是0) 二叉树的定义(五种基本形态)  完美二叉树(满二叉树)、完全二叉树(编号为i的结点与满二叉树中编号为i的结点在... 查看详情

    第五章图的遍历(深度遍历,广度遍历,城市地图,最少转机)

    深度和广度优先搜索:单词分解:首先是搜索        深度和广度:是针对图的遍历而言的图:由顶点和边组成图的遍历:把图中每一个顶点都访问一次一:输入:55(顶点数,边数)1213152435输出:124... 查看详情

    ds第五章学习记录

    二叉树性质在二叉树的第l层上至多有2i-l个结点深度为K的二叉树至多有2k-1个结点 对任何一棵二叉树T,如果其终端结点数为n。度为2的结点数为n2则n。=n2+1。 (结点-1=边)具有n个结点的完全二叉树的深度为llog心+1  &... 查看详情

    第五章学习小结

    ...复杂。在这章我们接触到了更加多的新的术语,例如树的深度,树的结点、兄弟、子孙层次等,这些都需要我们清楚地理解出各自相对应的意思;之后也学习了对于树不同的遍历方法,例如中序遍历:是先遍历左子树再访问根结... 查看详情

    第五章学习小结

    本周学习的新内容为图:在图的课件中学习了用邻接表和邻接矩阵的方式来储存图。对于邻接矩阵,更像是一个二维数组,通过储存0和1的方式来表示度与度之间是否连通。邻接矩阵的固有缺点,对于无向图来说,同一条路会储... 查看详情

    第五章学习小结

    ...学习了树和二叉树的定义,对节点,根节点,叶子结点,深度,度等概念进行了初步的了解。5-4节了解了与二叉树相关的一些性质,其中引出了完全二叉树与满二叉树的概念,从这一节开始也正式开始考虑用存储结构去存储一棵... 查看详情

    tensorflow实战google深度学习框架第五章5.2.1minister数字识别源代码(代码片段)

    1importos2importtab3importtensorflowastf45print"tensorflow5.2"67fromtensorflow.examples.tutorials.mnistimportinput_data89‘‘‘10mnist=input_data.read_data_sets("/asky/tensorflow/mnist_data",one_hot=True 查看详情

    javascript高级程序设计学习笔记第五章上

     第五章 引用类型的值(对象)是引用类型的一个实例。在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起。它也常被称为类,但这种称呼并不妥当。尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具... 查看详情

    第五章学习小结

    ...树(分等级的分类方案都可由一个树结构来表示)2.度与深度:节点的度:该节点拥有几个子树,就为几         &nbs 查看详情