如何在pytorch中正确进行渐变裁剪?

时间:2019-02-15 20:09:45

标签: python machine-learning pytorch gradient-descent

在pytorch中执行梯度剪切的正确方法是什么?

我有一个爆炸性的渐变问题,我需要解决这个问题。

3 个答案:

答案 0 :(得分:2)

clip_grad_norm(在执行就地修改时,实际上遵循尾部clip_grad_norm_的更一致的语法而实际上不赞成使用_)限制了的规范通过串联传递给函数的所有参数来实现整体渐变,如the documentation所示:

  

范数是在所有梯度上一起计算的,就好像它们被串联到单个矢量中一样。渐变就地修改。

从您的示例中看起来,您似乎想要clip_grad_value_来代替,它具有类似的语法,并且还可以就地修改渐变:

clip_grad_value_(model.parameters(), clip_value)

另一个选择是注册backward hook。这将当前渐变作为输入,并可能返回一个张量,该张量将代替先前的渐变使用,即对其进行修改。每次计算完梯度后都会调用此钩子,即,在钩子注册后就无需手动裁剪:

for p in model.parameters():
    p.register_hook(lambda grad: torch.clamp(grad, -clip_value, clip_value))

答案 1 :(得分:2)

更完整的示例

optimizer.zero_grad()        
loss, hidden = model(data, hidden, targets)
loss.backward()

torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip)
optimizer.step()

来源:https://github.com/pytorch/pytorch/issues/309

答案 2 :(得分:1)

通读documentation可以做到这一点:

clipping_value = 1#arbitrary number of your choosing
torch.nn.utils.clip_grad_norm(model.parameters(), clipping_value)

我敢肯定,它的深度要比仅此代码段还要深。