深度学习模型学到的表示很难用人类可以理解的方式来提取和呈现。本文基于猫狗分类任务对所训练的模型进行可视化,对模型中特征图以及滤波器进行可视化,深化卷积神经网络特征提取的理解。
对于给定输入,利用已训练好的分类模型,展示网络中各个卷积层和池化层输出的特征图。
输入一张用于可视化的图片:
- img_path='/Users/深度学习/cats_and_dogs_small/test/cats/cat.1700.jpg'
- from keras.preprocessing import image #将图像处理成4D张量
- import numpy as np
- import matplotlib.pyplot as plt
- 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)
- #显示测试图像
- plt.imshow(img_tensor[0])
- plt.show()
结果如图所示:
输出模型前8层的特征提取图(输入一个图像,这个模型系那个会返回原始模型前8层的激活值):
- from keras import models
- layer_outputs=[layer.output for layer in model.layers[:8]]
- activation_model=models.Model(inputs=model.input,outputs=layer_outputs)
其中,模型第一层的特征图总共32个通道,下面是第4个和第7个通道的可视化。
- activations=activation_model.predict(img_tensor)
- first_layer_activation=activations[0]
- print(first_layer_activation.shape)
- plt.matshow(first_layer_activation[0,:,:,4],cmap='viridis')
- plt.matshow(first_layer_activation[0,:,:,7],cmap='viridis')
左图为4channel,右图为7channel,结果如图所示:
模型前8层特征图的所有通道可视化:
- 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]
-
- 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')
结果如图所示:
等等后面的由于太大了截不完整,就不展示了,剩下的留给大家自己探索。
可以看出,随着层数的加深,层所提取的特征变得越来越抽象,更高的层特征图包含越来越少的输入信息,而关于类别的信息越来越多。这与人类和动物感知世界的方式类似:人类观察一个场景几秒钟后,可以记住其中有哪些抽象物体(比如自行车、树),但记不住这些事物的具体外观。