らんだむな記憶

blogというものを体験してみようか!的なー

Tensorboardで可視化(2)

Udacityのud187のImage Classification with CNNsのネタを使って

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, (3,3), padding='same', activation=tf.nn.relu,
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D((2, 2), strides=2),
    tf.keras.layers.Conv2D(64, (3,3), padding='same', activation=tf.nn.relu),
    tf.keras.layers.MaxPooling2D((2, 2), strides=2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10,  activation=tf.nn.softmax)
])

のグラフをTensorBoardで見てみる。
f:id:derwind:20190916015121p:plain:w253
model.summaryの結果と併せて見ても良いかもしれない。

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 28, 28, 32)        320       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 14, 14, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 14, 14, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 7, 7, 64)          0         
_________________________________________________________________
flatten (Flatten)            (None, 3136)              0         
_________________________________________________________________
dense (Dense)                (None, 128)               401536    
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 421,642
Trainable params: 421,642
Non-trainable params: 0
_________________________________________________________________

重みやバイアスについては以下のようにすれば見られそう。

for layer in model.layers:
    weights = layer.get_weights()
    print(layer.name)
    for w in weights:
      print(w.shape)
      print(w)
    print("-"*50)

層ごとでなくて良いなら

weights = model.get_weights()
print(type(weights), len(weights))
for w in weights:
    print(w.shape)
    print(w)
    print("-"*50)

で良さそう。プーリング層の情報がないので、長さが0より大きい情報だけがごそっととれているみたい。
意味合いについてはkerasのmodel.get_weights()で得られるlistの構造 - Qiitaのように[「現在の層から次の層への重み」, 「バイアス」]が層ごとにとれているのだろう。
keras.Sequentialで層を追加した直後はバイアスが0で初期化されている?*1のか知らないが、学習の前後でlayer_get_weights()するとバイアスが変化しているのが分かりやすい。正直重みのほうはマトリクスが大きすぎてよく分からない。

*1:bias_initializer='zeros' がデフォルト値のためのようだ