深度学习之权重初始化

这篇具有很好参考价值的文章主要介绍了深度学习之权重初始化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在深度学习中,神经网络的权重初始化方法( w e i g h t weight weight i n i t i a l i z a t i o n initialization initialization)对模型的收敛速度和性能有着至关重要的影响。说白了,神经网络其实就是对权重参数 w w w的不停迭代更新,以达到更好的性能。因此,对权重 w w w的初始化则显得至关重要,一个好的权重初始化虽然不能完全解决梯度消失和梯度爆炸的问题,但是对于处理这两个问题是有很大的帮助的,并且十分有利于模型性能和收敛速度。

本文将介绍以下五种常见的权重初始化的方法:

权重初始化为 0 0 0
权重随机初始化
X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization
H e He He i n i t i a l i z a t i o n initialization initialization
预训练权重
权重初始化为 0 0 0

如果将权重初始化全部为 0 0 0的话,这样的操作等同于等价于一个线性模型,将所有权重设为 0 0 0时,对于每一个 w w w而言,损失函数的导数都是相同的,因此在随后的迭代过程中所有权重都具有相同的值,这会使得隐藏单元变得对称,并继续运行设置的 n n n次的迭代,会导致网络中同一个神经元的不同权重都是一样的。下面代码为权重初始化为 0 0 0的代码:

def initialize_parameters_zeros(layers_dims):
    """
    Arguments:
    layer_dims -- python array (list) containing the size of each layer.
    Returns:
    parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL":
                    W1 -- weight matrix of shape (layers_dims[1], layers_dims[0])
                    b1 -- bias vector of shape (layers_dims[1], 1)
                    ...
                    WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1])
                    bL -- bias vector of shape (layers_dims[L], 1)
    """
    parameters = {}
    np.random.seed(3)
    L = len(layers_dims)  # number of layers in the network
    for l in range(1, L):
        parameters['W' + str(l)] = np.zeros((layers_dims[l], layers_dims[l - 1]))
        parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
    return parameters

让我们来看看权重初始化为 0 0 0之后其 c o s t cost cost f u n c t i o n function function是如何变化的,从图中可以看出,当代价函数降到 0.64 0.64 0.64(迭代 1000 1000 1000次)后,梯度逐渐消失,再训练迭代已经不起什么作用了。
深度学习之权重初始化,深度学习基础,深度学习,人工智能
权重随机初始化

权重随机初始化是比较常见的做法,即 W W W随机初始化。随机初始化的代码如下:

def initialize_parameters_random(layers_dims):
    """
    Arguments:
    layer_dims -- python array (list) containing the size of each layer.
    Returns:
    parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL":
                    W1 -- weight matrix of shape (layers_dims[1], layers_dims[0])
                    b1 -- bias vector of shape (layers_dims[1], 1)
                    ...
                    WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1])
                    bL -- bias vector of shape (layers_dims[L], 1)
    """
    np.random.seed(3)  # This seed makes sure your "random" numbers will be the as ours
    parameters = {}
    L = len(layers_dims)  # integer representing the number of layers
    for l in range(1, L):
        parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l - 1])*0.01
        parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
    return parameters

上述代码中权重乘 0.01 0.01 0.01是因为要把 W W W随机初始化到一个相对较小的值,因为如果 X X X很大的话, W W W又相对较大,会导致 Z Z Z非常大,这样如果激活函数是 s i g m o i d sigmoid sigmoid,就会导致 s i g m o i d sigmoid sigmoid的输出值 1 1 1或者 0 0 0,然后会导致一系列问题(比如 c o s t cost cost f u n c t i o n function function计算的时候, l o g log log里是 0 0 0,这样会有点麻烦)。随机初始化后, c o s t cost cost f u n c t i o n function function随着迭代次数的变化示意图如下图 2 2 2所示为
深度学习之权重初始化,深度学习基础,深度学习,人工智能
能够看出, c o s t cost cost f u n c t i o n function function的变化是比较正常的。但是随机初始化也有缺点, n p . r a n d o m . r a n d n ( ) np.random.randn() np.random.randn()其实是一个均值为 0 0 0,方差为 1 1 1的高斯分布中采样。当神经网络的层数增多时,会发现越往后面的层的激活函数(使用 t a n H tanH tanH)的输出值几乎都接近于 0 0 0,极易出现梯度消失。如下图 3 3 3所示:

深度学习之权重初始化,深度学习基础,深度学习,人工智能

X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization

