文章目录

  • 可视化卷积神经网络
    • 2-25 读入模组
    • 5-26 观察图像
    • 观察卷积层特征提取
    • 5-27 建立多输出模型观察输出
    • 5-28 显示图像
    • 5-29 打印全部的识别图
    • 5-32 为过滤器的可视化定义损失张量
    • 5-33 获取损失相对于输入的梯度
    • 5-34 梯度标准化
    • 5-35 给定输入numpy值,得到numpy输出
    • 5-36 通过随机梯度下降将让损失最大化
    • 5-37 张量转换为有效图像的实用函数
    • 5-38 生成过滤器可视化的函数
    • 5-39 生成某一层中所有过滤器响应模式组成的网络
    • 总结
  • 写在最后

可视化卷积神经网络


一直以来,人们都习惯将卷积神经网络的训练过程称为黑盒子,而我们现在就要解开这个盒子的秘密,进一步研究卷积神经网络在训练的过程中都做了些什么。

2-25 读入模组


from keras.models import load_modelmodel = load_model('cats_and_dogs_small_2.h5')# 观察模型基本概况
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_5 (Conv2D)            (None, 148, 148, 32)      896
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 74, 74, 32)        0
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 72, 72, 64)        18496
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 36, 36, 64)        0
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 34, 34, 128)       73856
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 17, 17, 128)       0
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 15, 15, 128)       147584
_________________________________________________________________
max_pooling2d_8 (MaxPooling2 (None, 7, 7, 128)         0
_________________________________________________________________
flatten_2 (Flatten)          (None, 6272)              0
_________________________________________________________________
dropout_2 (Dropout)          (None, 6272)              0
_________________________________________________________________
dense_3 (Dense)              (None, 512)               3211776
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 513
=================================================================
Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________

5-26 观察图像


# 读入图像img_path = r'E:\code\PythonDeep\DataSet\dogs-vs-cats\train\cat.1700.jpg'# 将图像处理为一个4D的tenser张量
from keras.preprocessing import image
import numpy as npimg = 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# 打印图像张量
print(img_tensor.shape)
(1, 150, 150, 3)
# 打印图像
import matplotlib.pyplot as plt# 注意这是一个4D张量
plt.imshow(img_tensor[0])
plt.show()

观察卷积层特征提取


为了能够进一步抽取图像,我们创建了一个Keras的模型,然后将图片输入进去,在输入的过程中,我们在观察特定的卷积层的输出

5-27 建立多输出模型观察输出


from keras import models# 提取最顶层前8层的输出
# 注意,这里是“前”8层,也就是说这些输出的层是叠加态的
layer_outputs = [layer.output for layer in model.layers[:8]]# 将数据喂给模型
activation_model = models.Model(inputs = model.input, outputs = layer_outputs)
# 返回一个5个元素的Numpy的一元数组
activations = activation_model.predict(img_tensor)
# 打印输出图像的信息
first_layer_activation = activations[0]
print(first_layer_activation.shape)
(1, 148, 148, 32)

5-28 显示图像


import matplotlib.pyplot as plt# 显示在第三层的图像
plt.matshow(first_layer_activation[0, :, :, 3], cmap = 'viridis')
plt.show()

我们继续深入,观察第29层的图像

plt.matshow(first_layer_activation[0, :, :, 29], cmap='viridis')
plt.show()

可以看到,随着层次的加深,卷积网络所识别的部位更加具体了

5-29 打印全部的识别图


import keras# 存储层数
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]# 图像的张量形状 (1, size, size, n_features)size = layer_activation.shape[1]# 对矩阵中的每一个设置激活通道n_cols = n_features // images_per_rowdisplay_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 *= 64channel_image += 128channel_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. / sizeplt.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')plt.show()





5-32 为过滤器的可视化定义损失张量


from keras.applications import VGG16
from keras import backend as Kmodel = VGG16(weights = 'imagenet', include_top = False)layer_name = 'block3_conv1'
filter_index = 0layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])

5-33 获取损失相对于输入的梯度


grads = K.gradients(loss, model.input)[0] # 返回一个张量列表,只保留第一个元素

5-34 梯度标准化


grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)

5-35 给定输入numpy值,得到numpy输出


iterate = K.function([model.input], [loss, grads])import numpy as np
loss_value, grads_value = iterate([np.zeros((1, 150, 150, 3))])

5-36 通过随机梯度下降将让损失最大化


