tf.Kerasの事前学習済みモデルに、正則化を加える正しい方法
TensorFlow(2系)の、 tf.keras.applicationsの学習済みモデルに、L2等の正規化を加える方法。 次の記事[1]で解決した。簡単にその要約を記す。
[1] Silva TS. How to Add Regularization to Keras Pre-trained Models the Right Way. 2019.
- Step 1. 学習済みモデル
model
が持つのlayerを走査する。 もしlayerがkernel_regularizer
プロパティを持っていれば、そこにregularizerオブジェクトを代入する。
(ここで加えた変更は、まだ、モデルそのものには反映されていない。) - Step 2. 一旦、config情報をjsonに書き出す。
- Step 3. 重みについても、一時ファイルに書き出す。
- Step 4. Step 3で書き出したconfig情報(json)を読み戻す。
(regularizerは反映されるが、重みがリセットされてしまう。) - Step 5. Step 4で書き出した重みを、一時ファイルから読み戻す。
(https://gist.github.com/sthalles/d4e0c4691dc2be2497ba1cdbfe3bc2eb から引用)
import os import tempfile def add_regularization(model, regularizer=tf.keras.regularizers.l2(0.0001)): if not isinstance(regularizer, tf.keras.regularizers.Regularizer): print("Regularizer must be a subclass of tf.keras.regularizers.Regularizer") return model for layer in model.layers: for attr in ['kernel_regularizer']: if hasattr(layer, attr): setattr(layer, attr, regularizer) # When we change the layers attributes, the change only happens in the model config file model_json = model.to_json() # Save the weights before reloading the model. tmp_weights_path = os.path.join(tempfile.gettempdir(), 'tmp_weights.h5') model.save_weights(tmp_weights_path) # load the model from the config model = tf.keras.models.model_from_json(model_json) # Reload the model weights model.load_weights(tmp_weights_path, by_name=True) return model
動作確認として、model.losses
にアクセスすれば、正則化の値をリストで取得することができる。
正則化を正しく反映できていれば、リストは空にならないはずである。
なお、プロパティとして、kernel_regularizer
だけでなく
bias_regularizer
とactivity_regularizer
も加えることが可能である。