Estoy transfiriendo mi red Caffe a TensorFlow pero no parece tener una inicialización xavier. Estoy usando, truncated_normal
pero esto parece hacer que sea mucho más difícil entrenar.
python
tensorflow
Alejandro
fuente
fuente
Respuestas:
En Tensorflow 2.0 y posteriores, ambos
tf.contrib.*
ytf.get_variable()
están en desuso. Para realizar la inicialización de Xavier, ahora debe cambiar a: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))
El uniforme Glorot y el uniforme Xavier son dos nombres diferentes del mismo tipo de inicialización. Si desea saber más sobre cómo usar las inicializaciones en TF2.0 con o sin Keras, consulte la documentación .
fuente
Dado que la versión 0.8 hay un inicializador de Xavier, consulte aquí los documentos .
Puedes usar algo como esto:
W = tf.get_variable("W", shape=[784, 256], initializer=tf.contrib.layers.xavier_initializer())
fuente
get_variable
sino dársela al inicializador? Solía tenertf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)
y especifiqué la forma allí, pero ahora tu sugerencia arruina mi código. ¿Tienes alguna sugerencia?tf.Variable(...)
y usatf.get_variable(...)
Solo para agregar otro ejemplo sobre cómo definir un
tf.Variable
inicializado usando el método de Xavier y 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)) ...
Esto me impidió tener
nan
valores en mi función de pérdida debido a inestabilidades numéricas al usar múltiples capas con RELU.fuente
La inicialización de @ Aleph7, Xavier / Glorot depende del número de conexiones entrantes (fan_in), el número de conexiones salientes (fan_out) y el tipo de función de activación (sigmoidea o tanh) de la neurona. Vea esto: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
Así que ahora, a tu pregunta. Así es como lo haría en 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))
Tenga en cuenta que deberíamos tomar muestras de una distribución uniforme y no de la distribución normal como se sugiere en la otra respuesta.
Por cierto, ayer escribí una publicación para algo diferente usando TensorFlow que también usa la inicialización de Xavier. Si está interesado, también hay un cuaderno de Python con un ejemplo de extremo a extremo: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb
fuente
Un buen envoltorio
tensorflow
llamadoprettytensor
ofrece una implementación en el código fuente (copiado directamente desde aquí ):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)
fuente
TF-contrib tiene
xavier_initializer
. Aquí hay un ejemplo de cómo usarlo: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)
Además de esto, tensorflow tiene otros inicializadores:
fuente
Miré y no pude encontrar nada integrado. Sin embargo, de acuerdo con esto:
http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization
La inicialización de Xavier solo muestra una distribución (generalmente gaussiana) donde la varianza es una función del número de neuronas.
tf.random_normal
puede hacer eso por usted, solo necesita calcular el stddev (es decir, el número de neuronas que está representado por la matriz de peso que está intentando inicializar).fuente
A través del
kernel_initializer
parámetro atf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense
etcp.ej
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
fuente
En caso de que quiera usar una línea como lo hace con:
W = tf.Variable(tf.truncated_normal((n_prev, n), stddev=0.1))
Tu puedes hacer:
fuente
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))
fuente