PyTorch:如何检查在训练期间某些重量是否没有改变?

PyTorch:如何检查在训练期间某些重量是否没有改变?,pytorch,Pytorch,我如何检查在PyTorch训练期间某些重量是否没有改变 据我所知,一个选项可以是在某些时期转储模型权重,并检查它们是否在权重上迭代更改,但可能有更简单的方法?有两种方法: 首先 用于模型中的名称、参数。命名参数() 如果名称中有“重量”: 温度=火炬零点(参数梯度形状) 温度[参数梯度!=0]+=1 计数记录[名称]+=温度 此步骤是在培训模块中的丢失.backward()步骤之后执行的。count\u dict[name]字典跟踪渐变更新。您可以在开始培训之前以这种方式初始化: 用于模型中的

我如何检查在PyTorch训练期间某些重量是否没有改变


据我所知,一个选项可以是在某些时期转储模型权重,并检查它们是否在权重上迭代更改,但可能有更简单的方法?

有两种方法:

首先

用于模型中的名称、参数。命名参数()
如果名称中有“重量”:
温度=火炬零点(参数梯度形状)
温度[参数梯度!=0]+=1
计数记录[名称]+=温度
此步骤是在培训模块中的
丢失.backward()步骤之后执行的。
count\u dict[name]
字典跟踪渐变更新。您可以在开始培训之前以这种方式初始化:

用于模型中的名称、参数。命名参数()
如果名称中有“重量”:
count_dict[name]=火炬零点(参数梯度形状)
现在,另一种方法是注册一个钩子函数,然后创建钩子函数,如果需要,您甚至可以在其中更新或修改渐变。这并不是跟踪权重更新所必需的,但如果您想对渐变做些什么,它会很方便。 假设,这里我随机稀疏梯度

def hook_fn(梯度):
'''
随机稀疏梯度
:param grad:图层的输入梯度
:return:grad_clone-稀疏FC层渐变
'''
grad_clone=grad.clone()
temp=火炬、cuda、浮动张量(梯度克隆、形状).uniform()
梯度克隆[温度<0.8]=0
返回梯度克隆
在这里,我给模型一个钩子

for name, param in model.named_parameters():
    if 'weight' in name:
            param.register_hook(hook_fn)
因此,这可能只是为您稀疏梯度,您可以通过以下方式在钩子函数本身中跟踪梯度:

def hook_func(module, input, output):
    temp = torch.zeros(output.shape)
    temp[output != 0] += 1
    count_dict[module] += temp

尽管如此,我不建议这样做。这通常在可视化向前传球功能/激活的情况下非常有用。而且,输入和输出可能会混淆,因为梯度和参数输入和输出是相反的。

您可以设置一个钩子来检查梯度,然后您可以通过计算零的数量来跟踪计数器梯度值是否曾经更新过。@AnuragReddy示例会很好。检查答案@如果有什么不对劲或令人困惑,请随时询问或纠正我。我可能也从你那里学到了一些东西:)似乎hook并不总是可以被称为hook,也可以使用
register\u hook
来代替
.grad
丢失后。backward()
?如果
.grad
不是
是否总是意味着权重将被更新?@mrglud回答您的第一个问题-因此,通常挂钩在可视化中间激活(前挂钩)或在后挂钩的情况下都很有用,它们在训练本身的同时在修改梯度时很有用。假设,您想要选通某些更新,或者有一些参数或值可以乘以或添加到渐变中,那么挂钩就好了。关于问题2-如果
.grad
不是
None
,我假设您设置
requires\u grad=False
,因为表示更新的是渐变本身的值。我的意思是,
.grad
值不能是None,但同时它可以是
0
和其他值的混合。因此,如果值为0,则表示synapse将保持不变且不会更新,并且在您共享的环境中,我建议直接使用
.grad
,而不是使用挂钩。因为,您不想修改渐变。是的,你可以在一个钩子中给出无梯度选项(通过在钩子函数中将所有梯度设置为0):P。