卷积神经网络的可视化

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

可视化中间激活

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)
参数说明

  • a : 输入的数组
  • a_min: 限定的最小值 也可以是数组 如果为数组时 shape必须和a一样
  • a_max:限定的最大值 也可以是数组 shape和a一样
  • out:剪裁后的数组存入的数组

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'}控制轴的纵横比。该方面与图像特别相关,因为它可能使图像失真,即像素不是方形的。

  • equal:确保宽高比为1.像素将为正方形(除非像素大小在使用* extent *的数据坐标中明确地为非正方形)。
  • auto:轴保持固定,方向调整,使数据适合轴。通常,这将导致非方形像素。

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容