input_img_data = np.random.random((1, 150, 150, 3)) * 20 + 128.# 每次梯度更新的步长
step = 1.for i in range(40):loss_value, grad_value = iterate([input_img_data])input_img_data += grads_value * step

5-37 张量转换为有效图像的实用函数


def deprocess_image(x):# 对张量作标准化x -= x.mean()x /= (x.std() + 1e-5)x *= 0.1# 将x裁切到区间[0, 1]之间x += 0.5x = np.clip(x, 0, 1)# 将x转换为RGB数组x *= 255x = np.clip(x, 0, 255).astype('uint8') # 对数据类型进行转换    return x

5-38 生成过滤器可视化的函数


import matplotlib.pyplot as plt
# 一个可以将过滤器转换为图像并进行可视化的函数
def generate_pattern(layer_name, fliter_index, size = 150):# 构建一个损失函数,将第n个过滤器最大化layer_output = model.get_layer(layer_name).outputloss = 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 * stepimg = input_img_data[0]return deprocess_image(img)
<matplotlib.image.AxesImage at 0x281d5d20240>


从上图可知,block3_conv1层的0个过滤器是波尔卡点,我们接下来将查看每一层的前64个过滤器,我们将输出放在一个88的网格种,每个网格是64像素64像素


5-39 生成某一层中所有过滤器响应模式组成的网络


for layer_name in ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1']:size = 64margin = 5# 生成一个空图像,用于保存结果results = np.zeros((8 * size + 7 * margin, 8 * size + 7 * margin, 3))# 遍历results网格的行for i in range(8):# 遍历results网格的列for j in range(8):# 生成layer_name层第 i + 8 个过滤器的模式filter_img = generate_pattern(layer_name, i + (j * 8), size = size)# 将结果放到results网格的第(i,j)个方块中horizontal_start = i * size + i * marginhorizontal_end = horizontal_start + sizevectical_start = j * size + j * marginvectical_end = vectical_start + size# 添加结果results[horizontal_start : horizontal_end,vectical_start : vectical_end, :] = filter_img# 显示result网格plt.figure(figsize = (20, 20))# plt.imshow(results) # 这句话需要改,输出为0-1之间的值plt.imshow(results.astype('uint8'))# for layer_name in ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1']:
#     size = 64
#     margin = 5#     # This a empty (black) image where we will store our results.
#     results = np.zeros((8 * size + 7 * margin, 8 * size + 7 * margin, 3))#     for i in range(8):  # iterate over the rows of our results grid
#         for j in range(8):  # iterate over the columns of our results grid
#             # Generate the pattern for filter `i + (j * 8)` in `layer_name`
#             filter_img = generate_pattern(layer_name, i + (j * 8), size=size)#             # Put the result in the square `(i, j)` of the results grid
#             horizontal_start = i * size + i * margin
#             horizontal_end = horizontal_start + size
#             vertical_start = j * size + j * margin
#             vertical_end = vertical_start + size
#             results[horizontal_start: horizontal_end, vertical_start: vertical_end, :] = filter_img#     # Display the results grid
#     plt.figure(figsize=(20, 20))#     plt.imshow(results.astype('uint8'))
# #     plt.imshow(results)
#     plt.show()



总结


  • 这些过滤器可视化包含卷积神经网课层如何观察世界,卷积神经网络的每一层都学习了一组过滤器,然后将输入表示为过滤器的组合
  • 随着输入的加深,卷积神经网络的过滤器也变得越来越复杂,越来越精细
  • 模型的第一层:简单的方向边缘以及颜色
  • 第二层:颜色组合以及简单纹理
  • 更高层的过滤器有更高的特征,如羽毛、眼睛、树叶等

写在最后

注:本文代码来自《Python 深度学习》,做成电子笔记的方式上传,仅供学习参考,作者均已运行成功,如有遗漏请练习本文作者

各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟!
<(^-^)>
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位同志作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知