在使用以上两种方法来初始化权重极易出现梯度消失的问题,而 X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization出现就解决了上面问题。其思想倒就是尽可能的让输入和输出服从相同的分布,这样就能够避免后面层的激活函数的输出值趋向于 0 0 0。本文主要介绍 P y t o r c h Pytorch Pytorch当中 X a v i e r Xavier Xavier均匀分布和 X a v i e r Xavier Xavier正态分布初始化这两种方式。

我们来简单推导一下 X a v i e r Xavier Xavier初始化的原理:首先我们定义一层的卷积运算为如下公式,其中 n i {n_i} ni表示输入的个数。

y = w 1 x 1 + ⋅ ⋅ ⋅ + w n i x n i + b y = w_1x_1 + ··· + w_{ni}x_{ni}+ b y=w1x1+⋅⋅⋅+wnixni+b

根据我们学过的概率论统计知识可以得到如下的方差公式:

V a r ( w i x i ) = E [ w i ] 2 V a r ( x i ) + E [ x i ] 2 V a r ( w i ) + V a r ( w i ) V a r ( x i ) Var(w_ix_i)=E[w_i]^2Var(x_i) + E[x_i]^2Var(w_i) + Var(w_i)Var(x_i) Var(wixi)=E[wi]2Var(xi)+E[xi]2Var(wi)+Var(wi)Var(xi)

当我们假设输入和输入的权重的均值都是 0 0 0(使用BN层以后很容易就可以满足)时,上式可以简化为:

V a r ( w i x i ) = V a r ( w i ) V a r ( x i ) Var(w_ix_i)=Var(w_i)Var(x_i) Var(wixi)=Var(wi)Var(xi)

进一步我们假设输入 x x x和权重 w w w都是独立同分布,则可以得到:

V a r ( y ) = n i V a r ( w i ) V a r ( x i ) Var(y) = n_iVar(w_i)Var(x_i) Var(y)=niVar(wi)Var(xi)

于是按照 X a v i e r Xavier Xavier的要求保证输入和输出的方差要一致,则可以得到:

V a r ( w i ) = 1 n i Var(w_i) = \frac{1}{n_i} Var(wi)=ni1

对于一个多层的网络,某一层的方差可以用累积的形式表达:

V a r [ z i ] = V a r [ x ] ∏ i = 0 i − 1 n i V a r [ W i ‘ ] Var[z^i] = Var[x]\prod_{i^{}=0}^{i-1}n_i^Var[W^{i^`}] Var[zi]=Var[x]i=0i1niVar[Wi]

对于误差反向传播也有类似的表达形式,如下所示,其中 n i + 1 n_{i+1} ni+1表示输出个数

V a r [ ∂ C o s t ∂ s i ] = V a r [ ∂ C o s t ∂ s d ] ∏ i = i d n i + 1 V a r [ W i ‘ ] Var[\frac{\partial Cost}{\partial s^i}] = Var[\frac{\partial Cost}{\partial s^d}]\prod_{i^{}=i}^{d}n_{i^+1}Var[W^{i^`}] Var[siCost]=Var[sdCost]i=idni+1Var[Wi]

综上,为了保证前向传播和反向传播时每一层的方差一致,应满足:

∀ i , n i V a r [ W i ] = 1 \forall_i ,n_iVar[W^i]=1 iniVar[Wi]=1

∀ i , n i + 1 V a r [ W i ] = 1 \forall_i ,n_{i+1}Var[W^i]=1 ini+1Var[Wi]=1

但是,实际当中输入与输出的个数往往不相等,于是为了均衡考量输出和输入,最终我们的权重的方差应满足如下要求:

∀ i , V a r [ W i ] = 2 n i + n i + 1 \forall_i ,Var[W^i]= \frac{2}{n_i + n_{i+1}} iVar[Wi]=ni+ni+12

1、 X a v i e r Xavier Xavier均匀分布初始化

对于均匀分布来说,我们都知道区间 [ a , b ] [a,b] [a,b]的方差为:

V a r = ( b − a ) 2 12 Var=\frac{(b-a)^2}{12} Var=12(ba)2

那么就需要将均匀分布的方差等于我们在上面推导出来的 X a v i e r Xavier Xavier的权重方差,即:

( b − a ) 2 12 = 2 n i + n i + 1 \frac{(b-a)^2}{12} = \frac{2}{n_i + n_{i+1}} 12(ba)2=ni+ni+12

经过化解后 ( a + b = 0 ) (a+b=0) (a+b=0)可以得到 X a v i e r Xavier Xavier均匀初始化后权重的取值范围为:

