我正在尝试提取在 PyTorch 的拟合函数期间计算的值:相对于参数的梯度;参数本身;和梯度的 L-2 范数。这是我实现这些目标的代码。
def get_theta(self):
theta = self.parameters().detach().cpu
return theta
def get_norm2Gradient(self,xb,yb):
grad = self.fit(xb.to(device),yb.to(device))
theta = self.parameters()
#collects gradient along new parameters
for param in theta:
grad.append(param.grad)
#computes gradient norm
norm2Gradient = torch.linalg.norm(grad).detach().cpu
return norm2Gradient
def fit(self, loader, epochs = None):
#loss_mean = []
norm2Gradient = 1
while norm2Gradient <10e-3 and epochs <2000:
#grad = []
for _, batch in enumerate(loader):
x, y = batch['x'], batch['y']
#computes f.cross_entropy loss of (xb,yb) on GPU
loss = self.loss(x,y)
#print("loss:", loss)
loss = loss.mean()
#print("loss mean:", loss)
#clears out old gradients
self.optimizer.zero_grad()
#calculates new gradients
grad = loss.backward()
print("grad:",grad)
#takes one step along new gradients to decrease the loss
self.optimizer.step()
#captures new parameters
theta = self.parameters()
print("theta:",theta)
#collects gradient along new parameters
for param in theta:
grad.extend(param.grad)
#computes gradient norm
norm2Gradient = torch.linalg.norm(grad)
return grad
这是重复出现的错误消息
UnboundLocalError: local variable 'grad' referenced before assignment
它发生在这行代码,它从代码的另一部分调用 fit 函数。
grad = model.fit(dataloader)
我用 Google 搜索了错误消息,这些结果表明 grad 变量可能为空。我尝试打印该函数的值但没有成功。我还阅读了我撰写此问题时提示的先前提出的堆栈问题建议。在我更新 fit 函数(并添加 get_theta 和 get_norm2Gradient 函数)之前,代码运行良好。
这是由于您的
while
条件出现错误
def fit(self, loader, epochs = None):
#loss_mean = []
norm2Gradient = 1
while norm2Gradient <10e-3 and epochs <2000:
...
return grad
自
norm2Gradient = 1
起,条件 norm2Gradient <10e-3
变为 False
并且 while
循环永远不会执行。当 return grad
变量尚未分配时,该函数会尝试 grad
。这会触发错误。
也就是说,您的方法还有另一个问题。你的梯度张量将具有不同的形状,因此你不能将它们串在一个列表中并计算它们的 L2 范数。您可能想单独计算每个梯度张量的 L2 范数,然后计算平均值。