pytorch hook

只要有一个tensor的requires_grad设置为True,那么接下来的计算中所有相关的tensor都会支持自动求导求梯度

设计的net里面的权重参数默认都是可以进行自动梯度求导的,我们平常的loss.backward()中反向求导中的所要更新的值也就是net中的权重参数值。


for param in dehaze_net.parameters():
 print(param.requires_grad)
 
True
True
True
True
True
True
True
True
True
True
for param in dehaze_net.parameters():
 print(param.size())
 
torch.Size([3, 3, 1, 1])
torch.Size([3])
torch.Size([3, 3, 3, 3])
torch.Size([3])
torch.Size([3, 6, 5, 5])
torch.Size([3])
torch.Size([3, 6, 7, 7])
torch.Size([3])
torch.Size([3, 12, 3, 3])
torch.Size([3])

register hook

但是自动求导的机制有个我们需要注意的地方

我们输入x是一个拥有两个元素的向量(x1,x2),y=(x12,x22)=(y1,y2) , z = (y1+y2)/2。

最终也就是z = (x12 + x22)/2,显然x1和x2对输出的导数是(1,1),但是如果我们看y和z的导数会发现什么也没有输出。

In[2]: import torch
In[3]: x = torch.tensor([1,2],dtype=torch.float32,requires_grad=True)
In[4]: y = x * 2
In[5]: z = torch.mean(y)
In[6]: z
Out[6]: tensor(3.)
In[7]: z.backward()
In[8]: x.grad
Out[8]: tensor([ 1.,  1.])
In[9]: y.grad # 应该为(0.5,0.5)
In[10]: z.grad # 应该为1

这是因为在自动求导机制中只保存叶子节点,也就是中间变量在计算完成梯度后会自动释放以节省空间,所以上面代码我们在计算过程中只得到了z对x的梯度。

如何得到y和z的梯度呢,这就需要hook函数了:

register hook (hook)[source] 这个函数属于torch.tensor类,这个函数在与这个tensor梯度计算的时候就会执行,这个函数的参数hook是一个函数,这个函数应该是以下的形式:

hook(grad) -> Tensor or None 。grad是这个tensor的梯度,该函数返回grad,我们可以改变这个hook函数的返回值,但是不能改变其参数。

In[2]: import torch
In[3]: x = torch.tensor([1,2],dtype=torch.float32,requires_grad=True)
In[4]: y = x * 2
In[5]: y.requires_grad
Out[5]: True
In[6]: y.register_hook(print)
Out[6]: <torch.utils.hooks.RemovableHandle at 0x7f765e876f60>
In[7]: z = torch.mean(y)
In[8]: z.backward()
tensor([ 0.5000,  0.5000])

register_backward_hooksrc_code

之前说的是tensor中的register_hook,现在说的这个函数是module类里面的hook函数,module即我们平常使用pytorch定义神经网络层时需要的模板类。register_backward_hook和register_forward_hook是差不多的,一个在backward中执行一个在forward中执行.

ref
https://cloud.tencent.com/developer/article/1122582
https://www.cnblogs.com/hellcat/p/8512090.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值