W − U [ − 6 n i + n i + 1 , 6 n i + n i + 1 ] W - U[-\frac{\sqrt{6}}{\sqrt{n_i+n_{i+1}}}, \frac{\sqrt{6}}{\sqrt{n_i+n_{i+1}}}] WU[ni+ni+1 6 ,ni+ni+1 6 ]

原理我们讲完了,现在来看一下在 P y t o r c h Pytorch Pytorch中是如何调用 X a v i e r Xavier Xavier均匀分布初始化的:

# tensor表示要初始化的张量,gain表示缩放因子
torch.nn.init.xavier_uniform(tensor, gain=1)

# 举例说明:
w = torch.Tensor(3, 5)
nn.init.xavier_uniform(w, gain=math.sqrt(2))

2、 X a v i e r Xavier Xavier正态分布初始化

我们都知道均值为 0 0 0,标准差为 σ \sigma σ的正态分布方差为

V a r = σ 2 Var=\sigma^2 Var=σ2

同样的,需要将正态分布的方差等于我们在上面推导出来的 X a v i e r Xavier Xavier的权重方差,即:

σ 2 = 2 n i + n i + 1 \sigma^2 = \frac{2}{n_i + n_{i+1}} σ2=ni+ni+12

经过化解后可以得到 X a v i e r Xavier Xavier正态分布初始化后权重的标准差为:

σ = 2 n i + n i + 1 \sigma = \sqrt{\frac{2}{n_i + n_{i+1}}} σ=ni+ni+12

那么我们再来看一下在 P y t o r c h Pytorch Pytorch中是如何调用 X a v i e r Xavier Xavier正态分布初始化的:

# tensor表示要初始化的张量,gain表示缩放因子
torch.nn.init.xavier_normal(tensor, gain=1)

# 举例说明:
w = torch.Tensor(3, 5)
nn.init.xavier_normal(w)

3、 X a v i e r Xavier Xavier权重初始化表现效果

如下图 4 4 4所示为采用 X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization后每层的激活函数输出值的分布,从图中我们可以看出,深层的激活函数输出值还是非常服从标准高斯分布。
深度学习之权重初始化,深度学习基础,深度学习,人工智能
虽然 X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization能够很好的适用于 t a n H tanH tanH 激活函数,但对于目前神经网络中最常用的 R e L U ReLU ReLU激活函数,还是无能能力,如下图 5 5 5所示为采用 R e L U ReLU ReLU激活函数后, X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization初始化的每层激活函数输出值的分布,从图中可以看出当达到 5 5 5 6 6 6层后几乎又开始趋向于 0 0 0,更深层的话很明显又会趋向于 0 0 0
深度学习之权重初始化,深度学习基础,深度学习,人工智能
由此可见, X a v i e r Xavier Xavier权重初始化方式比较适用于 t a n H tanH tanH S i g m o i d Sigmoid Sigmoid激活函数,而对于 R e L U ReLU ReLU这种非对称性的激活函数还是容易出现梯度消失的现象。

H e He He i n i t i a l i z a t i o n initialization initialization

H e He He i n i t i a l i z a t i o n initialization initialization是由何凯明大神提出的一种针对 R e L U ReLU ReLU激活函数的初始化方法。 H e He He i n i t i a l i z a t i o n initialization initialization的思想是:和 X a v i e r Xavier Xavier初始化方式一样,都希望初始化使得正向传播时,状态值的方差保持不变,反向传播时,关于激活值的梯度的方差保持不变。由于小于 0 0 0的值经过 R e L U ReLU ReLU激活函数都会变成 0 0 0,而大于 0 0 0的值则保持原值。因此在 R e L U ReLU ReLU网络中,假定每一层有一半的神经元被激活,另一半为 0 0 0,所以,要保持 v a r i a n c e variance variance不变,只需要在 X a v i e r Xavier Xavier的基础上再除以2即可。本文主要介绍 P y t o r c h Pytorch Pytorch当中 H e He He i n i t i a l i z a t i o n initialization initialization均匀分布和 H e He He i n i t i a l i z a t i o n initialization initialization正态分布初始化这两种方式。

对于 H e He He i n i t i a l i z a t i o n initialization initialization的推导来说前面和 X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization是相似的,但在方差推到过程中,需要将式子左侧除以 2 2 2,如下所示:

V a r ( y ) = 1 2 n i V a r ( w i ) V a r ( x i ) Var(y) = \frac{1}{2}n_iVar(w_i)Var(x_i) Var(y)=21niVar(wi)Var(xi)

为了保证输出和输入的方差一直,则可以得到权重的方差为:

