1. はじめに
ふとディープラーニングのパラメータってどうやって数えるんだっけと思って、理解を確認するためにも計算してみました。
2. モデルの構成
Kerasを使ってモデルを構成してみます。
今回作成するモデルは256x256のRBGの画像を入力として、9つのカテゴリーに分類するモデルとなります。
実装
必要なモジュールをインポートします。
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten, Dropout
from keras.layers.core import Dense
分類するクラス数を定数として定義し、
num_class = 9
モデルを構成します。
# モデルの作成
model = Sequential()
model.add(Conv2D(32, kernel_size=3, padding="same", activation='relu', input_shape=(256, 256, 3)))
model.add(Conv2D(32, kernel_size=3, padding="valid", activation='relu'))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Dropout(0.5))
model.add(Conv2D(32, kernel_size=3, padding="same", activation='relu'))
model.add(Conv2D(32, kernel_size=3, padding="valid", activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(32, kernel_size=3, padding="same", activation='relu'))
model.add(Conv2D(32, kernel_size=3, padding="valid", activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten()) #Flatten()により特徴マップをベクトルに変換
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_class, activation='softmax')) #Softmax関数にて、9 クラスの確度として出力
モデル情報を出力します。
model.summary() # モデル情報の表示
以下の出力が得られます。この中で一番右側にパラメータ数が出力されています。今回のモデルでは、6,029,097のパラメータが学習によって調整されることになります。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 256, 256, 32) 896
_________________________________________________________________
conv2d_2 (Conv2D) (None, 254, 254, 32) 9248
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 84, 84, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 84, 84, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 84, 84, 32) 9248
_________________________________________________________________
conv2d_4 (Conv2D) (None, 82, 82, 32) 9248
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 41, 41, 32) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 41, 41, 32) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, 41, 41, 32) 9248
_________________________________________________________________
conv2d_6 (Conv2D) (None, 39, 39, 32) 9248
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 19, 19, 32) 0
_________________________________________________________________
dropout_3 (Dropout) (None, 19, 19, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 11552) 0
_________________________________________________________________
dense_1 (Dense) (None, 512) 5915136
_________________________________________________________________
dropout_4 (Dropout) (None, 512) 0
_________________________________________________________________
dense_2 (Dense) (None, 128) 65664
_________________________________________________________________
dropout_5 (Dropout) (None, 128) 0
_________________________________________________________________
dense_3 (Dense) (None, 9) 1161
=================================================================
Total params: 6,029,097
Trainable params: 6,029,097
Non-trainable params: 0
_________________________________________________________________
3. パラメータ数の計算
3-1. CNN層
まず第1層のCNN層をみてみます。フィルタ数:32枚、フィルタサイズ:3x3、入力チャンネル:3(RGB)、出力チャンネル:3を指定しています。
model.add(Conv2D(32, kernel_size=3, padding="same", activation='relu', input_shape=(256, 256, 3)))
=================================================================
conv2d_1 (Conv2D) (None, 256, 256, 32) 896
_________________________________________________________________
パラメータ数は以下の式で求められます。
パラメータ数 = フィルタ縦サイズ x フィルタ横サイズ x 入力チャンネル数 x 出力チャンネル数 + バイアス x 出力チャンネル数
param =3 x 3 x 3 x 32 + 1 x 32 = 896
同じように第2層も計算してみます。
model.add(Conv2D(32, kernel_size=3, padding="valid", activation='relu', input_shape=(256, 256, 3)))
=================================================================
conv2d_2 (Conv2D) (None, 254, 254, 32) 9248
_________________________________________________________________
今度は第2層への入力が32チャンネルとなっているので、
パラメータ数 = フィルタ縦サイズ x フィルタ横サイズ x 入力チャンネル数 x 出力チャンネル数 + バイアス x 出力チャンネル数
param =3 x 3 x 32 x 32 + 1 x 32 = 9248
第3,4,5,6のConv2D層も同様に計算することができます。
3-2. Flatten層
特徴マップをベクトル化しています。1次元に落としています。ここでは学習によって調整するパラメータではありませんが、
_________________________________________________________________
dropout_3 (Dropout) (None, 19, 19, 32) 0
_________________________________________________________________
よりベクトルの次元は19 x 19 x 32 = 11552となります。
3-3. Dense層(隠れ層)
特徴量をベクトル化するFlatten層の次のDense層では
パラメータ数 = 入力サイズ x 出力サイズ + バイアス となるため
param = 11552 x 512 + 512 = 5915136
その次の隠れ層も同様に
dense_2 (Dense) param = 512 x 128 + 512 = 65664
dense_3 (Dense) param = 128 x 9 + 9 = 1161
4. まとめ
改めて構築したモデルを確認します。
一番右のParamの値を足すと、6,029,097となります。学習ではこのパラメータが調整されています。
そして学習によって調整されたパラメータがモデルの一部となり、推論においては、モデルを軽量化などしない限り、これらのパラメータが使われて計算されています。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 256, 256, 32) 896
_________________________________________________________________
conv2d_2 (Conv2D) (None, 254, 254, 32) 9248
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 84, 84, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 84, 84, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 84, 84, 32) 9248
_________________________________________________________________
conv2d_4 (Conv2D) (None, 82, 82, 32) 9248
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 41, 41, 32) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 41, 41, 32) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, 41, 41, 32) 9248
_________________________________________________________________
conv2d_6 (Conv2D) (None, 39, 39, 32) 9248
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 19, 19, 32) 0
_________________________________________________________________
dropout_3 (Dropout) (None, 19, 19, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 11552) 0
_________________________________________________________________
dense_1 (Dense) (None, 512) 5915136
_________________________________________________________________
dropout_4 (Dropout) (None, 512) 0
_________________________________________________________________
dense_2 (Dense) (None, 128) 65664
_________________________________________________________________
dropout_5 (Dropout) (None, 128) 0
_________________________________________________________________
dense_3 (Dense) (None, 9) 1161
=================================================================
Total params: 6,029,097
Trainable params: 6,029,097
Non-trainable params: 0
_________________________________________________________________