Przenoszę moją sieć Caffe do TensorFlow, ale wygląda na to, że nie ma inicjalizacji Xavier. Używam, truncated_normal
ale wydaje mi się, że trenowanie jest o wiele trudniejsze.
python
tensorflow
Alejandro
źródło
źródło
Odpowiedzi:
W Tensorflow 2.0 i nowszych oba
tf.contrib.*
itf.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 .
źródło
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())
źródło
get_variable
ale zamiast tego przekazując go inicjatorowi? Kiedyś miałemtf.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?tf.Variable(...)
i używatf.get_variable(...)
Aby dodać kolejny przykład, jak zdefiniować
tf.Variable
zainicjowany 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
nan
wartości mojej funkcji utraty z powodu niestabilności numerycznej podczas używania wielu warstw z RELU.źródło
@ 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
źródło
Ładne opakowanie wokół
tensorflow
wywołaniaprettytensor
daje 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)
źródło
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:
źródło
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_normal
możesz to zrobić za Ciebie, wystarczy obliczyć odchylenie standardowe (tj. liczbę neuronów reprezentowaną przez macierz wag, którą próbujesz zainicjować).źródło
Poprzez
kernel_initializer
parametr dotf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense
itpna przykład
layer = tf.layers.conv2d( input, 128, 5, strides=2,padding='SAME', kernel_initializer=tf.contrib.layers.xavier_initializer())
https://www.tensorflow.org/api_docs/python/tf/layers/conv2d
https://www.tensorflow.org/api_docs/python/tf/layers/conv2d_transpose
https://www.tensorflow.org/api_docs/python/tf/layers/Dense
źródło
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ć:
źródło
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))
źródło