V a r ( w i ) = 2 n i Var(w_i) = \frac{2}{n_i} Var(wi)=ni2

对于 B a c k w a r d Backward Backward来说和 F o r w a r d Forward Forward思路是相似的,只不过需要考虑到链式求导法则,这里不予以推导,只给出最终的结果为:

V a r ( w i + 1 ) = 2 n i + 1 Var(w_{i+1}) = \frac{2}{n_{i+1}} Var(wi+1)=ni+12

1、 H e He He i n i t i a l i z a t i o n initialization initialization均匀分布初始化

X a v i e r Xavier Xavier均匀分布初始化操作一样我们得到 H e He He i n i t i a l i z a t i o n initialization initialization的取值范围为:

W − U [ − 6 n i + ( a 2 + 1 ) , 6 n i + ( a 2 + 1 ) ] W - U[-\frac{\sqrt{6}}{\sqrt{n_i+(a^2+1)}}, \frac{\sqrt{6}}{\sqrt{n_i+(a^2+1)}}] WU[ni+(a2+1) 6 ,ni+(a2+1) 6 ]

P y t o r c h Pytorch Pytorch H e He He i n i t i a l i z a t i o n initialization initialization也叫做 k a i m i n g kaiming kaiming,调用代码如下:

# tensor表示要初始化的张量
# a表示这层之后使用的rectifier的斜率系数(ReLU的默认值为0
# mode可以为“fan_in”(默认)或“fan_out”。
# “fan_in”保留前向传播时权值方差的量级,“fan_out”保留反向传播时的量级。
torch.nn.init.kaiming_uniform(tensor, a=0, mode='fan_in')

# 举例说明:
w = torch.Tensor(3, 5)
nn.init.kaiming_uniform(w, mode='fan_in')

2、 H e He He i n i t i a l i z a t i o n initialization initialization正态分布初始化

X a v i e r Xavier Xavier正态分布初始化操作一样我们得到 H e He He i n i t i a l i z a t i o n initialization initialization的标准差为:

σ = 2 n i + ( a 2 + 1 ) \sigma = \sqrt{\frac{2}{n_i + (a^2+1)}} σ=ni+(a2+1)2

P y t o r c h Pytorch Pytorch X a v i e r Xavier Xavier正态分布初始化的调用代码如下:

# tensor表示要初始化的张量
# a表示这层之后使用的rectifier的斜率系数(ReLU的默认值为0
# mode可以为“fan_in”(默认)或“fan_out”。
# “fan_in”保留前向传播时权值方差的量级,“fan_out”保留反向传播时的量级。
torch.nn.init.kaiming_normal(tensor, a=0, mode='fan_in')

# 举例说明:
w = torch.Tensor(3, 5)
nn.init.kaiming_normal(w, mode='fan_out')

3、 H e He He i n i t i a l i z a t i o n initialization initialization权重初始化表现效果

如下图 6 6 6所示为采用 H e He He i n i t i a l i z a t i o n initialization initialization方式初始化权重后,隐藏层使用 R e L U ReLU ReLU时,激活函数的输出值的分布情况,从图中可知,针对 R e L U ReLU ReLU激活函数, H e He He i n i t i a l i z a t i o n initialization initialization效果是比 X a v i e r Xavier Xavier i n i t i a l i z a t i o n initialization initialization好很多。
深度学习之权重初始化,深度学习基础,深度学习,人工智能
由此可见, H e He He i n i t i a l i z a t i o n initialization initialization权重初始化方式是非常适用于 R e L U ReLU ReLU激活函数。

预训练模型

目前更多的使用已经针对相似任务已经训练好的模型,称之为预训练模型。在训练开始时就已经有了非常好的初始化参数,只需要将最后的全连接层进行冻结,训练其他部分即可。

总结

1、权重采用初始化为 0 0 0和随机初始化都比较容易出现梯度消失的问题,因此不常用。

2、 X a v i e r Xavier Xavier权重初始化方式主要针对于 t a n H tanH tanH s i g m o i d sigmoid sigmoid激活函数。

3、 H e He He i n i t i a l i z a t i o n initialization initialization权重初始化方式主要针对于 R e L U ReLU ReLU激活函数。

4、如果有相似任务已经训练好的模型,也可以考虑采用预训练模型来作权重初始化。文章来源地址https://www.toymoban.com/news/detail-572657.html

