天天看點

keras可視化中間層特征

可視化中間層不同通道特征及所有卷積層特征

  1. 讀取圖檔
#讀取圖檔
from tensorflow.keras.preprocessing import image
path='xxx.jpg'
img = image.load_img(path,target_size=(224,224))
img=image.img_to_array(img)
x = np.expand_dims(img, axis=0)
x.shape
# output:(1,224,224,3)
           
  1. 預訓練模型

    keras官方提供了很多預訓練模型作為api接口,介紹詳細并且可以選擇是否需要fc層、是否預訓練等,并将模型對應的預訓練也封裝,可以直接調用該模型的預訓練preprocess_input。

    官方網址有詳細案例及參數解釋

    官方網址:https://keras-cn.readthedocs.io/en/latest/other/application/

# vgg模型
import tensorflow as tf
from tensorflow.keras.applications import VGG16
from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions
import os
x=preprocess_input(x)
# include_top表示是否需要全連接配接層
# 從接口擷取模型
vgg16=VGG16(weights='imagenet', include_top=True)
# 将資料放入模型
predict = vgg16.predict(x)
# decode_predictions輸出類别機率
print('prediction: ',decode_predictions(predict))

# 可視化模型
from tensorflow.keras.utils import plot_model
plot_model(ResNet50(),show_shapes=True)
vgg16.summary()
           
  1. 利用VGG16提取特征,可視化某一層所有通道
# 抽取vgg所有層,即要顯示的層
from collections import OrderedDict
layer_dict=OrderedDict()
# vgg第一層為input層,上述官網中也有抽取特征的方法
for layer in vgg16.layers[1:]:
    layer_dict[layer.name]=layer
    
from tensorflow.keras import backend as K
# 将網絡中層輸出出來
def get_activations(model, layer,input_img_data):
    activations_f=K.function([model.layers[0].input],[layer.output])
    activations=activations_f((input_img_data,False))
    return activations

#輸出某一層不同通道的圖檔
layer_name='block1_conv2'
layer=layer_dict[layer_name]
activations=get_activations(vgg16,layer,x)
activation = activations[0]
activated_img = activation[0]
fig=plt.figure(figsize=(20,20))
n=8
# 一層中不同通道的圖檔
for i in range(8):
    for j in range(8):
        idx=n*i+j
        ax=fig.add_subplot(n,n,idx+1)
        ax.imshow(activated_img[:,:,idx])
           

結果:

keras可視化中間層特征

結果可以很明顯的看到每個通道學習的并不是一種特征,從亮度、輪廓等多方面學習

  1. 抽取每層卷積層特征
# 抽取特征時需判斷是否是卷積層,僅抽取卷積層特征
layers_conv = OrderedDict()
for layer in vgg16.layers:
    if 'conv' in layer.name:
        layers_conv[layer.name] = layer
    	print(layer.name)
activation_list=[]
for name, layer in layers_conv.items():
    activations_f = K.function([vgg16.layers[0].input], [layer.output,])
    activations = activations_f((x, False))
    activation_list.append(activations[0][0])
 
 
# 顯示每個卷積層特征
from PIL import Image
idx=0
fig_2 = plt.figure(figsize=(10, 10))
for activation in activation_list:
    feature_map = np.mean(activation,axis=2)
    matplotlib.image.imsave('{0}.png'.format(idx), feature_map)
    ax = fig_2.add_subplot(4, 4, idx+1)
    ax.imshow(feature_map[:,:])
    idx=idx+1
           

繼續閱讀