【深度學習】CNN模型的視覺化-1
阿新 • • 發佈:2019-01-04
CNN模型學到的東西很適合視覺化,這裡介紹三種方法:
- 視覺化CNN模型的中間輸出(中間啟用):幫助我們理解CNN是如何對輸入進行變換,以及CNN每個卷積核的含義
- 視覺化CNN的卷積核:幫助我們理解卷積核容易接受的視覺模式或概念
- 客戶刷影象中類啟用的熱力圖:影象中哪些部分被識別為某個類別,輔助我們定點陣圖像中的物體
載入已儲存的模型的方法
from keras.models import load_model
model = load_model('cats_and_dogs_small_2.h5')
model.summary()
'''
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_6 (Conv2D) (None, 148, 148, 32) 896
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 74, 74, 32) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, 72, 72, 64) 18496
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 36, 36, 64) 0
_________________________________________________________________
conv2d_8 (Conv2D) (None, 34, 34, 128) 73856
_________________________________________________________________
max_pooling2d_8 (MaxPooling2 (None, 17, 17, 128) 0
_________________________________________________________________
flatten_2 (Flatten) (None, 36992) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 36992) 0
_________________________________________________________________
dense_3 (Dense) (None, 512) 18940416
_________________________________________________________________
dense_4 (Dense) (None, 1) 513
=================================================================
Total params: 19,034,177
Trainable params: 19,034,177
Non-trainable params: 0
'''
處理待載入的模型的圖片
# 預處理單張影象
img_path = './data/cats_and_dogs_small/test/cats/cat.1700.jpg'
from keras.preprocessing import image
import numpy as np
img = image.load_img(img_path, target_size=(150, 150)) # 載入為Image物件
img_tensor = image.img_to_array(img) # 使用Numpy處理為張量
img_tensor.shape # (150, 150, 3)
img_tensor = np.expand_dims(img_tensor, axis=0) # 新增一個軸,擴充套件為4D張量
img_tensor.shape # (1, 150, 150, 3)
img_tensor /= 255. # 縮放
# 顯示圖片
import matplotlib.pyplot as plt
plt.imshow(img_tensor[0])
plt.show()
檢視特徵圖
為了提取想要檢視的特徵圖,我們需要建立一個Keras模型,以影象批量作為輸入,同時輸出所有卷積層和池化層的啟用結果。
這裡需要用到的是Keras的Model
類,不是我們建立模型時用到的Sequential
Model
類允許模型有多個輸出。而Sequential
不行。**之前的模型都是,一端進一端出,即一個輸入和一個輸出。
# 使用Model類建立模型
# 輸入一張影象,模型輸出前8層的啟用值
from keras import models
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(img_tensor) # 返回8個Numpy陣列組成的列表,每個Numpy陣列對應的是每層的輸出
activations[0].shape # (1, 148, 148, 32)
# 返回的結果是148x148大小,且有32個通道
# 我們繪製啟用層的第4個通道
import matplotlib.pyplot as plt
plt.matshow(activations[0][0, :, :, 4], cmap='viridis')
繪製全部輸出的全部通道:
# 繪製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] # (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')
剩下的兩類繪圖後面再補全。
END.
參考:
《Deep Learning with Python》