神经网络中的权值初始化方法

1,概述 网络

  神经网络中的权值初始化方法有不少,可是这些方法的设计也是遵循一些逻辑的,而且也有本身的适用场景。首先咱们假定输入的每一个特征是服从均值为0,方差为1的分布(通常输入到神经网络的数据都是要作归一化的,就是为了达到这个条件)。dom

  为了使网络中的信息更好的传递,每一层的特征的方差应该尽量相等,若是保证这个特征的方差是相等的呢。咱们能够从初始化的权重值入手。函数

  首先来作一个公式推导:spa

  $var(s) = var(\sum_i^n w_i x_i)$设计

  $var(s) = \sum_i^n var(w_i x_i)$3d

  $var(s) = \sum_i^n E(w_i^2) E(x_i^2) - (E(x_i))^2 (E(w_i))^2$orm

  $var(s) = \sum_i^n (E(w_i))^2 var(x_i) + (E(x_i))^2 var(w_i) + var(x_i) var(w_i)$blog

  在这里假定了x的均值为0,对于初始化的权重一般均值也是选择0,所以上面的式子能够转换成get

  $var(s) = \sum_i^n var(x_i) var(w_i)$it

  又由于x中每一个特征咱们都假定方差为1,所以上面的式子能够改写成

  $var(s) = n * var(w)$

  如今要使得$var(s) = 1$,则有

  $n * var(w) = 1$。

  $var(w) = \frac{1}{n}$。

  为了确保量纲和指望一致,咱们将方差转换成标准差,所以要确保标准差为$\frac{1}{\sqrt{n}}$

2,初始化方法

  如今咱们来看看每种方法初始化时咱们该如何设置方差能保证输入的分布状态不变。

  1)均匀分布

  对于均匀分布$U (a, b)$,其指望和方差分别为$E(x) = \frac{(a+b)}{2},  D(x) = \frac{(b-a)^2}{12}$。

  假定均匀分布为$(-\frac{1}{\sqrt{d}},\frac{1}{\sqrt{d}})$,在这里$d$为神经元的个数,则有指望和方差为:

  $E(x) = 0,  D(x) = \frac{1}{3d}$

  代入到$var(s) = n * var(w)$中,能够获得:

  $var(s) = \frac{1}{3}$,所以为了保证最终的方差为1,所以方差须要乘以3,标准差则须要乘以$\sqrt{3}$。所以通常均匀分布的初始化值能够选择$(-\sqrt{\frac{3}{d}},\sqrt{\frac{3}{d}})$。

  在xavier uniform init(glorot uniform),也就是 tf.glorot_uniform_initializer()方法中初始化值为$(-\sqrt{\frac{6}{(d_{in}+d_{out})}},\sqrt{\frac{6}{d_{in}+d_{out}}})$。在一个二维矩阵中$d_{in}, d_{out}$分别表示矩阵的第一个维度和第二个维度。

  见下面一个例子,对于tf.glorot_uniform_initializer()方法:

    

  能够看到通过一层神经网络以后,x的指望和方差基本不变。对于均匀分布tf.random_uniform_initializer(),当咱们将参数初始化为$(-\sqrt{\frac{3}{d}},\sqrt{\frac{3}{d}})$。其结果以下:

    

   2)正态分布

  正态分布会直接给出指望和标准差,因此这个不用多说。为了保证$var(s) = 1$,咱们须要让$var(w) = \frac{1}{d}$,则标准差为$\sqrt{\frac{1}{d}}$。

  tf.random_normal_initializer(),咱们将其标准差设置为$\sqrt{\frac{1}{d}}$。结果以下:

    

   xavier normal init(glorot normal),也就是tf.glorot_normal_initializer(),其标准差为$\sqrt{\frac{2}{(d_{in} + d_{out})}}$,其结果以下:

    

  3)常数初始化

    常数初始化时指望为常数值n,方差为0。

    tf.zeros_initializer(),以0初始化会致使输出x为0。

      

    tf.ones_initializer(),以1初始化方差会很大

       

     tf.constant_initializer(),同上

      

 

 3,引入激活函数

   上面都是在线性运算的状况下的结果,但实际应用中都是要引入激活函数的,这样神经网络才具备更强的表达能力。若是引入激活函数会怎么样?

   为了观看效果,咱们将网络层数设置为100层,权重初始化采用tf.glorot_normal_initializer()

  不加激活函数时:

    

  能够看到不加激活函数,方差即便在100层时也基本保持不变。

  引入tanh函数,

    

  结果如上,方差会减少到0.005,所以在深层网络中引入归一化层确实是很重要的。

  引入relu函数:

    

  上面的结果很显然relu函数并不适用tf.glorot_normal_initializer()。对于relu激活函数时,正态分布的标准差一般为$\sqrt{\frac{2}{d}}$,均匀分布一般为$(-\sqrt{\frac{6}{d}},\sqrt{\frac{6}{d}})$。所以更换下初始化参数,结果以下

    

   上面看结果就好不少了,方差在100层的输出为0.1,结果是比tanh要好的,此外这里的指望再也不接近0,由于relu函数就是不像tanh那样关于0对称的。

  另外我还发现一个奇怪的事情,暂时没法解释,能够给你们看下结果:

  当咱们直接用tf.random_normal_initializer()初始化时,此时方差为1。

  不引入激活函数。

    

   100层后获得的指望和方差都为nan,应该是发生爆炸了。

  引入tanh函数:

    

   100层后居然能保持方差为1。

  relu激活函数:

    

   指望和方差均为0。

  从上面的结果看好像在用tanh作激活函数时,能够直接将参数用0,1的正态分布初始化。

 

 4,初始化的随机性

  在实践中还发现一个问题,就是参数的大小也会影响最终的结果,以relu激活函数为例。为了方便计算,x和w的维度一致

   全部维度为512,两次获得的结果差别比较大:

    

    

   其实这个也好理解,自己x和w都是随机初始化的,虽然分布是同样的,可是具体的值并不同,最终的结果也不同,因此说即便一样的分布初始化,有时候获得的结果也会有所差别,这个差别多是收敛的速度,也多是最终的结果等等。

 

参考文献:

神经网络中的初始化

神经网络中的权重初始化一览:从基础到Kaiming

相关文章
相关标签/搜索