到了这里,关于深度学习之权重初始化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从零构建深度学习推理框架-2 从CSV文件初始化Tensor

    概念 CSV(逗号分隔值)文件是一种特殊的文件类型,可在 Excel 中创建或编辑。CSV文件采用逗号分隔的形式来存储文本和数字信息,总体来说,这种形式的文件格式具有扩展性好,移植性强的特点。 目前许多主流程序采用CSV文件作为数据导入导出的 中间格式 ,例如MySQL数据库

    2024年02月15日
    浏览(45)
  • 【go零基础】go-zero从零基础学习到实战教程 - 2项目初始化

    到项目初始化过程了,这边的项目设计完全按照作者自己的喜好来进行定义和设置的,所以各位完全可以按照自己的偏好自喜设置哈。 首先是创建一个工作文件夹哈。 别问为啥不直接quickstart,因为quickstart生成的api名字是greet,改起来很麻烦(头秃)。 注1: go-zero-demo是我随便

    2024年04月26日
    浏览(42)
  • 【深度学习】 Python 和 NumPy 系列教程(三):Python容器:1、列表List详解(初始化、索引、切片、更新、删除、常用函数、拆包、遍历)

    目录 一、前言 二、实验环境 三、Python容器(Containers) 0、容器介绍 1、列表(List) 1. 初始化 a. 创建空列表 b. 使用现有元素初始化列表 c. 使用列表生成式 d. 复制列表 2. 索引和切片 a. 索引 b. 负数索引 c. 切片 3. 常用操作(更新、删除) a. 更新单个元素 b. 更新切片 c. 删除单

    2024年02月09日
    浏览(51)
  • C++ 学习 ::【基础篇:13】:C++ 类的基本成员函数:类类型成员的初始化与构造函数问题

    本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段: 基础篇、STL 篇、高阶数据结构与算法篇 ,相关重点内容如下: 基础篇 : 类与对象 (涉及C++的三大特性等); STL 篇 : 学习使用 C++ 提供的 STL 相关库 ; 高阶数据结构与算

    2024年02月08日
    浏览(60)
  • 【Go学习之 go mod】gomod小白入门,在github上发布自己的项目(项目初始化、项目发布、项目版本升级等)

    Go语言基础之包 | 李文周的博客 Go mod的使用、发布、升级 | wei Go Module如何发布v2及以上版本 1.2.7. go mod命令 — 新溪-gordon V1.7.9 文档 golang go 包管理工具 go mod的详细介绍-腾讯云开发者社区-腾讯云 Go Mod 常见错误的原因 | walker的博客 oceanweave/testgomod 用于发布 go 包,v1 v2 版本等

    2024年02月03日
    浏览(63)
  • 基于ansible初始化linux服务器基础环境。

    大家好,今天我要和大家分享一个关于搭建centos环境的新方法。 以前我们经常会看到一些文章介绍如何搭建centos环境,但很多时候都会出现一些问题。不过现在有了一种新的方法,就是使用ansible脚本来实现。 虽然这种方法仅适用于centos7,但只要稍作修改就可以应用到其他的

    2023年04月27日
    浏览(45)
  • [C++]类与对象(下) -- 初始化列表 -- static成员 -- 友元 -- 内部类,一篇带你深度了解。

      目录 1、再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.2.1 初始化列表的意义 1.3 explicit 2、static成员 2.1 问题引入 2.2 特性 3、友元 3.1 友元函数 3.2 友元类 4、内部类 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 我们构造函

    2024年02月12日
    浏览(43)
  • 神经网络基础-神经网络补充概念-24-随机初始化

    在神经网络的训练过程中,权重和偏差的初始值对模型的性能和训练过程的收敛速度都有影响。随机初始化是一种常用的权重和偏差初始值设置方法,它有助于打破对称性,避免网络陷入局部最优解。 当所有权重和偏差都被设置为相同的初始值时,神经网络的每个神经元在反

    2024年02月12日
    浏览(50)
  • 【C++基础(六)】类和对象(下)--初始化列表,友元,匿名对象

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++初阶之路⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 关于类和对象的大致内容已经结束 本篇文章主要是介绍一些冗杂的细节 虽然本节的内容属于对类和对象锦上添花 但在很多特定的场所下,还是

    2024年02月14日
    浏览(61)
  • STM32的GPIO初始化配置-学习笔记

            由于刚开始没有学懂GPIO的配置原理,导致后面学习其它外设的时候总是产生阻碍,因为其它外设要使用前,大部分都要配置GPIO的初始化,因此这几天重新学习了一遍GPIO的配置,记录如下。         首先我们要知道芯片上的引脚,并不是只有GPIO的功能,还能复用成

    2024年04月17日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包