深層学習用ライブラリKeras CNN中間層を見てみたい

In [1]:
from sklearn.datasets        import fetch_lfw_people
from sklearn.model_selection import train_test_split
from sklearn.preprocessing   import StandardScaler, MinMaxScaler
from matplotlib import pyplot as plt

# Kerasからモデル作成用モジュール
from tensorflow.keras       import models, optimizers,layers, utils

import numpy as np
np.set_printoptions(precision=3) # 表示桁数を少数点以下2桁にします

# データロード
lfw = fetch_lfw_people(data_home='./scikit_learn_data/', min_faces_per_person=100, resize=0.5)

データの前処理

In [2]:
X = lfw.data
y = lfw.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
v,h = lfw.images.shape[1:3] # 画像の垂直・水平サイズを保持する
n_train = X_train.shape[0]  # 学習データ数を保持する
n_test  = X_test.shape[0]   # 検証データ数を保持する

# 標準化と正規化
sc = StandardScaler()
sc.fit(X_train)
X_train_sc = sc.transform(X_train)
X_test_sc  = sc.transform(X_test)

ms = MinMaxScaler(feature_range=(0,1))
ms.fit(X_train_sc)
X_train_sc = ms.transform(X_train_sc)
X_test_sc  = ms.transform(X_test_sc)

X_train_sc = X_train_sc.reshape([n_train, v, h, 1])
X_test_sc  = X_test_sc.reshape([n_test, v, h, 1])

# 正解データをカテゴリ変数化する(One-Hot Encoding)
y_train_cat = utils.to_categorical(y_train,5)
y_test_cat  = utils.to_categorical(y_test,5)

保存したモデルHDF5ファイルをロードする

In [3]:
model = models.load_model('./model_cnn_adam.h5')
In [4]:
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 60, 45, 32)        320       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 58, 43, 32)        9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 29, 21, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 29, 21, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 27, 19, 64)        18496     
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 25, 17, 64)        36928     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 12, 8, 64)         0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 12, 8, 64)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 6144)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               1573120   
_________________________________________________________________
dropout_3 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 5)                 1285      
=================================================================
Total params: 1,639,397
Trainable params: 1,639,397
Non-trainable params: 0
_________________________________________________________________
In [5]:
model.layers
Out[5]:
[<tensorflow.python.keras.layers.convolutional.Conv2D at 0x2487a432198>,
 <tensorflow.python.keras.layers.convolutional.Conv2D at 0x2487a432ef0>,
 <tensorflow.python.keras.layers.pooling.MaxPooling2D at 0x2487a4ce710>,
 <tensorflow.python.keras.layers.core.Dropout at 0x2487a4ce518>,
 <tensorflow.python.keras.layers.convolutional.Conv2D at 0x2487a4320b8>,
 <tensorflow.python.keras.layers.convolutional.Conv2D at 0x2487c251470>,
 <tensorflow.python.keras.layers.pooling.MaxPooling2D at 0x2487c25ca58>,
 <tensorflow.python.keras.layers.core.Dropout at 0x2487c27db00>,
 <tensorflow.python.keras.layers.core.Flatten at 0x2487c27e780>,
 <tensorflow.python.keras.layers.core.Dense at 0x2487c27e9e8>,
 <tensorflow.python.keras.layers.core.Dropout at 0x2487c2e1978>,
 <tensorflow.python.keras.layers.core.Dense at 0x2487c27e048>]
In [6]:
model.layers[0].input
Out[6]:
<tf.Tensor 'conv2d_1_input:0' shape=(None, 62, 47, 1) dtype=float32>
In [7]:
model.layers[0].output
Out[7]:
<tf.Tensor 'conv2d_1/Identity:0' shape=(None, 60, 45, 32) dtype=float32>
In [8]:
model.input
Out[8]:
<tf.Tensor 'conv2d_1_input:0' shape=(None, 62, 47, 1) dtype=float32>
In [9]:
model.output
Out[9]:
<tf.Tensor 'dense_2/Identity:0' shape=(None, 5) dtype=float32>
In [10]:
model_mid = models.Model(inputs=model.input, outputs=[layer_out.output for layer_out in model.layers])
In [11]:
model_mid.summary()
Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1_input (InputLayer)  [(None, 62, 47, 1)]       0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 60, 45, 32)        320       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 58, 43, 32)        9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 29, 21, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 29, 21, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 27, 19, 64)        18496     
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 25, 17, 64)        36928     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 12, 8, 64)         0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 12, 8, 64)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 6144)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               1573120   
_________________________________________________________________
dropout_3 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 5)                 1285      
=================================================================
Total params: 1,639,397
Trainable params: 1,639,397
Non-trainable params: 0
_________________________________________________________________
In [12]:
model_output = model_mid.predict(X_test_sc[15:17])
In [13]:
for i in range(len(model_output)):
    print(model_output[i].shape, type(model_output[i]))
(2, 60, 45, 32) <class 'numpy.ndarray'>
(2, 58, 43, 32) <class 'numpy.ndarray'>
(2, 29, 21, 32) <class 'numpy.ndarray'>
(2, 29, 21, 32) <class 'numpy.ndarray'>
(2, 27, 19, 64) <class 'numpy.ndarray'>
(2, 25, 17, 64) <class 'numpy.ndarray'>
(2, 12, 8, 64) <class 'numpy.ndarray'>
(2, 12, 8, 64) <class 'numpy.ndarray'>
(2, 6144) <class 'numpy.ndarray'>
(2, 256) <class 'numpy.ndarray'>
(2, 256) <class 'numpy.ndarray'>
(2, 5) <class 'numpy.ndarray'>
In [14]:
layer_names = [layer.name for layer in model.layers]
In [20]:
%matplotlib inline
from matplotlib import pyplot as plt
from matplotlib.gridspec import GridSpec

data_num = model_output[0].shape[0]
rowmax = 64

for data_idx in range(data_num):
    fig = plt.figure(figsize=(60,450), facecolor = 'gray')
    gs = GridSpec(rowmax, len(model_output), wspace=0.1, hspace=0.1, width_ratios=[2]*8+[1]*4)

    for layer_idx in range(len(model_output)):
        if model_output[layer_idx].ndim == 4 :
            layer_out_tr = model_output[layer_idx][data_idx].transpose(2,0,1)

        if model_output[layer_idx].ndim == 2 :
            layer_out_tr = model_output[layer_idx][data_idx].reshape(model_output[layer_idx][data_idx].shape[0], 1)
            layer_out_tr = np.tile(layer_out_tr, [1, 1, int(model_output[layer_idx][data_idx].shape[0]/5)])

        num = layer_out_tr.shape[0]
        for idx in range(num):
            if idx >= rowmax:
                break
            if num > 1 :
                ax = fig.add_subplot(gs[idx, layer_idx], facecolor = 'white')
            else :
                ax = fig.add_subplot(gs[:  , layer_idx], facecolor = 'white' )
 
            ax.imshow(layer_out_tr[idx], cmap='viridis')
            ax.tick_params(bottom=False,
                    left=False,
                    right=False,
                    top=False,
                    labelbottom=False,
                    labelleft=False,
                    labelright=False,
                    labeltop=False)

    plt.savefig('.\model_layer{}.jpg'.format(data_idx))
    plt.show()
In [ ]: