《Python深度学习》第五章-4(可视化中间激活层)读书笔记

Posted Paul-Huang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Python深度学习》第五章-4(可视化中间激活层)读书笔记相关的知识,希望对你有一定的参考价值。

5.4 卷积神经网络的可视化

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

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

5.4.1 可视化中间激活

  1. 可 视 化 中 间 激 活 \\color{red}可视化中间激活 ,是指对于给定输入, 展 示 网 络 中 各 个 卷 积 层 和 池 化 层 输 出 的 特 征 图 \\color{red}展示网络中各个卷积层和池化层输出的特征图 (层的输出通常被称为该层的激活,即激活函数的输出)。
  2. 我们希望在三个维度对特征图进行可视化: 宽 度 、 高 度 和 深 度 ( 通 道 ) \\color{red}宽度、高度和深度(通道) 。每个通道都对应相对独立的特征,所以将这些特征图可视化的正确方法是将每个通道的内容分别绘制成二维图像
    from tensorflow.keras.models import load_model
    model = load_model('cats_and_dogs_small_1.h5')
    model.summary() # 作为提醒
    
  3. 预处理单张图像
    img_path = 'C:\\\\Users\\\\Administrator\\\\deep-learning-with-python-notebooks-master\\\\cats_and_dogs_small\\\\test\\\\cats\\\\cat.3700.jpg'
    from tensorflow.keras.preprocessing import image
    import numpy as np
    img = image.load_img(img_path, target_size=(150, 150))
    img_tensor = image.img_to_array(img)
    img_tensor = np.expand_dims(img_tensor, axis=0)
    img_tensor /= 255.
    # 其形状为 (1, 150, 150, 3)
    print(img_tensor.shape)
    
    显示测试图像
    import matplotlib.pyplot as plt
    plt.imshow(img_tensor[0])
    plt.show()
    
  4. 将模型实例化
    • 用一个输入张量和一个输出张量列表将模型实例化。使用KerasModel类。
      1. 使用 KerasModel类。为了提取想要查看的特征图,我们需要创建一个 Keras 模型并使用Model类,以图像批量作为输入,并输出所有卷积层和池化层的激活。
      2. Model 类允许模型有多个输出,这一点与 Sequential 模型不同。模型实例化需要两个参数:一个输入张量(或输入张量的列表)和一个输出张量(或输出张量的列表)。
    • 输入一张图像,这个模型将返回原始模型前 8 层的激活值。
      from tensorflow.keras import models
      
      layer_outputs = [layer.output for layer in model.layers[:8]] # 提取前 8 层的输出
      # 创建一个模型,给定模型输入,可以返回这些输出
      activation_model = models.Model(inputs=model.input, outputs=layer_outputs) 
      
  5. 以预测模式运行模型
    # 返回8个Numpy数组组成的列表,每个层激活对应一个 Numpy 数组
    activations = activation_model.predict(img_tensor)
    
    >>>first_layer_activation = activations[0]
    >>>print(first_layer_activation.shape)
    (1, 148, 148, 32)
    
    可知其大小为 148×148 的特征图,有 32 个通道。
  6. 可视化通道
    • 可视化原始模型第一层激活的第 4 个通道。
      import matplotlib.pyplot as plt
      plt.matshow(first_layer_activation[0, :, :, 4], cmap='viridis')
      

      该通道像边界检测器。
    • 将首层第 7 个通道可视化
    • 将每个中间激活的所有通道可视化
# 层的名称,这样你可以将这些名称画到图中
layer_names = []
for layer in model.layers[:8]:
	layer_names.append(layer.name)
images_per_row = 16

# 显示特征图
for layer_name, layer_activation in zip(layer_names, activations):
	n_features = layer_activation.shape[-1] # 特征图中的特征个数
	
	size = layer_activation.shape[1] # 特征图的形状为 (1, size, size, n_features)
	
	n_cols = n_features // images_per_row # 在这个矩阵中将激活通道平铺
	display_grid = np.zeros((size * n_cols, images_per_row * size))
	# 将每个过滤器平铺到一个大的水平网格中
	for col in range(n_cols):
		for row in range(images_per_row):
			channel_image = layer_activation[0,
											:, :,
											col * images_per_row + row]
		# 对特征进行后处理,使其看起来更美观
		channel_image -= channel_image.mean()
		channel_image /= channel_image.std()
		channel_image *= 64
		channel_image += 128
		channel_image = np.clip(channel_image, 0, 255).astype('uint8')
		display_grid[col * size : (col + 1) * size, # 显示网格
					row * size : (row + 1) * size] = channel_image
		scale = 1. / size
		plt.figure(figsize=(scale * display_grid.shape[1],
							scale * display_grid.shape[0]))
	plt.title(layer_name)
	plt.grid(False)
	plt.imshow(display_grid, aspect='auto', cmap='viridis')




中间激活的结论

  • 第 一 层 是 各 种 边 缘 探 测 器 的 集 合 \\color{red}第一层是各种边缘探测器的集合 。在这一阶段,激活几乎保留了原始图像中的所有信息。
  • 随 着 层 数 的 加 深 , 激 活 变 得 越 来 越 抽 象 , 并 且 越 来 越 难 以 直 观 地 理 解 \\color{red}随着层数的加深,激活变得越来越抽象,并且越来越难以直观地理解 。它们开始表示更高层次的概念,比如“猫耳朵”和“猫眼睛”。层数越深,其表示中关于图像视觉内容的信息就越少,而关于类别的信息就越多。
  • 激 活 的 稀 疏 度 ( s p a r s i t y ) 随 着 层 数 的 加 深 而 增 大 \\color{red}激活的稀疏度(sparsity)随着层数的加深而增大 sparsity。在第一层里,所有过滤器都被输入图像激活,但在后面的层里,越来越多的过滤器是空白的。也就是说,输入图像中找不到这些过滤器所编码的模式

随着层数的加深,层所提取的特征变得越来越抽象。更高的层激活包含关于特定输入的信息越来越少,而关于目标的信息越来越多(本例中即图像的类别:猫或狗)。这个跟人类的认知场景很相似,我们认识一个东西也是这样开始的。

深度神经网络可以有效地作为 信 息 蒸 馏 管 道 \\color{red}信息蒸馏管道 (information distillation pipeline),输入原始数据(本例中是 RGB 图像),反复对其进行变换,将无关信息过滤掉(比如图像的具体外观), 并 放 大 和 细 化 有 用 的 信 息 \\color{red}并放大和细化有用的信息 (比如图像的类别)。


以上是关于《Python深度学习》第五章-4(可视化中间激活层)读书笔记的主要内容,如果未能解决你的问题,请参考以下文章

《Python深度学习》第五章-5(可视化过滤器)读书笔记

《Python深度学习》第五章-1(CNN简介)读书笔记

《Python深度学习》第五章-3(预训练)读书笔记

《Python深度学习》第五章-2(Cats_vs_Dogs)读书笔记

第五章学习小结

第五章学习小结