赞
踩
关于图像处理方面,深度学习的模型就像是一个“黑盒”,我们只能看到输入和输出的图像,那么在中间经过每个网络层处理的图像我们一般看不到,因此就有了可视化中间激活这个概念。
所谓可视化中间激活就是将网络中各个卷积层和池化层输出的特征图进行可视化展示,我们可以从中了解到网络中每一个过滤器的作用是什么。通过下面例子可以更好的了解到这个概念。
在这之前我想先说明本文章使用的网络结构,以免后面更好的理解:
下面为不同网络层的所有通道的可视化图像
在上面三个图中,我们分别展示了三个层的可视化(注意,这里并未列举出所有层的可视化图像,只是任选了三个层)。我们可以看到随着层数的加深,层提取的特征越来越抽象,可能会从一开始提取猫的轮廓特征,到后面提取的越来越详细,比如耳朵、眼睛等等,因此层数越深,其表示关于图像视觉直观的内容的就越来越少,而关于类别的信息就会越来越多。另外我们可以看到,在后面的层里,越来越多的过滤器是空白的,也就是说输入图像中找不到这些过滤器编码的模式。
import tensorflow as tf import os,shutil import numpy as np import matplotlib.pylab as plt import matplotlib.pyplot as plt from keras import models from keras import layers from keras import optimizers from keras.preprocessing.image import ImageDataGenerator from keras.preprocessing import image img_path = 'C:/1/PCProgram/pythonProject1/result/train/cats/cat.247.jpg'#图像路径 #将图像预处理为一个4D张量 img = image.load_img(img_path,target_size=(150,150)) image_tensor = image.img_to_array(img)#将图片转化为数组 image_tensor = np.expand_dims(image_tensor,axis=0) image_tensor /=255. #定义模型 model=models.Sequential() model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(150,150,3))) model.add(layers.MaxPool2D(2,2)) model.add(layers.Conv2D(64,(3,3),activation='relu')) model.add(layers.MaxPool2D(2,2)) model.add(layers.Conv2D(128,(3,3),activation='relu')) model.add(layers.MaxPool2D(2,2)) model.add(layers.Conv2D(128,(3,3),activation='relu')) model.add(layers.MaxPool2D(2,2)) model.add(layers.Flatten()) model.add(layers.Dropout(0.5)) model.add(layers.Dense(512,activation='relu')) model.add(layers.Dense(1,activation='sigmoid')) #模型编译 model.compile(loss='binary_crossentropy', optimizer=tf.keras.optimizers.RMSprop(lr=1e-4), metrics=['acc']) #用一个输入张量和一个输出张量列表将模型实例化 layer_outputs = [layer.output for layer in model.layers[:8]]#提取前8层的输出 activation_model = models.Model(inputs=model.input,outputs=layer_outputs)#创建一个模型,给定模型输入,可以返回这些输出 activations = activation_model.predict(image_tensor)#每个层激活对应一个numpy数组 #----------将每个中间激活的所有通道可视化------------- #图的名称,下面以一个for循环可将每一个网络层的名称画到图中 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') #显示网格 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') plt.show()
-------------------------------------------------------------------------------------------------------------
PS:本文章是个人对书目《Python 深度学习》([美]弗朗索瓦.肖莱著)某章节学习复习专用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。