深度学习笔记17_卷积神经网络数据可视化_中间激活

可视化的概念

深度学习模型是“黑盒”,即模型学到的表示很难用人类可以理解的方式来提取和呈现。但是我们现在的学习的卷积伸进网络却可以通过可视化很形象的说明深度学习在卷积神经网络方面可以很表示的,并不是黑盒。目前比较容易理解的三种可视化的方法如下:

  • 可视化卷积神经网络的中间输出(中间激活)

    • 就是可以展示网络中各个卷积层和池化层输出的特征图
    • 理解卷积神经网络连续的层如何对输入进行变换
    • 于初步了解卷积神经网络每个过滤器的含义
  • 可视化卷积神经网络的过滤器

    • 精确理解卷积神经网络中每个过滤器容易接受的视觉模式或视觉概念
  • 可视化图像中类激活的热力图

    • 有助于理解图像的哪个部分被识别为属于某个类别
    • 可以定位图像中的物体

中间激活激活的概念理解

可视化中间激活,是指对于给定输入,展示网络中各个卷积层和池化层输出的特征图。
这样我们就可以通过查看不同层的不同的过滤器最终输出图像的结果,来分析模型是怎么来识别图片的过程,会去识别那些信息,对于哪些信息会保留和过滤都有很好的记录。

这里我们需要做的就是:将这些特征图可视化的正确方法是将每个通道的内容分别绘制成二维图像。这里以猫狗分类的案例-从头训练一个模型为例子来分析。

  • 加载模型
  • 预处理单张图像
# 加载模型猫狗分类的案例-从头训练一个模型
from keras.models import load_model
model = load_model('cats_and_dogs_small_data_2.h5')
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 148, 148, 32)      896       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 72, 72, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 36, 36, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 34, 34, 128)       73856     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 17, 17, 128)       0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 15, 15, 128)       147584    
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 7, 7, 128)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 6272)              0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 6272)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               3211776   
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 513       
=================================================================
Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________
#预处理单张图像
img_path = 'G:/Data/Kaggle/dogcat/smallData/test/cats/cat.1700.jpg'

from 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.

print(img_tensor.shape)

(1, 150, 150, 3)
# 显示测试图像

import matplotlib.pyplot as plt
plt.imshow(img_tensor[0])
plt.show()

output_3_0.png

Keras 模型多输出

创建一个 Keras 模型,以图像批量作为输入,并输出所有卷积层和池化层的激活。 Keras 的 Model 类,模型实例化需要两个参数:一个输入张量(或输入张量的列表)和一个输出张量(或输出张量的列表),得到的类是一个Keras 模型.

输入一张图像,这个模型将返回原始模型前 8 层的激活值.一般情况下,模型可以有任意个输入和输出。这个模型有一个输入和 8 个输出,即每层激活对应一个输出。

from keras import models
#from keras import layers
# 输入一张图像,这个模型将返回原始模型前 8 层的激活值
# 每层激活对应一个输出。
layers_outputs = [layer.output for layer in model.layers[:8]]
# 创建一个模型,给定模型输入,可以返回这些输出
activation_model = models.Model(inputs = model.input,outputs=layers_outputs)
#以预测模式运行模型
activations = activation_model.predict(img_tensor)

first_layer_activation = activations[0]
print(first_layer_activation.shape)
(1, 148, 148, 32)
# 将第 6 和10个通道可视化
import matplotlib.pyplot as plt

plt.matshow(first_layer_activation[0,:,:,6],cmap='viridis')
plt.matshow(first_layer_activation[0,:,:,10],cmap='viridis')

output_7_1.png

output_7_2.png

layer_names = []
for layer in model.layers[:8]:
    layer_names.append(layer)
    
image_per_row = 16

for layer_name,layer_activation in zip(layer_names,activations):
    n_features = layer_activation.shape[-1]
    
    size = layer_activation.shape[1]
    
    n_cols = n_features // image_per_row
    display_grid = np.zeros((size * n_cols,image_per_row * size))
    

    for col in range(n_cols):
        for row in range(image_per_row):
            channel_image = layer_activation[0,:,:,col * image_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')
    
    

第四层block.png

第三层block.png

第二层block.png

第一层block.png

中间激活的结论

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

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


分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!扫码上车!

瓦力人工智能 - 扫码上车

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值