TensorFlowでXavierの初期化を行う方法


回答:


12

Tensorflow 2.0、さらに双方tf.contrib.*tf.get_variable()非推奨されています。Xavierの初期化を行うには、次のように切り替える必要があります。

init = tf.initializers.GlorotUniform()
var = tf.Variable(init(shape=shape))
# or a oneliner with a little confusing brackets
var = tf.Variable(tf.initializers.GlorotUniform()(shape=shape))

GlorotユニフォームとXavierユニフォームは、同じ初期化タイプの2つの異なる名前です。Kerasの有無にかかわらずTF2.0で初期化を使用する方法について詳しく知りたい場合は、ドキュメントを参照してください。


上記のコードを使用すると、以下のようなエラーが発生します。_init_xavier = tf.Variable(init(shape = shape))NameError:name'shape 'is not defined
Chiranga

119

バージョン0.8以降、Xavierイニシャライザーがあります。ドキュメントについては、こちらを参照してください

次のようなものを使用できます。

W = tf.get_variable("W", shape=[784, 256],
           initializer=tf.contrib.layers.xavier_initializer())

3
シェイプをget_variable与えるのではなく、イニシャライザに与えることでこれを行うことを知っていますか?以前は持っていてtf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)、そこで形状を指定しましたが、今ではあなたの提案が私のコードを台無しにしてしまいます。何か提案はありますか?
ピノキオ2016

1
@Pinocchioと同じ署名をtf.Variable(...)持ち、使用するラッパーを自分で作成するだけですtf.get_variable(...)
jns 2016

2
:バージョンなしの「現在」のリンクtensorflow.org/api_docs/python/tf/contrib/layers/...
scipilot

28

XavierとYoshuaの方法tf.Variableを使用して初期化を定義する方法に関する別の例を追加するだけです。

graph = tf.Graph()
with graph.as_default():
    ...
    initializer = tf.contrib.layers.xavier_initializer()
    w1 = tf.Variable(initializer(w1_shape))
    b1 = tf.Variable(initializer(b1_shape))
    ...

これによりnan、RELUで複数のレイヤーを使用する場合、数値が不安定になるため、損失関数に値を設定できなくなりました。


2
この形式は私のコードに最もよく適合しました-そしてそれは私の学習率を0.5に戻すことを可能にしました(私は別のrelu'dレイヤーを追加するときにそれを0.06に下げる必要がありました)。このイニシャライザーをすべての非表示レイヤーに適用すると、最初の数百エポックから信じられないほど高い検証率が得られます。違いが信じられない!
scipilot 2017

12

@ Aleph7、Xavier / Glorotの初期化は、ニューロンの着信接続の数(fan_in)、発信接続の数(fan_out)、および活性化関数の種類(sigmoidまたはtanh)によって異なります。これを参照してください:http//jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

さて、あなたの質問に。これは私がTensorFlowでそれを行う方法です:

(fan_in, fan_out) = ...
    low = -4*np.sqrt(6.0/(fan_in + fan_out)) # use 4 for sigmoid, 1 for tanh activation 
    high = 4*np.sqrt(6.0/(fan_in + fan_out))
    return tf.Variable(tf.random_uniform(shape, minval=low, maxval=high, dtype=tf.float32))

他の回答で提案されている正規分布ではなく、一様分布からサンプリングする必要があることに注意してください。

ちなみに、私は昨日、Xavier初期化も使用するTensorFlowを使用して別の何かについて投稿しました。興味がある場合は、エンドツーエンドの例を含むPythonノートブックもあります:https//github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb


1
relu活性化関数でどのように使用できますか。
gautam840 ​​2016

その論文は、一般的に使用される初期化を使用して、さまざまな活性化関数の下での重み勾配の動作を研究しています。次に、活性化関数に関係なく、ユニバーサル初期化を提案します。さらに、メソッドも活性化関数に依存しないため、Tensorflowに組み込まれているXavier初期化を使用することをお勧めします。
Vahid Mirjalili 2017年

8

tensorflowと呼ばれる優れたラッパーprettytensorは、ソースコードに実装を提供します(ここから直接コピーされます)。

def xavier_init(n_inputs, n_outputs, uniform=True):
  """Set the parameter initialization using the method described.
  This method is designed to keep the scale of the gradients roughly the same
  in all layers.
  Xavier Glorot and Yoshua Bengio (2010):
           Understanding the difficulty of training deep feedforward neural
           networks. International conference on artificial intelligence and
           statistics.
  Args:
    n_inputs: The number of input nodes into each output.
    n_outputs: The number of output nodes for each input.
    uniform: If true use a uniform distribution, otherwise use a normal.
  Returns:
    An initializer.
  """
  if uniform:
    # 6 was used in the paper.
    init_range = math.sqrt(6.0 / (n_inputs + n_outputs))
    return tf.random_uniform_initializer(-init_range, init_range)
  else:
    # 3 gives us approximately the same limits as above since this repicks
    # values greater than 2 standard deviations from the mean.
    stddev = math.sqrt(3.0 / (n_inputs + n_outputs))
    return tf.truncated_normal_initializer(stddev=stddev)

8

TF-contribにはxavier_initializer。使用方法の例を次に示します。

import tensorflow as tf
a = tf.get_variable("a", shape=[4, 4], initializer=tf.contrib.layers.xavier_initializer())
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(a)

これに加えて、tensorflowには他の初期化子があります。


おかげで、これは非常に有用だった先生、私は初期化することができればお聞きしたいのバイアス使っ xavier_initializer
Sakhri Houssem

4

調べたところ、何も組み込まれていませんでした。しかし、これによると:

http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization

Xavierの初期化は、分散がニューロンの数の関数である(通常はガウス)分布をサンプリングするだけです。 tf.random_normalあなたのためにそれを行うことができます、あなたはただstddevを計算する必要があります(すなわちあなたが初期化しようとしている重み行列によって表されているニューロンの数)。


一様分布からサンプリングする必要があるためです。
2015年


3

次のように1行を使用する場合に備えて:

W = tf.Variable(tf.truncated_normal((n_prev, n), stddev=0.1))

できるよ:

W = tf.Variable(tf.contrib.layers.xavier_initializer()((n_prev, n)))

0

Tensorflow 1:

W1 = tf.get_variable("W1", [25, 12288],
    initializer = tf.contrib.layers.xavier_initializer(seed=1)

Tensorflow 2:

W1 = tf.get_variable("W1", [25, 12288],
    initializer = tf.random_normal_initializer(seed=1))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.