【理论】【代码】参数随机初始化方法

15 篇文章 8 订阅
12 篇文章 3 订阅

一、均匀分布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=1nω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 xiwi 的方差,根据方差公式有:
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 xiwi 独立同分布:
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=0i1nkD(wk)
其中, D ( x i ) D(x_i) D(xi) 为第 i i i 层的输入, n k 和 w k n_k 和 w_k nkwk 分别为前面第 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(wiL)=D(wmL)p=imnp+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+nout 6 ,nin+nout 6 ]

4.3 代码

4.3.1 torch

对于Xavier初始化方式,pytorch提供了uniform和normal两种:

  1. 均匀分布
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”初始化的初始化器。
 此初始化程序旨在使所有图层中的渐变比例大致相同。
 # 参数
  1. 默认情况下: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}是将结果馈入神经元的数量。
  2. rnd_type is 'uniform'均匀分布 and factor_type is 'in',
    math: c = 3. n i n c = \sqrt{\frac{3.}{n_{in}}} c=nin3. .
    Similarly when factor_type is 'out',
    math: c = 3. n o u t c = \sqrt{\frac{3.}{n_{out}}} c=nout3. .
  3. rnd_type is 'gaussian' and factor_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.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深度神经模糊随机森林(Deep Neural Fuzzy Random Forest,DNF-RF)是一种结合了模糊逻辑、神经网络和随机森林的机器学习算法。以下是一个使用Python实现DNF-RF的示例代码: ```python import numpy as np from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error import math # 定义模糊逻辑函数 def fuzzy_logic(x, a, b, c, d): if x <= a or x >= d: return 0 elif a < x <= b: return (x - a) / (b - a) elif b < x <= c: return 1 elif c < x < d: return (d - x) / (d - c) # 定义深度模糊神经网络模型 class DNF_NN(): def __init__(self, num_inputs, num_hidden_layers, num_hidden_nodes): self.num_inputs = num_inputs self.num_hidden_layers = num_hidden_layers self.num_hidden_nodes = num_hidden_nodes self.weights = [] self.biases = [] for i in range(num_hidden_layers+1): if i == 0: w = np.random.randn(num_inputs, num_hidden_nodes) b = np.random.randn(num_hidden_nodes) elif i == num_hidden_layers: w = np.random.randn(num_hidden_nodes, 1) b = np.random.randn(1) else: w = np.random.randn(num_hidden_nodes, num_hidden_nodes) b = np.random.randn(num_hidden_nodes) self.weights.append(w) self.biases.append(b) def predict(self, X): a = np.copy(X) for i in range(self.num_hidden_layers+1): z = np.dot(a, self.weights[i]) + self.biases[i] if i == self.num_hidden_layers: y = z else: y = np.zeros_like(z) for j in range(self.num_hidden_nodes): y[j] = fuzzy_logic(z[j], -1, -0.5, 0.5, 1) a = y return y # 定义深度模糊随机森林模型 class DNF_RF(): def __init__(self, num_trees, num_inputs, num_hidden_layers, num_hidden_nodes): self.num_trees = num_trees self.num_inputs = num_inputs self.num_hidden_layers = num_hidden_layers self.num_hidden_nodes = num_hidden_nodes self.trees = [] for i in range(num_trees): tree = DNF_NN(num_inputs, num_hidden_layers, num_hidden_nodes) self.trees.append(tree) def fit(self, X, y): for i in range(self.num_trees): indices = np.random.choice(X.shape[0], X.shape[0], replace=True) X_boot = X[indices] y_boot = y[indices] self.trees[i].fit(X_boot, y_boot) def predict(self, X): predictions = np.zeros((X.shape[0], self.num_trees)) for i in range(self.num_trees): predictions[:, i] = self.trees[i].predict(X).flatten() return np.mean(predictions, axis=1) # 测试代码 if __name__ == '__main__': # 生成示例数据 X = np.random.randn(1000, 5) y = np.sin(X[:,0]) + np.cos(X[:,1]) + np.tan(X[:,2]) + np.power(X[:,3], 2) + np.exp(X[:,4]) # 划分训练集和测试集 X_train = X[:800] X_test = X[800:] y_train = y[:800] y_test = y[800:] # 训练模型 model = DNF_RF(num_trees=10, num_inputs=5, num_hidden_layers=2, num_hidden_nodes=10) model.fit(X_train, y_train) # 测试模型 y_pred = model.predict(X_test) mse = mean_squared_error(y_test, y_pred) rmse = math.sqrt(mse) print('RMSE:', rmse) ``` 在上面的代码中,我们首先定义了一个模糊逻辑函数fuzzy_logic,它用于将输入映射到0和1之间的模糊值。然后定义了一个深度模糊神经网络模型DNF_NN,它包含了多个隐藏层和多个隐藏节点,每个节点都使用模糊逻辑函数进行激活。最后定义了一个深度模糊随机森林模型DNF_RF,它包含了多个DNF_NN模型,并且每个模型都使用不同的数据子集进行训练。在测试代码中,我们首先生成了一个示例数据集,并将其划分为训练集和测试集。然后使用DNF_RF模型对训练集进行训练,并使用测试集进行测试,输出了RMSE作为性能指标。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值