torch.autograd
模块给用户提供了一个自定义求导的接口。torch.autograd.grad
可以手动地将loss对某部分参数进行梯度求导,特别适用于debug和观测。
笔者经常使用这个接口用于观测模型优化出现问题时,梯度值是否出现异常;以及用于代替tensorboard等可视化工具,快速理解复杂的计算图。
比方说下面这段代码:
t2 = torch.autograd.grad(adv_loss,next(self.dis.parameters()),retain_graph=True)
t3 = torch.autograd.grad(adv_loss,next(self.gen.parameters()),retain_graph=True)
t1 = torch.autograd.grad(adv_loss,target,retain_graph=True)
用于观测,最终的loss是否由self.dis(model)、self.gen(model)、target(tensor)计算,进而用于判断哪些模型参与这个loss的优化。这个功能就类似于使用tensorboard可视化loss的计算过程,只不过这样更方便。
如果在autograd的时候出现如下错误:
“...appears to not have been used in the graph”
就说明,这部分模型参数、变量,并没有参与到这个loss的计算中,自然loss.backward()的时候,这部分参数也不会被优化。
用这种技巧的时候,要注意两个参数:
allow_unused=False
:默认False,意味着如果被求导参数不在计算图的话,会报错;如果设置为True,就算参数不在loss的计算图里,梯度也会被计算,而且必定为0。这里的话,必须设置为False,也就是如果参数不在计算图里,就会提示上述`“…appears to not have been used in the graph”的错误。
retain_graph=True
:默认为False,也就是一旦求导一次之后,计算图就会被释放;这里的话如果要观测多次autograd的结果,就必须设置为True,把计算图保留。
更多有关于torch.autograd.grad的细节,参见:
torch官方文档