deeplearning权重以及dl4j 权重

我们在创建深度神经网络时,通常要对网络的权重初始化,而在dl4j中大概有如下权重类型(枚举型):

DISTRIBUTION,ZERO,SIGMOID_UNIFORM,UNIFORM,XAVIER,XAVIER_UNIFORM,XAVIER_FAN_IN,XAVIER_LEGACY,RELU,RELU_UNIFORM;

接下来我会对这些类型做进一步说明(其中可能会引用一些其他杂志或论文的图片,如果涉及侵权,请及时联系本人,谢谢)

为什么要进行权重初始化:(数学符合这个编辑器无法打出来,直接写文字)权重w,输入x,偏置b

简单来说根据公式有 f=sum(xi*wi)+b,计算出的f,而f有可能是一个远小于-1或者远大于1的数,通过激活函数(比如sigmoid)后所得到的输出会非常接近0或者1,也就是隐藏层神经元处于饱和的状态。为了避免这种情况,我们应该调整权重大小,而这种改变会影响f值,使f值接近于0,进而会影响激活值。


图-1 

如果激活函数是这个f(t)=sigmoid(t),那么可以看到,当f是一个远小于-1或者远大于1的数,那么通过激活函数计算出的值将会非常接近于0或者1,这样造成了什么严重后果呐,从图中我们可以看到梯度消失了,非常接近于0了,既然如此,那么nn只能两眼发呆,啥也学不到。

如何进行权重初始化:

综上,初始化weight是非常重要的,容不得半点马虎,我们必须保证权重初始化在一个合理的范围。或者说为了让f接近于值0,使神经元处于不太饱和状态,我们需要赋予它一个合适的值。当然,大多数情况下我们需要根据不同的激活函数初始化不同的权重类型。对于许多人来说,我们在构建满足自己业务需求的nn时,有个疑问?到底哪一个权重是适合的?一种通用的方式就是选用高斯分布(正太分布)权重。还是说说具体的吧,比如在dl4j的权重初始化大概有以下几类。


(一)DISTRIBUTION:

ret = dist.sample(shape);

Sample weights from a provided distribution

给定分布的样例权重


很明显高斯分布或者正太分布将趋向0均值和有限的方差


(二)RELU:

ret = Nd4j.randn(order, shape).muli(FastMath.sqrt(2.0 / fanIn)); //N(0, 2/nIn)

He et al. (2015), "Delving Deep into Rectifiers". Normal distribution with variance 2.0/nIn

 

(三)RELU_UNIFORM:

double u = Math.sqrt(6.0 / fanIn);

ret = Nd4j.rand(shape, Nd4j.getDistributions().createUniform(-u, u)); //U(-sqrt(6/fanIn), sqrt(6/fanIn)

He et al. (2015), "Delving Deep into Rectifiers". Uniform distribution U(-s,s) with s = sqrt(6/fanIn)

 

(四)SIGMOID_UNIFORM:

double r = 4.0 * Math.sqrt(6.0 / (fanIn + fanOut));

ret = Nd4j.rand(shape, Nd4j.getDistributions().createUniform(-r, r));

A version of XAVIER_UNIFORM for sigmoid activation functions. U(-r,r) with r=4*sqrt(6/(fanIn + fanOut))

 

(五)UNIFORM:

double a = 1.0 / Math.sqrt(fanIn);

ret = Nd4j.rand(shape, Nd4j.getDistributions().createUniform(-a, a));

 Uniform U[-a,a] with a=1/sqrt(fanIn). "Commonly used heuristic" as per Glorot and Bengio 2010

 

(六)XAVIER:

ret = Nd4j.randn(order, shape).muli(FastMath.sqrt(2.0 / (fanIn + fanOut)));

As per Glorot and Bengio 2010: Gaussian distribution with mean 0, variance 2.0/(fanIn + fanOut)

 如何执行xavier初始化?

如果我们想让通过nn的每一个layer的方差相同,我们就必须计算y的方差,也就是输入值f的方差

var(y) = var(w1x1 + w2x2 + ... + wNxN + b)
我们计算上面等式右边的方差,如果考虑通用术语,那么进一步我们会有如下公式:

var(wixi) = E(xi)2var(wi) + E(wi)2var(xi) + var(wi)var(xi)
这里E()代表给定变量的期望值,一般来说就是表示平均值,我们假定输入值x和权重w来自0均值方差的高斯分布,于是E()可以取消,公式更变如下:(0均值就是样本的数学期望是0)

var(wixi) = var(wi)var(xi)
注意b是一个静态变量,且是一个0方差,所以b在这里可以不写,我们替代原始的等式,则如下显示

var(y) = var(w1)var(x1) + ... + var(wN)var(xN)
由于它们有相同的分布,所以公式继续可以写为:
var(y) = N * var(wi) * var(xi)
如果我们想让y的方差和x的方差相等,那么术语中N * var(wi)应当等于1,于是有如下公式:

N * var(wi) = 1
var(wi) = 1/N
我们继续拓展,我们得到了xavier初始化的公式。当然,我们需要从0均值和1/N的方差中选取权重,这里的N是指神经网络的输入神经元的数量。如何实现caffe library,在原论文中,作者取得是输入神经元数量和输出神经元数量的平均值。所以公式演化如下:
var(wi) = 1/Navg 
where Navg = (Nin + Nout)/2
这样做的原因是在BP中可以较好的保持特征值,但是这样导致了更复杂的计算。于是我们在实际中仅仅需要输入神经元的数量就可以了。

 

参考论文:http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf

(七)XAVIER_UNIFORM:

 

double s = Math.sqrt(6.0) / Math.sqrt(fanIn + fanOut);

ret = Nd4j.rand(shape, Nd4j.getDistributions().createUniform(-s, s));

 As per Glorot and Bengio 2010: Uniform distribution U(-s,s) with s = sqrt(6/(fanIn + fanOut))

 

(八)XAVIER_FAN_IN:

ret = Nd4j.randn(order, shape).divi(FastMath.sqrt(fanIn));

Similar to Xavier, but 1/fanIn -> Caffe originally used this.

 

(九)XAVIER_LEGACY:

ret = Nd4j.randn(order, shape).divi(FastMath.sqrt(shape[0] + shape[1]));

 Xavier weight init in DL4J up to 0.6.0. XAVIER should be preferred.

 

(十)ZERO:

ret = Nd4j.create(shape, order);

 Generate weights as zeros

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值