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

5.4 卷积神经网络的可视化

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

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

5.4.2 可视化卷积神经网络的过滤器

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

5.4.2.1 可视化过滤器的概念

  1. What ?——什么是过滤器可视化?
    “在无特定目标类别输入图片下”(实际上需要一副空白图像),展示CNN网络中卷积层里各个 过 滤 器 \color{red}过滤器 所响应的视觉模式(即特定过滤器所能过滤出的特定视觉表达,包括点、线不同的排列组台)

  2. Why?——为什么使用过滤器可视化?

    • 与中间层激活可视化、类激活热力图等方式相比,过滤器可视化技术无需特定输入图片,即可观察到不同过滤器的特定视觉模式,
    • 它可以帮助我们更直观察地展现过滤器的特点,是一种 “ 事 前 ” 可 视 化 分 析 方 案 \color{blue}“事前”可视化分析方案
  3. How?——如何实现过滤器可视化?

    • 从一副空白输入图像开始( 实 际 上 是 随 机 生 成 的 带 有 噪 声 的 灰 度 图 像 \color{red}实际上是随机生成的带有噪声的灰度图像 ),
    • 梯 度 下 降 \color{red}梯度下降 技术应用输入图像的值,其目的是 让 特 定 过 滤 器 的 输 出 响 应 最 大 化 \color{red}让特定过滤器的输出响应最大化

    得到的最大化响应图像即为过滤器的视觉模式。

5.4.2.2 可视化过滤器的实战

  1. 网络对象
    VGG16卷积基。
    《Python深度学习》第五章-5(可视化过滤器)读书笔记_第2张图片

  2. 输入图像

    • 所谓的“空台输入图像其实并不是真的空白图像,而是 一 副 随 机 生 成 的 带 有 噪 声 的 灰 度 图 像 \color{red}一副随机生成的带有噪声的灰度图像
    • 需要对随机生成的数组进行Z-SCORE标准化处理、然后再将数组转换为RGB(无符号整型的0-255),我们才会看到真正的带有噪声的灰度图像。
      《Python深度学习》第五章-5(可视化过滤器)读书笔记_第3张图片
  3. 基本流程
    《Python深度学习》第五章-5(可视化过滤器)读书笔记_第4张图片

    • 第一个卷积层中第一个过滤器所响应的视觉模式为波尔卡点( polka-dot)图案,即过滤输入图像中相应位置的点状图形。

      波尔卡圆点一般是同一大小、同一种颜色的圆点以一定的距离均匀地排列而成。波尔卡这个名字,来源于一种忽叫波尔卡的东欧音乐,倒不是说这些图案像跳动的音符,而是有一段时间很多波尔卡音乐的唱片封套都是以波尔卡圆点图案来装饰的。

    • 通 过 可 视 化 , 可 以 了 解 三 类 过 滤 信 息 点 \color{red}通过可视化,可以了解三类过滤信息点

      • 形 状 \color{red}形状
      • 位 置 \color{red}位置
      • 颜 色 \color{red}颜色
  4. 整体思路
    《Python深度学习》第五章-5(可视化过滤器)读书笔记_第5张图片
    关于“ n 次 梯 度 更 新 \color{red}n次梯度更新 n”的思路:

    • 构 建 一 个 损 失 函 数 ( m e a n ( l o s s ) ) \color{red}构建一个损失函数(mean(loss)) mean(loss)
    • 通 过 随 机 梯 度 下 降 调 节 带 有 噪 声 的 灰 度 图 像 \color{red}通过随机梯度下降调节带有噪声的灰度图像
    • 不 断 迭 代 , 让 损 失 最 大 化 ( 即 该 过 滤 器 的 激 活 值 最 大 ) \color{red}不断迭代,让损失最大化(即该过滤器的激活值最大) ,()

5.4.2.3 代码设计

  1. 代码基本思路
    《Python深度学习》第五章-5(可视化过滤器)读书笔记_第6张图片
  2. 代码解释
    《Python深度学习》第五章-5(可视化过滤器)读书笔记_第7张图片
  3. 将张量转换为有效图像的实用函数
    def deprocess_image(x):
    	# 对张量做标准化,使其均值为0,标准差为 0.1
    	x -= x.mean()
    	x /= (x.std() + 1e-5)
    	x *= 0.1
    	# 将 x 裁切( clip )到 [0, 1] 区间
    	x += 0.5
    	x = np.clip(x, 0, 1)
    	# 将 x 转换为 RGB 数组
    	x *= 255
    	x = np.clip(x, 0, 255).astype('uint8')
    	return x
    

5.4.2.4 生成过滤器可视化的整体函数

