背景
ニューラルネットワークを用いた機械学習において、より精度を上げようとする場合、モデルの中間層数を含めたハイパーパラメータチューニングは欠かせません。
ただ、tensorflowでニューラルネットワークモデルを記述する場合、下記のように記述されていることが多いと思います。
(Kaggleチュートリアルでよく知られている、タイタニック号製造予測を想定しています。)
model_train01.py
#(前提)「in_var」は説明変数のリスト。「out_var」は目的変数のリスト(生/死=0/1の集まり)
import tensorflow as tf
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(12, activation='relu',name='dense0', input_shape=(in_var.shape[1],)), #入力層定義
tf.keras.layers.Dense(12, activation='relu'), #1層目の『中間層』を定義。ノード数=12
tf.keras.layers.Dense(12, activation='relu'), #2層目の『中間層』を定義。ノード数=12
tf.keras.layers.Dense(12, activation='relu'), #3層目の『中間層』を定義。ノード数=12
tf.keras.layers.Dropout(0.1), #過学習防止のためのドロップアウト層。ドロップアウト率=0.1(10%)
tf.keras.layers.Dense(2,activation='sigmoid') #出力層(生/死=2値判定)
])
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.summary()
history=model.fit(in_var, out_var, epochs=500, batch_size=32,verbose=1,
validation_split=0.3)
問題点
上記のように記述した場合、中間層ノード数や学習回数(epochs)が直接定義されているため、パラメータ調整をする際には下記のように変数を定義して記述することが多いと思います。
model_train02.py
#学習条件(ハイパーパラメータ)を変数定義
node=12 #中間層ノード数
Epochs=500 #学習回数
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(node, activation='relu',name='dense0', input_shape=(in_var.shape[1],)),
tf.keras.layers.Dense(node, activation='relu'), #1層目の『中間層』を定義
tf.keras.layers.Dense(node, activation='relu'), #2層目の『中間層』を定義
tf.keras.layers.Dense(node, activation='relu'), #3層目の『中間層』を定義
tf.keras.layers.Dropout(0.1), #ドロップアウト層
tf.keras.layers.Dense(2,activation='sigmoid') #出力層(2値判定)
])
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.summary()
history=model.fit(in_var, out_var, epochs=Epochs, batch_size=32,verbose=1,
validation_split=0.3)
こうすれば、学習条件(中間層ノード数、学習回数)を簡単に変化させることができます。
ただ、この場合でも中間層数を変化させるには、モデル定義時のDense行を追加する必要があり、ひと手間です。
特に、自動で中間層数含めたハイパーパラメータチューニングを行いたい場合には困ってしまいます。
解決策
中間層数を簡単に変化させたい場合には「.add」を使う記述方法が便利です。
model_train03.py
#学習条件(ハイパーパラメータ)を変数定義
node=12 #中間層ノード数
Epochs=500 #学習回数
layer_N=3 #中間層数
model = keras.Sequential() #空のsequentialモデルを準備
model.add(layers.Dense(node, activation='relu',name='dense0', input_shape=(in_var.shape[1],))) #入力層追加
for i in range(layer_N):
model.add(layers.Dense(node, activation='relu')) #中間層を追加
model.add(layers.Dropout(0.1)) #ドロップアウト層追加
model.add(layers.Dense(2,activation='sigmoid')) #出力層追加(2値判定)
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.summary()
history=model.fit(in_var, out_var, epochs=Epochs, batch_size=32,verbose=1,
validation_split=0.3)
この記述方法で中間層数を簡単に変化させることができ、ハイパーパラメータチューニングも捗ります。
誰かの参考になればうれしいです