梯度截断
1.出现原因
由于进行反向传播时,进行每一层的梯度计算,假设梯度都是比较大的值,计算到第一层的梯度时,会呈指数级增长(反向传播,从后往前,有相乘的关系),那么更新完的参数值也会很大,越来越大,就会产生梯度爆炸的现象,找不到最优解。
所以,提出了梯度截断的方法。
2.解决方法
①按值截断
按值截断是比较简单粗暴的方法,由于梯度太大会产生梯度爆炸的现象,太小会产生梯度消失的现象(参数不更新),所以为梯度提供一个范围[a,b],
- 如果梯度大于b,就把它设置为b;
- 如果梯度小于a,就把它设置为a;
- 若在此区间,不做变化
pytorch下的使用
torch.nn.utils.clip_grad_value_(model.parameters(), value)
注:value就是b,a就直接默认为-value
②按模截断
为梯度g设置一个最大阈值threshold,用梯度的二范数与该阈值做比较;
- 若大于阈值,则对其进行压缩,计算公式如图所示
- 否则,不改变梯度
二范数:就是向量的每个方向上的值平方求和再开方
pytorch使用
torch.nn.utils.clip_grad_norm_(model.parameters(), threshold)
注:threshold即为阈值