首发地址:https://zhuanlan.zhihu.com/p/143417405
1、梯度消失
1.1、换激活函数
从sigmoid换成relu或relu的一系列改进版,比如leaky relu等。sigmoid中导数接近于零的情况,就换成了导数恒定的情况,单个节点的梯度(导数)就不管x变化都永远有了。
但是多个0~1之间的数相乘还是趋近于0的趋势没变,所以只是缓解,而非完全解决。
1.2、Batch Norm
还用sigmoid,可以通过normalization将值scale到sigmoid的有效范围内,有效范围内导数大于0,可以缓解梯度下降的情况。
(图片来源 : 李宏毅讲transformer:www.bilibili.com/video/av56239558/)
上图中,横向红框是batch norm,纵向红框是layer norm
(图片来源 : https://blog.csdn.net/wsp_1138886114/article/details/81535272)
1.3、换网络结构
1.3.1、LSTM
下图红箭头路径是相加的关系,所以求梯度就不再是导数相乘的关系,就缓解了梯度下降的问题。(但是绿色路径依然存在梯度爆炸的问题。)
(图片来源 : https://www.cnblogs.com/pinking/p/9362966.html)
1.3.2、ResNet
感性理解是,导数整体加了1,相比原先就不那么容易梯度消失了吧。
更感性理解是,resnet是两个网络融合之后的结果,一个是原先的,一个是去掉这一层结构的,去掉后相乘的元素就少了一个,就不那么容易梯度消失了,,两个结构合并后也比原先更不容易梯度消失;多层resnet也是同理。
1.4、pretrain + fine-tuning
好多资料都说了这一点,可是我感觉这压根就是两码事,因为如果考虑可以换成预训练模型,那选项那么多,直接选不容易梯度消失的模型就可以了。问题就转成了怎么选模型的问题了,就已经不是怎么(通过小改动)解决梯度消失的问题了。故略。
2、梯度爆炸
**
2.1、梯度剪切
**
设置梯度的最大阈值,当算出来梯度很大,超过阈值时,就取最大阈值当做梯度。
强硬不让它炸。就这么简单粗暴有效。
(记得李宏毅说这方法最早的出现,并不在论文正文中,有人复现不出结果才看论文后面的资料,才看到。)
2.2、权重正则化
目标函数 = 损失函数 + 正则化项。通过目标函数中的正则化项,“惩罚”过大的权重,从而使权重不会过大,进而缓解梯度爆炸的问题。
比如L1、L2正则化项。
如果觉得有用,请点赞~