《Python深度学习》第五章-5(可视化过滤器)读书笔记
Posted Paul-Huang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Python深度学习》第五章-5(可视化过滤器)读书笔记相关的知识,希望对你有一定的参考价值。
5.4 卷积神经网络的可视化
卷积神经网络学到的表示非常适合可视化,很大程度上是因为它们是 视 觉 概 念 的 表 示 \\color{red}视觉概念的表示 视觉概念的表示。接下来介绍3种可视化方法。
- 事 中 \\color{blue}事中 事中: 可 视 化 卷 积 神 经 网 络 的 中 间 输 出 ( 中 间 激 活 ) \\color{red}可视化卷积神经网络的中间输出(中间激活) 可视化卷积神经网络的中间输出(中间激活):有助于理解卷积神经网络连续的层如何对输入进行变换,也有助于初步了解卷积神经网络每个过滤器的含义。
- 事 前 \\color{blue}事前 事前: 可 视 化 卷 积 神 经 网 络 的 过 滤 器 \\color{red}可视化卷积神经网络的过滤器 可视化卷积神经网络的过滤器:有助于精确理解卷积神经网络中每个过滤器容易接受的视觉模式或视觉概念。
- 事 后 \\color{blue}事后 事后: 可 视 化 图 像 中 类 激 活 的 热 力 图 \\color{red}可视化图像中类激活的热力图 可视化图像中类激活的热力图:有助于理解图像的哪个部分被识别为属于某个类别,从而可以定位图像中的物体。
5.4.2 可视化卷积神经网络的过滤器
5.4.2.1 可视化过滤器的概念
-
What ?——什么是过滤器可视化?
“在无特定目标类别输入图片下”(实际上需要一副空白图像),展示CNN网络中卷积层里各个 过 滤 器 \\color{red}过滤器 过滤器所响应的视觉模式(即特定过滤器所能过滤出的特定视觉表达,包括点、线不同的排列组台)。 -
Why?——为什么使用过滤器可视化?
- 与中间层激活可视化、类激活热力图等方式相比,过滤器可视化技术无需特定输入图片,即可观察到不同过滤器的特定视觉模式,
- 它可以帮助我们更直观察地展现过滤器的特点,是一种 “ 事 前 ” 可 视 化 分 析 方 案 \\color{blue}“事前”可视化分析方案 “事前”可视化分析方案。
-
How?——如何实现过滤器可视化?
- 从一副空白输入图像开始( 实 际 上 是 随 机 生 成 的 带 有 噪 声 的 灰 度 图 像 \\color{red}实际上是随机生成的带有噪声的灰度图像 实际上是随机生成的带有噪声的灰度图像),
- 将 梯 度 下 降 \\color{red}梯度下降 梯度下降技术应用输入图像的值,其目的是 让 特 定 过 滤 器 的 输 出 响 应 最 大 化 \\color{red}让特定过滤器的输出响应最大化 让特定过滤器的输出响应最大化。
得到的最大化响应图像即为过滤器的视觉模式。
5.4.2.2 可视化过滤器的实战
-
网络对象
VGG16卷积基。
-
输入图像
- 所谓的“空台输入图像其实并不是真的空白图像,而是 一 副 随 机 生 成 的 带 有 噪 声 的 灰 度 图 像 \\color{red}一副随机生成的带有噪声的灰度图像 一副随机生成的带有噪声的灰度图像。
- 需要对随机生成的数组进行Z-SCORE标准化处理、然后再将数组转换为RGB(无符号整型的0-255),我们才会看到真正的带有噪声的灰度图像。
-
基本流程
-
第一个卷积层中第一个过滤器所响应的视觉模式为波尔卡点( polka-dot)图案,即过滤输入图像中相应位置的点状图形。
波尔卡圆点一般是同一大小、同一种颜色的圆点以一定的距离均匀地排列而成。波尔卡这个名字,来源于一种忽叫波尔卡的东欧音乐,倒不是说这些图案像跳动的音符,而是有一段时间很多波尔卡音乐的唱片封套都是以波尔卡圆点图案来装饰的。
-
通 过 可 视 化 , 可 以 了 解 三 类 过 滤 信 息 点 \\color{red}通过可视化,可以了解三类过滤信息点 通过可视化,可以了解三类过滤信息点:
- 形 状 \\color{red}形状 形状
- 位 置 \\color{red}位置 位置
- 颜 色 \\color{red}颜色 颜色
-
-
整体思路
关于“ 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 代码设计
- 代码基本思路
- 代码解释
- 将张量转换为有效图像的实用函数
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 生成某一层中所有过滤器响应模式组成的网格
-
对block3的conv1进行可视化(前64个过滤器)
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_conv1
、block2_conv1
、block3_conv1
、 block4_ conv1
、 block5_conv1
)
- 实验结论
-
b
l
o
c
k
1
中
的
第
1
个
卷
积
层
\\color{red}block1中的第1个卷积层
block1中的第1个卷积层
该层过滤器的视觉模式大致对应 简 单 的 边 缘 、 颜 色 \\color{blue}简单的边缘、颜色 简单的边缘、颜色。 -
b
l
o
c
k
2
中
的
第
1
个
卷
积
层
\\color{red}block2中的第1个卷积层
block2中的第1个卷积层
该层过滤器的视觉模式大致对应 边 缘 、 颜 色 组 合 而 成 的 简 单 纹 理 \\color{blue}边缘、颜色组合而成的简单纹理 边缘、颜色组合而成的简单纹理。 -
更
高
层
b
l
o
c
k
中
的
卷
积
层
\\color{red}更高层block中的卷积层
更高层block中的卷积层
更高层次中的过滤器视觉模式呈现出 自 然 界 中 的 各 种 愈 加 复 杂 的 纹 理 样 式 \\color{blue}自然界中的各种愈加复杂的纹理样式 自然界中的各种愈加复杂的纹理样式,包括羽毛状,眼睛状、树叶状等。
-
b
l
o
c
k
1
中
的
第
1
个
卷
积
层
\\color{red}block1中的第1个卷积层
block1中的第1个卷积层
参考
以上是关于《Python深度学习》第五章-5(可视化过滤器)读书笔记的主要内容,如果未能解决你的问题,请参考以下文章
《Python深度学习》第五章-6(可视化类激活图)读书笔记
《Python深度学习》第五章-2(Cats_vs_Dogs)读书笔记