神经网络反向传播过程中,函数中间变量梯度的查看、修改方法(计算图中间变量梯度查看、修改方法)

本文介绍了在PyTorch中如何查看非叶子节点的梯度,通过hook函数保存中间变量的梯度,并展示了如何修改计算图节点的梯度,包括整体梯度和特定位置的梯度。同时提到了使用梯度裁剪来防止梯度爆炸的问题。
摘要由CSDN通过智能技术生成

1.查看计算图节点梯度

很多时候在BP过程中需要查看某个变量的梯度,来看看到底在梯度计算和计算图计算过程中发生了什么,如果是叶子节点,或是神经网络内部的节点,或者是loss等值还好,可以使用pytorch自带的  .grad  方法直接查看。

loss.retain_grad()
print(loss.grad)

        但是如果想查看的中间变量是自定义函数计算过程中的非叶子节点,这些中间变量的梯度在函数执行后是不能在函数外查看的,就需要用hook的思想,把他勾出来记一下。方法如下:

# 先定义函数
grads = {}
def save_grad(name):
    def hook(grad):
        grads[name] = grad
    return hook



# 在想查看的位置添加register_hook(函数内部或这个中间变量出现的地方)
t3.register_hook(save_grad('t3')) # 保存t3的梯度

# 最后输出这个中间变量梯度
print("[grads]t3:", grads['t3'])

2.修改计算图节点梯度

        有些时候想人为修改某个节点的梯度,例如在BP过程中,某个节点的梯度出现了不理想值,需要修改,可以考虑这个方法(注意!!慎用,该方法相当于直接改回传梯度,会影响整体梯度回传,当梯度不理想时,建议认真查原因,而不是人为强制修改回传梯度)

# 定义修改函数
def hook_fn(grad):
    grad = torch.zeros_like(grad)
    return grad

# 在需要修改梯度的中间变量的后边添加这个register_hook,
# BP时会直接执行上边自定义的梯度修改函数,这里我对s2中间变量的i[0]位置的数的梯度进行修改。没错,甚至可以改一个1*n tensor中某个位置的梯度,这取决于代码逻辑。
s2[i[0]].register_hook(hook_fn)

3.(常用)修改梯度

如果担心梯度爆炸之类的发生,推荐使用clip_grad进行梯度剪裁

loss.backward()  # 反向传播求梯度
nn.utils.clip_grad_norm_(model.parameters(), max_norm=args.clip)  # 进行梯度裁剪

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值