Supposons que le vecteur \theta
est l'ensemble des paramètres d'un réseau neuronal, je me demande comment calculer la matrice hessienne pour \theta
en pytorch.
Supposons que le réseau soit le suivant :
class Net(Module):
def __init__(self, h, w):
super(Net, self).__init__()
self.c1 = torch.nn.Conv2d(1, 32, 3, 1, 1)
self.f2 = torch.nn.Linear(32 * h * w, 5)
def forward(self, x):
x = self.c1(x)
x = x.view(x.size(0), -1)
x = self.f2(x)
return x
Je sais que la dérivée seconde peut être calculée en appelant torch.autograd.grad()
deux fois, mais les paramètres dans pytorch sont organisés par net.parameters()
et je ne sais pas comment calculer la hessienne pour tous les paramètres.
J'ai essayé d'utiliser torch.autograd.functional.hessian()
dans pytorch 1.5 comme suit :
import torch
import numpy as np
from torch.nn import Module
import torch.nn.functional as F
class Net(Module):
def __init__(self, h, w):
super(Net, self).__init__()
self.c1 = torch.nn.Conv2d(1, 32, 3, 1, 1)
self.f2 = torch.nn.Linear(32 * h * w, 5)
def forward(self, x):
x = self.c1(x)
x = x.view(x.size(0), -1)
x = self.f2(x)
return x
def func_(a, b c, d):
p = [a, b, c, d]
x = torch.randn(size=[8, 1, 12, 12], dtype=torch.float32)
y = torch.randint(0, 5, [8])
x = F.conv2d(x, p[0], p[1], 1, 1)
x = x.view(x.size(0), -1)
x = F.linear(x, p[2], p[3])
loss = F.cross_entropy(x, y)
return loss
if __name__ == '__main__':
net = Net(12, 12)
h = torch.autograd.functional.hessian(func_, tuple([_ for _ in net.parameters()]))
print(type(h), len(h))
h
est un tuple, et les résultats ont une forme étrange. Par exemple, la forme de \frac{\delta Loss^2}{\delta c1.weight^2}
est [32,1,3,3,32,1,3,3]
. Il semble que je puisse les combiner en une H
mais je ne sais pas de quelle partie il s'agit dans l'ensemble de la matrice hessienne et l'ordre correspondant.