《Python 深度学习》刷书笔记 Chapter 5 Part-4 卷积神经网络的可视化(Fillter)相关推荐

  1. Python深度学习一书中: 8.4代码VAE在tensorflow2.0错误‘lambda_1/random_normal/shape‘的解决方案

    Python深度学习一书中: 8.4代码VAE在tensorflow2.0下会有Duplicate node name in graph: 'lambda_1/random_normal/shape' ...

  2. 【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]

    [神经网络与深度学习]CIFAR-10数据集介绍,并使用卷积神经网络训练模型--[附完整代码] 一.CIFAR-10数据集介绍 1.1 CIFAR-10数据集的内容 1.2 CIFAR-10数据集的结 ...

  3. 《Python 深度学习》刷书笔记 Chapter 3 预测房价:回归问题

    文章目录 波士顿房价数据集 3-24 加载波士顿房价数据 3-25 数据标准化 3-26 模型定义 3-27 K折验证 3-28 训练500轮,保存每折的验证结果 3-29 计算所有轮次茨种的K折验证 ...

  4. 《Python 深度学习》刷书笔记 Chapter 8 Part-1 生成式深度学习

    文章目录 生成式深度学习 8-1 对于不同的softmax温度,对概率进行重新加权 实现字符级的LSTM文本生成 8-2 下载并解析初始文本文件 8-3 将字符序列向量化 8-4 用于预测下一个字符的 ...

  5. 《Python 深度学习》刷书笔记 Chapter 4 关于电影评论模型的进一步探讨

    文章目录 电影评论模型的进一步改进 4-3 原始模型 4-4 容量更小的模型 4-5 容量更大的模型 4-6 向模型中添加L2权重正则化 写在最后 电影评论模型的进一步改进 我们将在这一节使用实验的方 ...

  6. 吴恩达《神经网络与深度学习》精炼笔记(4)-- 浅层神经网络

    上节课我们主要介绍了向量化.矩阵计算的方法和python编程的相关技巧.并以逻辑回归为例,将其算法流程包括梯度下降转换为向量化的形式,从而大大提高了程序运算速度.本节课我们将从浅层神经网络入手,开始真 ...

  7. 【深度学习基础】一步一步讲解卷积神经网络

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送 本文转自:一步一步讲解卷积神经网络 卷积神经网络(Convoluti ...

  8. 《Python深度学习》读书笔记:第1章 什么是深度学习

    目录 第1章 什么是深度学习 1.1 人工智能.机器学习与深度学习 1.1.1 人工智能 1.1.2 机器学习 1.1.3 从数据中学习表示 1.1.4 深度学习之"深度" 1.1 ...

  9. 《Python深度学习》读书笔记

    第一章 1. 人工智能.机器学习.深度学习之间的关系 2. 人工智能:将通常由人类完成的智力任务自动化. 3. 机器学习 第二章 keras实现mnist识别 from keras.datasets ...

最新文章

  1. 2022-2028年中国冶金工业节能减排投资分析及前景预测报告
  2. python列表、元组、字典和集合的算法时间_27.Python列表(list)、元组(tuple)、字典(dict)和集合(set)详解...
  3. ImagesSprite V1.1.1 Beta发布
  4. 12.Bridge-桥接模式
  5. 主流HTML5游戏框架的分析和对比(Construct2、ImpactJS、CreateJS、Cocos2d-html5……)
  6. ev3编码软件linux,机器人编程软件下载 乐高ev3机器人编程软件(LEGO MINDSTORMS EV3 Home Edition)V1.3.1 中文安装版 下载-脚本之家...
  7. 证明矩阵的秩=行秩=列秩
  8. 基于MDK1808-EK_T70开发板的miniGUI应用程序演示03: ads1110热电偶温度传感器
  9. Mixpanel接入
  10. 双色汉诺塔算法的证明——数学归纳法
  11. 转:Android实时获取音量(单位:分贝)
  12. Windows 10 设置开机自动连接宽带
  13. Win11找不到gpedit.msc怎么办?Win11无法打开gpedit.msc解决教程
  14. 宝宝长牙发烧怎么办?会自己退吗?
  15. 常见的考勤管理系统有哪些功能?
  16. 哈工大pyltp安装和使用方法
  17. 【 简化的插入排序 】 本题要求编写程序,将一个给定的整数插到原本有序的整数序列中,使结果序列仍然有序
  18. 大型网站服务器容量规划(一)
  19. 【PyTorch基础教程29】DIN模型
  20. 边缘保留滤波(EPF)

热门文章

  1. 函数formatDatetime的使用及说明
  2. vue3.0+vant3仿快手/抖音短视频|Vue3+Vite2聊天/直播实例
  3. python转码方法_python转码问题
  4. 不知道血糖仪哪种准确度高?快来看看这篇文章吧
  5. o2o模式的未来在哪里?
  6. JavaScript与Java的姐妹情缘
  7. Excel批量删除含有某关键字的多个工作表
  8. 复旦数据院副院长阳德青:知识图谱在个性化推荐系统中的应用
  9. 用代码告诉你为什么努力工作却不能涨薪水
  10. 计算机专业的考研英语作文,2019计算机考研英语作文复习得分攻略