tf.layers.conv2d と tf.layers.dense のデフォルトのカーネルイニシャライザーは何ですか?
Tensorflow API の公式ドキュメントでは、tf.lays.conv2d
と tf.layers.dense
のパラメータ kernel_initializer
のデフォルトは None
であるとされています。
しかし、layers tutorial (https://www.tensorflow.org/tutorials/layers) を読むと、このパラメータがコードに設定されていないことに気づきました。例えば
# Convolutional Layer #1
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
チュートリアルのサンプルコードは何のエラーもなく実行されるので、デフォルトの kernel_initializer
は None
ではないのだと思います。では、どのイニシャライザが使われているのでしょうか?
別のコードでは、conv2dとdenseレイヤーの kernel_initializer
を設定しませんでしたが、すべてうまくいきました。しかし、kernel_initializer
に tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)
をセットしようとすると、NaNエラーが発生しました。どうなっているのでしょうか?どなたか教えてください。
66
2
いい質問ですねー。調べるのはなかなかコツがいりますね!
tf.lays.conv2d
にはドキュメントがありません。variable_scope.get_variable
を呼び出していることがわかります。コードでは
次のステップ: イニシャライザが None のとき、変数スコープはどうなっているか
ここにはこう書いてあります。
initializer が None
(デフォルト) の場合、コンストラクタで渡されたデフォルトのイニシャライザが使われます。 が使用されます。もし、これも
Noneならば、新しい glorot_uniform_initializer
を使用します。つまり答えは、
glorot_uniform_initializer
を使うということです。完全を期すために、このイニシャライザーの定義を示します。
Glorot uniform initializer, Xavier uniform initializerとも呼ばれます。 これは、一様分布から [-limit, limit] の範囲内でサンプルを取得します。 ここで,
limit
はsqrt(6 / (fan_in + fan_out))
です. ここで、fan_in
はウェイトテンソルの入力ユニット数 であり、fan_out
はウェイトテンソルの出力ユニット数である。 参考:http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf編集:これは私がコードとドキュメントで見つけたものです。おそらく、重みに対してevalを実行することで、初期化がこのように見えることを確認することができるだろう
Andrew Ng氏の[本講座](https://www.youtube.com/watch?v=s2coXdufOzE)やXavierドキュメントによると、活性化関数としてReLUを使っている場合、デフォルトの重みの初期化子(*Xavier uniform)をXavier normal**に変更した方が良いそうです。