from tensorflow.keras.applications import VGG16
from tensorflow.keras import backend as K
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
tf.compat.v1.disable_eager_execution()

model = VGG16(weights='imagenet',
			include_top=False)
layer_name = 'block3_conv1'
filter_index = 0

# 将张量转换为有效图像的实用函数
def deprocess_image(x):
	# 对张量做标准化,使其均值为0,标准差为 0.1
	x -= x.mean()
	x /= (x.std() + 1e-5)
	x *= 0.1
	# 将 x 裁切( clip )到 [0, 1] 区间
	x += 0.5
	x = np.clip(x, 0, 1)
	# 将 x 转换为 RGB 数组
	x *= 255
	x = np.clip(x, 0, 255).astype('uint8')
	return x

def generate_pattern(layer_name, filter_index, size=150):
	# 构建一个损失函数,将该层第 n 个过滤器的激活最大化
	layer_output = model.get_layer(layer_name).output
	loss = K.mean(layer_output[:, :, :, filter_index])
	# 计算这个损失相对于输入图像的梯度
	grads = K.gradients(loss, model.input)[0]
	# 标准化技巧:将梯度标准化
	grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
	# 返回给定输入图像的损失和梯度
	iterate = K.function([model.input], [loss, grads])
	# 从带有噪声的灰度图像开始
	input_img_data = np.random.random((1, size, size, 3)) * 20 + 128.
	# 运行 40 次,梯度上升
	step = 1.
	for i in range(40):
		loss_value, grads_value = iterate([input_img_data])
		input_img_data += grads_value * step
	img = input_img_data[0]
	return deprocess_image(img)

plt.imshow(generate_pattern('block3_conv1', 0))

从图可知: block3_conv1 层第 0 个过滤器响应的是 波 尔 卡 点 \color{red}波尔卡点 polka-dot)图案。

5.4.2.5 生成某一层中所有过滤器响应模式组成的网格

  1. 对block3的conv1进行可视化(前64个过滤器)
    《Python深度学习》第五章-5(可视化过滤器)读书笔记_第8张图片

    size = 64 #一个格的像素大小,该卷积层
    margin = 5 #格与格之间间隔
    #用于保存过滤器图像矩阵结果,该卷积层共有64个过滤器,故设置一个8 x 8的矩阵,每一个网格由64 x 64的像素构成
    # 空图像(全黑色),用于保存结果
    results = np.zeros((8*size + 7*margin, 8*size + 7*margin, 3))
    
    
    #填充网格
    for i in range(8): #遍历 results 网格的行
        for j in range(8): # 遍历 results 网格的列
        	# 生成 layer_name 层第i +(j * 8)个过滤器的模式
            filter_img = generate_pattern(layer_name, j + ( i * 8 ), size = 64)
            # 将结果放到 results 网格第 (i, j) 个方块中
            horizontal_start = i * size + i * margin
            hortzontal_end = horizontal_start + size
            vertical_start = j * size + j * margin
            vertical_end = vertical_start + size
            
            results[horizontal_start:hortzontal_end, vertical_start:vertical_end, :] = filter_img
    # 显示 results 网格        
    plt.figure(figsize = (20,20))
    plt.imshow(results.astype('uint8'))
    plt.show()
    

得出的结果如图:

2. 对每个block中的conv1进行可视化
为了简单起见,我们只查看每一层的前 64 个过滤器,并只查看每个卷积块的第一层(即 block1_conv1block2_conv1block3_conv1block4_ conv1block5_conv1

  1. 实验结论
    • b l o c k 1 中 的 第 1 个 卷 积 层 \color{red}block1中的第1个卷积层 block11
      该层过滤器的视觉模式大致对应 简 单 的 边 缘 、 颜 色 \color{blue}简单的边缘、颜色
    • b l o c k 2 中 的 第 1 个 卷 积 层 \color{red}block2中的第1个卷积层 block21
      该层过滤器的视觉模式大致对应 边 缘 、 颜 色 组 合 而 成 的 简 单 纹 理 \color{blue}边缘、颜色组合而成的简单纹理
    • 更 高 层 b l o c k 中 的 卷 积 层 \color{red}更高层block中的卷积层 block
      更高层次中的过滤器视觉模式呈现出 自 然 界 中 的 各 种 愈 加 复 杂 的 纹 理 样 式 \color{blue}自然界中的各种愈加复杂的纹理样式 ,包括羽毛状,眼睛状、树叶状等。

参考

  1. 《Python深度学习》读书笔记系列之ch5.4.1

你可能感兴趣的:(Python学习,可视化,卷积,python,深度学习,神经网络)