Je porte mon réseau Caffe vers TensorFlow mais il ne semble pas avoir d'initialisation xavier. J'utilise truncated_normal
mais cela semble rendre l'entraînement beaucoup plus difficile.
python
tensorflow
Alejandro
la source
la source
Réponses:
Dans tensorflow 2.0 et en outre à la fois
tf.contrib.*
ettf.get_variable()
sont obsolètes. Pour effectuer l'initialisation de Xavier, vous devez maintenant passer à: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))
L'uniforme Glorot et l'uniforme Xavier sont deux noms différents du même type d'initialisation. Si vous souhaitez en savoir plus sur l'utilisation des initialisations dans TF2.0 avec ou sans Keras, reportez-vous à la documentation .
la source
Depuis la version 0.8, il existe un initialiseur Xavier, voir ici pour la documentation .
Vous pouvez utiliser quelque chose comme ceci:
W = tf.get_variable("W", shape=[784, 256], initializer=tf.contrib.layers.xavier_initializer())
la source
get_variable
mais la donner à l'initialiseur? J'avais l'habitude d'avoirtf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)
et j'ai spécifié la forme là-bas, mais maintenant votre suggestion a en quelque sorte anéanti mon code. Avez-vous des suggestions?tf.Variable(...)
et utilisetf.get_variable(...)
Juste pour ajouter un autre exemple sur la façon de définir un
tf.Variable
initialisé en utilisant la méthode de Xavier et 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)) ...
Cela m'a empêché d'avoir des
nan
valeurs sur ma fonction de perte en raison d'instabilités numériques lors de l'utilisation de plusieurs couches avec des RELU.la source
@ Aleph7, l'initialisation de Xavier / Glorot dépend du nombre de connexions entrantes (fan_in), du nombre de connexions sortantes (fan_out) et du type de fonction d'activation (sigmoïde ou tanh) du neurone. Voir ceci: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
Alors maintenant, à votre question. Voici comment je le ferais dans 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))
Notez que nous devrions échantillonner à partir d'une distribution uniforme, et non de la distribution normale comme suggéré dans l'autre réponse.
Incidemment, j'ai écrit un article hier pour quelque chose de différent en utilisant TensorFlow qui utilise également l'initialisation de Xavier. Si vous êtes intéressé, il existe également un bloc-notes python avec un exemple de bout en bout: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb
la source
Un joli wrapper autour de
tensorflow
appeléprettytensor
donne une implémentation dans le code source (copié directement à partir d' ici ):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)
la source
TF-contrib a
xavier_initializer
. Voici un exemple comment l'utiliser: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)
En plus de cela, tensorflow a d'autres initialiseurs:
la source
J'ai cherché et je n'ai rien trouvé de intégré. Cependant, d'après ceci:
http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization
L'initialisation de Xavier consiste simplement à échantillonner une distribution (généralement gaussienne) où la variance est fonction du nombre de neurones.
tf.random_normal
pouvez le faire pour vous, il vous suffit de calculer le stddev (c'est-à-dire le nombre de neurones représentés par la matrice de poids que vous essayez d'initialiser).la source
Via le
kernel_initializer
paramètre àtf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense
etcpar exemple
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
la source
Juste au cas où vous voudriez utiliser une ligne comme vous le faites avec:
W = tf.Variable(tf.truncated_normal((n_prev, n), stddev=0.1))
Tu peux faire:
la source
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))
la source