So führen Sie die Xavier-Initialisierung in TensorFlow durch


Antworten:


12

In Tensorflow 2.0 und weiter sind beide tf.contrib.*und tf.get_variable()veraltet. Um die Xavier-Initialisierung durchzuführen, müssen Sie jetzt wechseln zu:

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-Uniform und Xavier-Uniform sind zwei verschiedene Namen desselben Initialisierungstyps. Weitere Informationen zur Verwendung von Initialisierungen in TF2.0 mit oder ohne Keras finden Sie in der Dokumentation .


119

Seit Version 0.8 gibt es einen Xavier-Initialisierer. Die Dokumentation finden Sie hier .

Sie können so etwas verwenden:

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

3
Wissen Sie, dass Sie dies tun müssen, ohne die Form zu geben, get_variablesondern sie dem Initialisierer zu geben? Früher hatte tf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)ich die Form dort angegeben, aber jetzt schraubt Ihr Vorschlag meinen Code irgendwie durcheinander. Hast du irgendwelche Vorschläge?
Pinocchio

1
@ Pinocchio Sie können sich einfach einen Wrapper schreiben, der die gleiche Signatur hat tf.Variable(...)und verwendettf.get_variable(...)
jns


28

Nur um ein weiteres Beispiel zum Definieren einer tf.VariableInitialisierung mit der Methode von Xavier und Yoshua hinzuzufügen :

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))
    ...

Das hat mich daran gehindert nan ich aufgrund numerischer Instabilitäten bei Verwendung mehrerer Ebenen mit RELUs Werte für meine Verlustfunktion hatte.


2
Dieses Format passte am besten zu meinem Code - und ich konnte meine Lernrate auf 0,5 zurücksetzen (ich musste sie auf 0,06 senken, wenn ich eine weitere relu'd-Ebene hinzufügte). Sobald ich diesen Initialisierer auf ALLE versteckten Ebenen angewendet hatte, erhalte ich bereits in den ersten paar hundert Epochen unglaublich hohe Validierungsraten. Ich kann den Unterschied nicht glauben, den es gemacht hat!
Scipilot

12

@ Aleph7, Xavier / Glorot-Initialisierung hängt von der Anzahl der eingehenden Verbindungen (fan_in), der Anzahl der ausgehenden Verbindungen (fan_out) und der Art der Aktivierungsfunktion (Sigmoid oder Tanh) des Neurons ab. Siehe hierzu: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

Nun zu Ihrer Frage. So würde ich es in TensorFlow machen:

(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))

Beachten Sie, dass wir eine Stichprobe aus einer gleichmäßigen Verteilung ziehen sollten und nicht aus der Normalverteilung, wie in der anderen Antwort vorgeschlagen.

Übrigens habe ich gestern mit TensorFlow einen Beitrag für etwas anderes geschrieben, das zufällig auch die Xavier-Initialisierung verwendet. Wenn Sie interessiert sind, gibt es auch ein Python-Notizbuch mit einem End-to-End-Beispiel: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb


1
Wie können wir es mit Relu-Aktivierungsfunktion verwenden?
Gautam840

In diesem Artikel wird das Verhalten von Gewichtsgradienten unter verschiedenen Aktivierungsfunktionen mit der häufig verwendeten Initialisierung untersucht. Dann schlagen sie eine universelle Initialisierung vor, unabhängig von einer Aktivierungsfunktion. Darüber hinaus hängt Ihre Methode auch nicht von der Aktivierungsfunktion ab. Verwenden Sie daher besser die integrierte Xavier-Initialisierung in Tensorflow.
Vahid Mirjalili

8

Ein netter Wrapper tensorflownamens prettytensorgibt eine Implementierung im Quellcode (direkt von hier kopiert ):

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 hat xavier_initializer. Hier ist ein Beispiel für die Verwendung:

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)

Darüber hinaus verfügt Tensorflow über weitere Initialisierer:


Danke, Sir, das war sehr hilfreich. Ich möchte Sie fragen, ob ich die Verzerrung mit xavier_initializer
Sakhri Houssem


3

Ich habe nachgesehen und konnte nichts Eingebautes finden. Demnach jedoch:

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

Bei der Xavier-Initialisierung wird lediglich eine (normalerweise Gaußsche) Verteilung abgetastet, bei der die Varianz von der Anzahl der Neuronen abhängt. tf.random_normalWenn Sie dies für Sie tun können, müssen Sie nur den Standardwert berechnen (dh die Anzahl der Neuronen, die durch die Gewichtsmatrix dargestellt werden, die Sie initialisieren möchten).


Vince Sie sollten Proben aus einer gleichmäßigen Verteilung nehmen.
Löschen Sie den

3

Nur für den Fall, dass Sie eine Zeile verwenden möchten, wie Sie es tun mit:

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

Du kannst tun:

W = tf.Variable(tf.contrib.layers.xavier_initializer()((n_prev, n)))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.