深度学习

卷积神经网络的可视化

2019-05-14  本文已影响0人  庵下桃花仙

可视化中间激活

from keras.models import load_model
model = load_model('cats_and_dogs_small_2.h5')
print(model.summary())  # 作为提醒

# 预处理单张图像
img_path = 'D:/DeepLearning/kaggle/cats_and_dogs_small/test/cats/cat.1700.jpg'

from keras.preprocessing import image  # 将图像处理为一个4D张量
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()
测试的猫图像.png
# 用一个输入张量和一个输出张量将模型实例化
from keras import models

layer_outputs = [layer.output for layer in model.layers[:8]]  # 提取前3层的输出
# 创建一个模型,给定模型输入,可以返回这些输出
activation_model = models.Model(inputs=model.input, outputs=layer_outputs)

使用 keras 的 Model 类,得到的类是一个 Keras 模型,如同 Sequential 模型一样,将特定输入映射为特定输出。Model 类允许有多个输出,Sequential 模型允许一个输入和一个输出。
上述代码,输入一张图像将返回原始模型前 8 层的激活值。

# 以预测模式运行模型
activations = activation_model.predict(img_tensor)  # 返回8个Numpy数组组成的列表,每个层激活对应一个Numpy数组
first_layer_activation = activations[0]
print(first_layer_activation.shape)
(1, 148, 148, 32)
# 将第4个、第7通道可视化
import matplotlib.pyplot as plt

plt.matshow(first_layer_activation[0, :, :, 4], cmap='viridis')
plt.matshow(first_layer_activation[0, :, :, 7], cmap='viridis')
plt.show()
对于测试的猫图像,第一层激活的第4个通道.png
对于测试的猫图像,第一层激活的第7个通道.png

matplotlib.pyplot.matshow 矩阵可视化
这是一个绘制矩阵的函数:matplotlib.pyplot.matshow(A, fignum=None, **kwargs)
A是绘制的矩阵,一个矩阵元素对应一个图像像素。
plt.matshow(Mat, cmap=plt.cm.gray),cmap代表一种颜色映射方式。

# 将每个中间激活的所有通道可视化
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')  # 数据裁剪到0到255内,8位图像节省内存空间
            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')

np.clip()的用法
numpy.clip(a, a_min, a_max, out=None)
参数说明

plt.imshow()
imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, hold=None, data=None, **kwargs)
其中,X变量存储图像,可以是浮点型数组、unit8数组以及PIL图像,如果其为数组,则需满足一下形状:
(1) M X N 此时数组必须为浮点型,其中值为该坐标的灰度;
(2) M X N X 3 RGB(浮点型或者unit8类型)
(3) M X N X 4 RGBA(浮点型或者unit8类型)
参数aspect
aspect:{'equal','auto'}控制轴的纵横比。该方面与图像特别相关,因为它可能使图像失真,即像素不是方形的。

深度神经网络学到表示的一个重要普遍特征:随着层数的加深,层所提取的特征越来越抽象。更高层激活包含关于特定输入的信息越来越少,而关于目标的信息越来越多(猫或狗)。深度神经网络可以有效地作为信息蒸馏管道,输入原始数据(RGB图像),反复对其进行变换,将无关信息过滤掉(图像的具体外观),并放大和细化有用信息(图像的类别)。

上一篇下一篇

猜你喜欢

热点阅读