【Python】kerasの可視化されたモデルのパラメータの数の計算方法
KerasのSequentialモデルのサンプル1
Kerasのパラメータの計算方法として次のWebのサンプルを使って計算します。回答で、明確な計算方法が書かれていなかったので記事にしてみました。
https://teratail.com/questions/165439
この例でのKerasのSequentialモデルは以下の通りです。
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(5, 5), padding="same", activation="relu", input_shape=(28, 28, 1)))
model.add(Conv2D(filters=32, kernel_size=(5, 5), padding="same", activation="relu"))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters=64, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(Conv2D(filters=64, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation="relu"))
model.add(Dropout(0.25))
model.add(Dense(10, activation="softmax"))
モデルの深層構造を可視化する
このSequentialモデルを可視化すると以下の通りになります。
print(model.summary())
出力結果
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 28, 28, 32) 832
_________________________________________________________________
conv2d_2 (Conv2D) (None, 28, 28, 32) 25632
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 14, 14, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 14, 14, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 14, 14, 64) 18496
_________________________________________________________________
conv2d_4 (Conv2D) (None, 14, 14, 64) 36928
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 7, 7, 64) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 7, 7, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 3136) 0
_________________________________________________________________
dense_1 (Dense) (None, 256) 803072
_________________________________________________________________
dropout_3 (Dropout) (None, 256) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 2570
=================================================================
Total params: 887,530
Trainable params: 887,530
Non-trainable params: 0
_________________________________________________________________
サイト上の回答で計算方法が書かれていますが、丁寧ではありません。Paramの計算方法は以下の通りです。
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 28, 28, 32) 832 ← conv_size(5*5)*filter_num(32)*rgb_num(1)+bias_num(32)=832
_________________________________________________________________
conv2d_2 (Conv2D) (None, 28, 28, 32) 25632 ← conv_size(5*5)*filter_num(32*32)+bias_num(32)=25632
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 14, 14, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 14, 14, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 14, 14, 64) 18496 ← conv_size(3*3)*filter_num(64*32)+bias_num(64)=18496
_________________________________________________________________
conv2d_4 (Conv2D) (None, 14, 14, 64) 36928 ← conv_size(3*3)*filter_num(64*32)+bias_num(64)=18496
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 7, 7, 64) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 7, 7, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 3136) 0 ← 畳み込み後の画像の幅(7)*畳み込み後の画像の高さ(7)*filter_num(64)
_________________________________________________________________
dense_1 (Dense) (None, 256) 803072 ← 入力層の数(3136)*中間層の数(256)+bias_num(256)=803072
_________________________________________________________________
dropout_3 (Dropout) (None, 256) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 2570 ← 中間層の数(256)*出力層の数10+bias_num(10)=2570
=================================================================
Total params: 887,530
Trainable params: 887,530
Non-trainable params: 0
_________________________________________________________________
解説
バイアスというのは、切片のことです。学校で習ったy=ax+bにおけるbの部分です。ニューラルネットワークの場合、y=wx+w’x’+w"’x"’+w""x""+bという形で線形結合しますので(曖昧)、このbがbias(=切片)となります。Paramでこの切片を合計した方がよいのか分かりませんが、model.summary()で表示するとこのように表示されて、計算はこのようにやればParamの数値と合致するというだけです。
なぜ、バイアス(切片)を足すのか?
中間層のニューロンの数だけバイアスがあるからです。ちなみに出力層のニューロンにもバイアスがあります。Paramは単に変化するパラメータを合計しているだけです。およその数がわかればいいのです。
paramの数値は大きくした方がよいのか?
わかりません。しかし、大きすぎると、GPUサーバのメモリが足りなくて、計算できずにエラーとなります。複雑でない画像の場合や、画像が小さいのに必要以上にParamが大きくなるのは意味がありません。
Paramの使い所
自分がParamの数値を参考にしているのは、畳込み処理をやると、パラメータが少なくなりますので、畳み込みをしすぎて、その後Flatten()で一次元の配列にしたときに、要素数が少なすぎると良い結果がでないと思うので、畳み込みの層や中間層の各層で、今どのくらいの次元数(≒ノード数≒パラメーター数)なのかを確認するときにParamの数値が参考になります。
画像を単なるニューラルネットワークで計算した場合
画像を単なるニューラルネットワークで機械学習するとします。KerasのSequentialモデルのコードです。畳み込み処理を利用していない簡単な例です。
model = Sequential()
# 横640縦480のカラー画像を一次元の配列に変換するという意味。
# 一直線にすることでニューラルネットワークの計算が可能となる
model.add(Flatten(input_shape=(640, 480, 3)))
# 中間層
model.add(Dense(128, activation = "relu"))
# 中間層
model.add(Dense(8, activation = "relu"))
# 出力層
model.add(Dense(50, activation = "softmax"))
KerasのSequentialモデルを可視化すると以下のようになります。
print(model.summary())
# 出力結果
Layer (type) Output Shape Param #
=================================================================
flatten_1 (Flatten) (None, 921600) 0
_________________________________________________________________
dense_1 (Dense) (None, 128) 117964928 ← 入力層の数(921600)*中間層の数(128)+bias(128)
_________________________________________________________________
dense_2 (Dense) (None, 8) 1032 ← 中間層の数(128)*中間層の数(8)+biasの数(8)=1032
_________________________________________________________________
dense_3 (Dense) (None, 50) 450 ← 中間層の数(8)*出力層の数(50)+biasの数(50)=450(50)=450
=================================================================
Total params: 117,966,410
Trainable params: 117,966,410
Non-trainable params: 0
_________________________________________________________________
囲碁のAIの層の仕組み
http://home.q00.itscom.net/otsuki/20160415AlphaGopublic.pdf
この記事の通りにKerasでSequentialを作成すると以下の通りになる。(Pooling層とかDropout層とか省略していると思うので、分かり次第修正しますが…)
model = Sequential()
model.add(Conv2D(192, (5, 5), padding='same', activation="relu", input_shape=(19, 19, 48)))
for i in range(0,10):
model.add(Conv2D(192, (3, 3), padding='same', activation="relu", input_shape=(19, 19, 48)))
model.add(Flatten())
# 出力層
model.add(Dense(19*19, activation="softmax"))
print(model.summary())
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 19, 19, 192) 230592 ← conv_size(5*5)*filter_num(192)*channel_num(48)+bias_num(192)=230592
_________________________________________________________________
conv2d_2 (Conv2D) (None, 19, 19, 192) 331968 ← conv_size(3*3)*filter_num(192*192)+bias_num(192)=331968
_________________________________________________________________
conv2d_3 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_4 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_5 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_6 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_7 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_8 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_9 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_10 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
conv2d_11 (Conv2D) (None, 19, 19, 192) 331968
_________________________________________________________________
flatten_1 (Flatten) (None, 69312) 0 ← 畳み込み後の画像の幅(19)*畳み込み後の画像の高さ(19)*filter_num(192)=69312
_________________________________________________________________
dense_1 (Dense) (None, 361) 25021993 ← 入力層の数(69312)*出力層の数(19*19)+biasの数(361)=25021993
=================================================================
Total params: 28,572,265
Trainable params: 28,572,265
Non-trainable params: 0
_________________________________________________________________
このKerasのSequentialが他の画像処理でも利用できるのか、いつか確認してみたい。
