(补充):深层次网络中的梯度消失和梯度爆炸现象,原因以及处理方式

本文探讨了在深度学习中常见的梯度消失和梯度爆炸问题,分析了这些问题产生的原因,包括网络层次过深和激活函数的选择不当。并提出了几种解决方案,如梯度剪切、正则化、更换激活函数及使用LSTM网络。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于梯度消失和爆炸,其前提是采用梯度下降办法去更新网络参数,使得代价函数最小化。出现梯度消失和爆炸的原因基本上归为两点:一,网络层次太深,由于很多网络的更新时的链式原理,使得更新信息往往指数级变化;二,采用了不合适的激活函数,比如sigmoid,梯度爆炸一般出现在深层网络和权值初始化值太大的情况下。

1.深层网络角度

比较简单的深层网络如下:

这里写图片描述


图中是一个四层的全连接网络,假设每一层网络激活后的输出为f_{i}\left ( x \right ),其中i为第i层, x代表第i层的输入,f是激活函数,那么,得出f_{i+1}=f\left ( f_{i}*\omega _{i+1}+b_{i+1} \right )
例如BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,参数的更新为w←w+Δw,给定学习率α,得出\Delta \omega =-\alpha \frac{\partial Loss}{\partial \omega }​。如果要更新第二隐藏层的权值信息,根据链式求导法则,更新梯度信息:
\Delta \omega _{2}=\frac{\partial Loss}{\partial \omega _{2}}=\frac{\partial Loss}{\partial f_{4}}\frac{\partial f_{4}}{\partial f_{3}}\frac{\partial f{_{3}}}{\partial f{_{2}}}\frac{\partial f_{2}}{\partial \omega _{2}},很容易看出来\frac{\partial f_{2}}{\partial \omega _{2}}=\frac{\partial f}{\partial (f_{1}*\omega _{2}))}f_{1}​,即第二隐藏层的输入。
所以说,\frac{\partial f_{3}}{\partial f_{4}}​​就是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。

2.激活函数角度

其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其导数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失。


sigmoid函数sigmoid函数导数

梯度消失、爆炸的解决方案

1.梯度剪切、正则

梯度剪切这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。

另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)。

2.换用relu、leakrelu、elu等激活函数

3.LSTM

LSTM全称是长短期记忆网络(long-short term memory networks),是不那么容易发生梯度消失的,主要原因在于LSTM内部复杂的“门”(gates),如下图,LSTM通过它内部的“门”可以接下来更新的时候“记住”前几次训练的”残留记忆“,因此,经常用于生成文本中。

 

这里写图片描述

### YOLOv8颈部网络架构及其功能 YOLOv8继承并优化了前代YOLO系列模型的设计理念,在颈部网络(neck network)方面采用了路径聚合网络(PANet),这与YOLOv4中的设计相似[^2]。具体来说,PANet通过自底向上自顶向下的多尺度特征融合机制来增强不同层次特征图之间的信息交互。 #### 路径聚合网络(PANet) - **双向特征金字塔**:PANet构建了一个双向的特征金字塔结构,不仅能够从低层到高层传递空间细节信息,还能反向传播高层次语义信息至底层。这种双向的信息流有助于提高小目标检测精度以及整体性能。 - **横向连接**:为了进一步加强跨层间的信息交流,PANet引入了横向连接,使得每一级特征都能获得来自其他级别的补充信息,从而更好地捕捉物体的各种尺度变化。 ```python class PANet(nn.Module): def __init__(self, in_channels_list, out_channel=256): super().__init__() self.lateral_convs = nn.ModuleList() self.fpn_convs = nn.ModuleList() for i in range(len(in_channels_list)): lateral_conv = ConvModule( in_channels_list[i], out_channel, kernel_size=1) fpn_conv = ConvModule( out_channel, out_channel, kernel_size=3, padding=1) self.lateral_convs.append(lateral_conv) self.fpn_convs.append(fpn_conv) def forward(self, inputs): laterals = [ lat_conv(inputs[i]) for i, lat_conv in enumerate(self.lateral_convs)] used_backbone_levels = len(laterals) for i in range(used_backbone_levels - 1].shape[2:] laterals[i - 1] += F.interpolate( laterals[i], size=prev_shape, mode='nearest') outs = [ self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels)] return tuple(outs) ``` 此代码片段展示了如何实现一个简单的PANet模块,其中包含了卷积操作用于调整通道数,并通过插值方法完成高分辨率特征图与低分辨率特征图间的拼接工作。 #### 颈部网络的作用 - **提升多尺度感知能力**:通过对不同层级特征的有效组合,使模型具备更强的空间位置敏感性更广泛的视野范围,这对于处理具有复杂背景或遮挡情况的目标尤为重要。 - **改善梯度回传效率**:由于存在丰富的短路链接,减少了深层神经元更新过程中可能出现消失/爆炸现象的风险,促进了整个网络更快收敛于最优解附近。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值