kntty.hateblo.jp

ここに何か書く。

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.

sthalles.github.io

  • 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_regularizeractivity_regularizerも加えることが可能である。