梯度裁剪
引入
梯度裁剪(Gradient Clipping)是一种在深度学习中用于防止梯度爆炸的技术。原理是通过对梯度进行限制,将梯度的大小控制在一个合理的范围内,避免梯度出现过大的极端情况,从而保证模型训练的稳定性和有效性。
L2范数裁剪
设模型参数为\(\theta\),梯度为\(\nabla\theta\),阈值为\(c\),则
总梯度L2范数: \[ \mathrm{total\_norm} = ||\nabla\theta|| = \sqrt{\sum_{i}(\nabla\theta_i)^2} \] 其中,\(\nabla\theta_i\)是第\(i\)个参数的梯度。
若\(\mathrm{total\_norm} > c\),则需要进行梯度裁剪,缩放梯度: \[ \begin{aligned} &\mathrm{scale} = \frac{c}{\mathrm{total\_norm}}\\ \\ &\nabla\theta_i\longleftarrow\nabla\theta_i\times\mathrm{scale} \end{aligned} \] 即 \[ \nabla\theta' = \begin{cases} \displaystyle\frac{c}{||\nabla\theta||}\nabla\theta\quad & \mathrm{if}\ ||\nabla\theta||>c\\ \\ \nabla\theta&\mathrm{otherwise} \end{cases} \]
按范数裁剪是考虑了整个模型中的所有参数的梯度,将其当成一个整体,若这个整体的梯度太大,则对所有的梯度进行放缩,不论其中某个参数的梯度是大还是小。
按元素裁剪
对于梯度\(\nabla\theta\)中的每个元素,\(\nabla\theta_i\),如果\(\nabla\theta_i>c\),则将其设置为\(c\),如果\(\nabla\theta_i<-c\),则将其设置为\(-c\),数学表达式为: \[ \nabla\theta_i' = \begin{cases} c\quad\quad& \mathrm{if}\ \nabla\theta_i > c\\ \\ -c& \mathrm{if}\ \nabla\theta_i < -c\\ \\ \nabla\theta_i&\mathrm{otherwise} \end{cases} \] 按元素裁剪的方式是针对每个参数,若这个参数的梯度太大,则裁剪,否则维持这个参数的梯度。
PyTorch实现梯度裁剪
使用L2范数裁剪:
1 |
|
将模型model
的参数的L2范数限制在max_norm
范围内,梯度裁剪需要用在模型backward()
方法之后,也就是需要模型先反向传播生成梯度。
比如:
1 |
|
使用元素裁剪:
1 |
|
将模型model
的参数的梯度的每个元素限制在[-clip_value, clip_value]
范围内。
比如:
1 |
|