如何在TensorFlow上进行Xavier初始化
我将我的Caffenetworking移植到TensorFlow,但似乎没有xavier初始化。 我正在使用truncated_normal
但是这似乎使得它更难以训练。
从0.8版本开始,有一个Xavier初始化程序, 请参阅这里的文档 。
你可以使用这样的东西:
W = tf.get_variable("W", shape=[784, 256], initializer=tf.contrib.layers.xavier_initializer())
@ Aleph7,Xavier / Glorot初始化取决于传入连接(fan_in)的数量,传出连接的数量(fan_out)以及神经元的激活函数(sigmoid或tanh)的types。 看到这个: http : //jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
所以,现在,你的问题。 这就是我如何在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))
请注意,我们应该从统一的分布抽样,而不是按照其他答案中所build议的正态分布。
顺便说一下,我昨天写了一篇文章,用于使用TensorFlow不同的东西,也发生了使用Xavier初始化。 如果你有兴趣,还有一个端到端的python笔记本: https : //github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb
一个名为prettytensor
包装器提供了源代码的实现(直接从这里复制):
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)
只是增加另一个例子来说明如何定义一个使用Xavier和Yoshua方法初始化的tf.Variable :
graph = tf.Graph() with graph.as_default(): ... initializer = tf.contrib.layers.xavier_initializer() w1 = tf.Variable(initializer(w1_shape)) b1 = tf.Varialbe(initializer(b1_shape)) ...
这阻止了我在使用RELU使用多个图层时由于数值不稳定而对我的损失函数具有nan
值。
我看,我找不到任何内置的东西。但是,根据这个:
http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization
Xavier初始化只是采样(通常是高斯)分布,其中方差是神经元数量的函数。 tf.random_normal
可以为你做这个,你只需要计算stddev(即你想要初始化的权重matrix表示的神经元的数量)。
TF-contrib有xavier_initializer
。 这里是一个如何使用它的例子:
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)
除此之外,tensorflow还有其他的初始化程序:
- xavier_initializer_conv2d
- variance_scaling_initializer
- constant_initializer
- zeros_initializer
- ones_initializer
- uniform_unit_scaling_initializer
- truncated_normal_initializer
- random_uniform_initializer
- random_normal_initializer
- orthogonal_initializer
- 以及来自keras的许多初始化器