花瓣小跑 发表于 2024-10-20 20:59:13

pytorch求hessian

起首有个
网络界说

随意界说了,根据自己的情况
class ANN(nn.Module):
    def __init__(self):
      super(ANN, self).__init__()
      self.fc1 = nn.Linear(10000, 1)
      # self.fc1.bias.data.fill_(0)
      
    def forward(self, data):
      x = self.fc1(data)
      return x
求hessian

autograd这个方法求梯度的时候分子是scalar ,分母是vector的时候,也即scalar对vector求导,得到的梯度向量和vector一样,而对于vector对vector求导,autograd没法求,只能求scalar对vector求导,以是需要循环。

def getHessian(grads, model, loss_fn, dat, tar ,device):


    loss = loss_fn(model(dat), tar)
    grads_fn = torch.autograd.grad(loss, model.parameters(), retain_graph=True, create_graph=True) # 记录一阶梯度的grad_fn
       
        # 这部分是更新一阶梯度的值,因为其实我要计算的一阶梯度的值是grads
    for source, target in zip(grads, grads_fn):
      target.data.copy_(source)

    hessian_params = []
    #第k个梯度
    for k in range(len(grads_fn)):
      # 第i个参数
      for param in model.parameters():
            hess_params = []
            # 第k个梯度的地i行参数
            for i in range(grads_fn.size(0)):
                # 判断是w还是b
                if len(grads_fn.size()) == 2:
                  # w
                  for j in range(grads_fn.size(1)):
                        hess = torch.autograd.grad(grads_fn, param, retain_graph=True, allow_unused= True)
                        hess_params.append(hess.cpu().detach().numpy() if hess is not None else None)
                else:
                  # b
                  hess = torch.autograd.grad(grads_fn, param, retain_graph=True, allow_unused=True)
                  hess_params.append(hess.cpu().detach().numpy() if hess is not None else None)
            hessian_params.append(np.array(hess_params))
    return hessian_params
关于backward和autograd

autograd只计算梯度不反向传播更新model的参数,由于这部分是torch中的优化器举行的,backward()也计算梯度,但获得具体一门路度信息需要用这个命令
   grad_list =
而这样得到的一门路度是不含grad_fn的,再举行求导的时候报错,虽然我也尝试loss.backward(retain_graph=True)用了这里的参数,但仍然无法解决问题,以是照旧用了autograd。但在模型更新的时候两者利用并不冲突
net = ANN()
opt = optim.SGD(net.parameters(), lr=1e-4)


net.load_state_dict(model_state_dict)
net.to(device)

opt.load_state_dict(optimizer_state_dict)

opt.zero_grad()

pred = net(inputs)

loss = loss_fn(pred, targets)


grads = torch.autograd.grad(loss, net.parameters(), retain_graph=True, create_graph=True) # 计算一阶梯度

loss.backward(retain_graph=True)
opt.step()

·········
······
#之后进行hessian矩阵的计算就可以
参考

参考这个博客举行pytorch 求hessian
【矩阵的导数运算】标量向量方程对向量求导_分母布局_分子布局 此系列三个视频
常用矩阵微分公式_老子今晚不加班的博客-CSDN博客 这里提到的链接,内里也有提到的链接
Matrix calculus - Wikipedia这内里总结的很好

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: pytorch求hessian