一、均匀分布uniform
1.1 介绍
服从~ U ( a , b ) U ( a , b ) U(a,b)
1.2 代码
1.2.1 torch
torch.nn.init.uniform_(tensor, a=0, b=1)
#给Tensor或者Variable填充值使其满足均匀分布U(a,b)
#参数:
#tensor: 一个待填充的 torch.Tensor or autograd.Variable
#a: 均匀分布下界
#b: 均匀分布上届
#Examples:
# >>> w = torch.Tensor(3, 5)
# >>> nn.init.uniform_(w)
if isinstance(tensor, Variable):
#如果是Variable类型,给他的data tensor填充数值即可
uniform_(tensor.data, a=a, b=b)
return tensor
提示:现在使用torch.nn.init.uniform_(tensor, a=0, b=1)
而不使用torch.nn.init.uniform(tensor, a=0, b=1)
1.2.2 mxnet
uniform = mx.init.Uniform()
# 使用从给定范围内均匀采样的随机值初始化权重。
class Uniform(Initializer)
| Uniform(scale=0.07 )
| 参数: scale
| 比例尺:float,可选
| 生成的随机值范围的边界。
| 值从范围[-`scale`,`scale`]生成。
| 默认比例为0.07
# 案例: 在-0.1到0.1之间均匀采样的随机值。
init = mxnet.init.Uniform(0.1) # 正太分布初始化 的 实例化
module.init_params(init) # 模型参数 初始化
二、正太分布normal
2.1 介绍
服从~ N ( m e a n , s t d ) N ( m e a n , s t d ) N(mean,std)
2.2 代码
2.2.1 torch
torch.nn.init.normal_(tensor, mean=0, std=1)
#给Tensor或者Variable填充值使其满足正态分布N(mean, std)
#参数:
#tensor: n维待填充的 torch.Tensor or autograd.Variable
#mean: 正态分布均值
#std: 正态分布方差
#Examples:
# >>> w = torch.Tensor(3, 5)
# >>> nn.init.normal_(w)
if isinstance(tensor, Variable):
normal(tensor.data, mean=mean, std=std)
return tensor
return tensor.normal_(mean, std)
#torch.normal_在C++代码中实现
2.2.2 mxnet
init = mx.init.Normal()
class Normal(Initializer)
| Normal(sigma=0.01)
使用从正态分布中采样的随机值初始化权重,均值为零且标准差为sigma
| 参数:sigma
| sigma:float,可选
| 正态分布的标准偏差。
| 默认标准偏差为0.01。
方法:
init = mx.init.Normal(0.5)
module.init_params(init)
init.dumps() # 将初始化保存为字符串,(json格式)
三、初始化为常数constant
3.1 介绍
初始化整个矩阵为常数val
3.2 代码
3.2.1 torch
torch.nn.init.constant_(tensor, val)
#给tensor或者Variable填充常数Val.
#参数:
#tensor: n维 torch.Tensor or autograd.Variable
#val: 填充的常数
#Examples:
# >>> w = torch.Tensor(3, 5)
# >>> nn.init.constant_(w)
if isinstance(tensor, Variable):
constant_(tensor.data, val)
return tensor
return tensor.fill_(val)
3.2.2 mxnet
mxnet.init.Constant(value)
class Constant(Initializer)
| Constant(value)
将权重初始化为给定值。传入的值可以是与要设置的参数形状匹配的标量或NDarray
四、xavier_init()
4.1 思想来源
如果初始化值很小,那么随着层数的传递,方差就会趋于0,此时输入值 也变得越来越小,在sigmoid上就是在0附近,接近于线性,失去了非线性
如果初始值很大,那么随着层数的传递,方差会迅速增加,此时输入值变得很大,而sigmoid在大输入值写倒数趋近于0,反向传播时会遇到梯度消失的问题
其他的激活函数同样存在相同的问题。
https://prateekvjoshi.com/2016/03/29/understanding-xavier-initialization-in-deep-neural-networks/
所以论文提出,在每一层网络保证输入和输出的方差相同。
4.2 过程推导
来源自:https://blog.csdn.net/nini_coded/article/details/79302820
初始化方法由Bengio等人在2010年的论文《Understanding the difficulty of training deep feedforward neural networks》中提出。
它为了保证前向传播和反向传播时每一层的方差一致,根据每层的输入个数和输出个数来决定参数随机初始化的分布范围,是一个通过该层的输入和输出参数个数得到的分布范围内的均匀分布。
公式如下:
U
[
−
6
s
q
r
t
n
i
n
+
n
o
u
t
,
6
s
q
r
t
n
i
n
+
n
o
u
t
]
U[-\frac{\sqrt{6}}{sqrt{n_{in}+n_{out}}},\frac{\sqrt{6}}{sqrt{n_{in}+n_{out}}}]
U[−sqrtnin+nout6,sqrtnin+nout6]
其中:
n
i
n
n_{in}
nin,
n
o
u
t
n_{out}
nout分别表示该层输入和输出的参数(权重)个数。
具体推导如下:
假设某层激活函数为线性(非线性与之类似),输入输出关系如下:
y
=
∑
i
=
1
n
ω
i
x
i
+
b
y=\sum^n_{i=1}\omega_ix_i+b
y=i=1∑nωixi+b
定义
D
(
x
i
)
和
D
(
w
i
)
D(x_i) 和 D(w_i)
D(xi)和D(wi) 分别为随机变量
x
i
和
w
i
x_i 和 w_i
xi和wi 的方差,根据方差公式有:
D
(
w
i
x
i
)
=
E
(
w
i
)
2
D
(
x
i
)
+
E
(
x
i
)
2
D
(
w
i
)
+
D
(
w
i
)
D
(
x
i
)
D(w_ix_i)=E(w_i)^2D(x_i)+E(x_i)^2D(w_i)+D(w_i)D(x_i)
D(wixi)=E(wi)2D(xi)+E(xi)2D(wi)+D(wi)D(xi)
设计网络时,我们通常会用一些tricks使每层的输入和权值的均值为0,,则有:
D
(
w
i
x
i
)
=
D
(
w
i
)
D
(
x
i
)
D(w_ix_i)=D(w_i)D(x_i)
D(wixi)=D(wi)D(xi)
假设输入
x
i
和
权
值
w
i
x_i和权值 w_i
xi和权值wi 独立同分布:
D
(
y
)
=
n
D
(
w
i
)
D
(
x
i
)
D(y)=nD(w_i)D(x_i)
D(y)=nD(wi)D(xi)
由于输入和输出方差相同(控制):
D
(
y
)
=
D
(
x
)
D(y)=D(x)
D(y)=D(x) ,所以有:
D
(
w
)
=
1
n
D(w)=\frac{1}{n}
D(w)=n1
对于多层网络,正向传播时第
i
i
i 层的输出方差
D
(
y
i
)
D(y_i)
D(yi) 可用前面各层方差的乘积表示:
D
(
y
i
)
=
D
(
x
i
)
∏
k
=
0
i
−
1
n
k
D
(
w
k
)
D(y_i)=D(x_i)\prod^{i-1}_{k=0}n_kD(w_k)
D(yi)=D(xi)k=0∏i−1nkD(wk)
其中,
D
(
x
i
)
D(x_i)
D(xi) 为第
i
i
i 层的输入,
n
k
和
w
k
n_k 和 w_k
nk和wk 分别为前面第
k
k
k 层的参数数量和长度为
n
k
n_k
nk 的权值向量。
反向传播时,与正向传播类似:
D
(
∂
L
∂
w
i
)
=
D
(
∂
L
∂
w
m
)
∏
p
=
i
m
n
p
+
1
D
(
w
p
)
D({\frac{\partial L}{\partial w_i}}) = D({\frac{\partial L}{\partial w_m}}) \prod_{p=i}^{m}n_{p+1} D(w_p)
D(∂wi∂L)=D(∂wm∂L)p=i∏mnp+1D(wp)
其中,
L
L
L 为最高层第
m
m
m 层的损失函数。
对于每一层的权值向量
w
i
w_i
wi,正向与反向传播的方差
D
(
x
i
)
D(x_i)
D(xi) 相等:
n
i
D
(
w
i
)
=
1
n_i D(w_i) = 1
niD(wi)=1
n
i
+
1
D
(
w
i
)
=
1
n_{i+1}D(w_i) = 1
ni+1D(wi)=1
由于通常相邻两层的权重参数的数量不同,因此选择:
D
(
w
i
)
=
2
n
i
+
n
i
+
1
D(w_i) = \frac{2}{n_i+n_{i+1}}
D(wi)=ni+ni+12
为了满足在某个关于原点对称的范围内实现均匀分布,所以Xavier的初始化为在如下范围内的均匀分布:
U
[
−
6
n
i
n
+
n
o
u
t
,
6
n
i
n
+
n
o
u
t
]
U [-\frac{\sqrt{6}}{\sqrt{n_{in}+n_{out}}},\frac{\sqrt{6}}{\sqrt{n_{in}+n_{out}}}]
U[−nin+nout6,nin+nout6]
4.3 代码
4.3.1 torch
对于Xavier初始化方式,pytorch提供了uniform和normal两种:
- 均匀分布
torch.nn.init.xavier_uniform_(tensor, gain=1)
均匀分布 ~
U
(
−
a
,
a
)
U ( − a , a )
U(−a,a)
其中, a的计算公式:
a
=
g
a
i
n
×
6
f
a
n
i
n
+
f
a
n
o
u
t
a=gain \times \sqrt{\frac{6}{fan_{in}+fan_{out}}}
a=gain×fanin+fanout6
2. 正太分布
torch.nn.init.xavier_normal_(tensor, gain=1)
正态分布~N ( 0 , s t d ) N(0,std)N(0,std)
其中std的计算公式:
s
t
d
=
g
a
i
n
×
2
f
a
n
i
n
+
f
a
n
o
u
t
std=gain \times \sqrt{\frac{2}{fan_{in}+fan_{out}}}
std=gain×fanin+fanout2
4.3.2 mxnet
class Xavier(Initializer)
| Xavier(rnd_type='uniform', factor_type='avg', magnitude=3)
返回对权重执行“ Xavier”初始化的初始化器。
此初始化程序旨在使所有图层中的渐变比例大致相同。
# 参数
- 默认情况下:
rnd_type='uniform'
均匀分布;factor_type='avg'
是均匀分布中随机填充的数字范围
math:[-c, c]
,
where :math: c = 3. 0.5 ∗ ( n i n + n o u t ) c = \sqrt{\frac{3.}{0.5 * (n_{in} + n_{out})}} c=0.5∗(nin+nout)3.
n_ {in}”是馈入权重的神经元数量,n_ {out}
是将结果馈入神经元的数量。 rnd_type
is'uniform'
均匀分布 andfactor_type
is'in'
,
math: c = 3. n i n c = \sqrt{\frac{3.}{n_{in}}} c=nin3..
Similarly whenfactor_type
is'out'
,
math: c = 3. n o u t c = \sqrt{\frac{3.}{n_{out}}} c=nout3..rnd_type
is'gaussian'
andfactor_type
is'avg'
,
rnd_type='gaussian’高斯分布;factor_type='in’是正太分布中的标准差
范围:
3. 0.5 ∗ ( n i n + n o u t ) \sqrt{\frac{3.}{0.5 * (n_{in} + n_{out})}} 0.5∗(nin+nout)3.