Jak przeprowadzić inicjalizację Xaviera w TensorFlow


Odpowiedzi:


12

W Tensorflow 2.0 i nowszych oba tf.contrib.*i tf.get_variable()są przestarzałe. Aby wykonać inicjalizację Xaviera, musisz teraz przełączyć się na:

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

Mundur Glorot i mundur Xaviera to dwie różne nazwy tego samego typu inicjalizacji. Jeśli chcesz dowiedzieć się więcej o tym, jak używać inicjalizacji w TF2.0 z lub bez Keras, zajrzyj do dokumentacji .


Użyłem powyższego kodu i otrzymałem błąd jak poniżej; _init_xavier = tf.Variable (init (shape = shape)) NameError: name 'shape' nie jest zdefiniowana
Chiranga

119

Od wersji 0.8 istnieje inicjator Xavier, zobacz tutaj dokumentację .

Możesz użyć czegoś takiego:

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

3
czy wiesz, aby to zrobić bez nadawania kształtu, get_variableale zamiast tego przekazując go inicjatorowi? Kiedyś miałem tf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)i określałem tam kształt, ale teraz twoja sugestia trochę psuje mój kod. Masz jakieś sugestie?
Pinokio,

1
@Pinocchio, możesz po prostu napisać sobie opakowanie, które ma ten sam podpis, co tf.Variable(...)i używatf.get_variable(...)
jns


28

Aby dodać kolejny przykład, jak zdefiniować tf.Variablezainicjowany przy użyciu metody Xaviera i Yoshua :

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

Uniemożliwiło mi to uzyskanie nanwartości mojej funkcji utraty z powodu niestabilności numerycznej podczas używania wielu warstw z RELU.


2
Ten format najlepiej pasował do mojego kodu - i pozwolił mi przywrócić współczynnik uczenia się do 0,5 (musiałem obniżyć go do 0,06 podczas dodawania kolejnej warstwy relu'd). Kiedy zastosowałem ten inicjator do WSZYSTKICH ukrytych warstw, otrzymuję niewiarygodnie wysokie wskaźniki walidacji od pierwszych kilkuset epok. Nie mogę uwierzyć, jaka to różnica!
scipilot

12

@ Aleph7, inicjalizacja Xavier / Glorot zależy od liczby połączeń przychodzących (fan_in), liczby połączeń wychodzących (fan_out) i rodzaju funkcji aktywacji (sigmoid lub tanh) neuronu. Zobacz: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

A teraz do twojego pytania. Oto jak zrobiłbym to w 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))

Zauważ, że powinniśmy pobierać próbki z rozkładu jednorodnego, a nie z rozkładu normalnego, jak sugeruje inna odpowiedź.

Nawiasem mówiąc, wczoraj napisałem post dotyczący czegoś innego za pomocą TensorFlow, który również używa inicjalizacji Xavier. Jeśli jesteś zainteresowany, jest też notatnik Pythona z pełnym przykładem: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb


1
Jak możemy go używać z funkcją aktywacji relu.
gautam840

W artykule tym badano zachowanie gradientów ciężaru przy różnych funkcjach aktywacji z powszechnie stosowaną inicjalizacją. Następnie proponują uniwersalną inicjalizację niezależnie od funkcji aktywacji. Co więcej, Twoja metoda również nie zależy od funkcji aktywacji, więc lepiej jest użyć wbudowanej inicjalizacji Xavier w Tensorflow.
Vahid Mirjalili

8

Ładne opakowanie wokół tensorflowwywołania prettytensordaje implementację w kodzie źródłowym (skopiowanym bezpośrednio stąd ):

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

Wkład TF ma xavier_initializer. Oto przykład, jak go używać:

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)

Oprócz tego tensorflow ma inne inicjatory:


dzięki, sir, to było bardzo pomocne, chcę cię zapytać, czy mogę zainicjować odchylenie za pomocą xavier_initializer
Sakhri Houssem

4

Szukałem i nie mogłem znaleźć nic wbudowanego. Jednak zgodnie z tym:

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

Inicjalizacja Xaviera polega po prostu na próbkowaniu rozkładu (zwykle Gaussa), w którym wariancja jest funkcją liczby neuronów. tf.random_normalmożesz to zrobić za Ciebie, wystarczy obliczyć odchylenie standardowe (tj. liczbę neuronów reprezentowaną przez macierz wag, którą próbujesz zainicjować).


Vince, powinieneś pobierać próbki z jednolitej dystrybucji.
Delip


3

Na wszelki wypadek, gdybyś chciał użyć jednej linii, tak jak robisz z:

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

Możesz to zrobić:

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))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.