相信大家在看一些论文实现的时候, 很多时候都会看到xavier的实现. 对于一个喜欢刨根问底的人来说, 就会产生许多疑问:
xavier
这个名字啥意思?- 它是一个什么样的权重分部?
- 它解决了什么问题?
- 它为什么有效?
- 它跟其他初始化方法比有哪些不同?
- 它实现起来怎么样?
- 它有其他变种吗?
- 学会它能忽悠面试官吗?
- 不用它会怎么样?
- 除了它还能用啥?
- ....
问题很多. 我们也不用一一解答, 这些问题应该伴随着你的整个工作学习流程去慢慢思考.
今天主要解决两个问题, 它是什么, 它为什么有用.
这个初始化方法首次提出于这里: http://machinelearning.wustl.edu/mlpapers/paper_files/AISTATS2010_GlorotB10.pdf. 在tensorflow里面有一个 tf.glorot_norm_initializer 实际上就是xavier.
但是为什么glorot要被叫做xavier呢? 不得而知, 可能有另外一个人也提出过类似的东西?
那么这个xavier到底是个啥分部呢?
我们看一个代码:
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初始化实际上就是截断的高斯分布或者均匀分布, 根据输入输出确定方差和区域.
那么为什么这样做它就有效了呢?
这个就得从神经网络反向传播说起了..