我使用functorch.hessian
计算(2,2)线性模型的Hessian,如下所示
model = torch.nn.Linear(2,2).to(device)
inputs = torch.rand(1,2).to(device)
criterion = torch.nn.CrossEntropyLoss()
target=torch.ones(len(inputs), dtype=torch.long).to(device)
func, func_params = functorch.make_functional(model)
def loss(params):
out = func(params, inputs)
return criterion(out, target)
H=functorch.hessian(loss)(func_params)
因为我有2个输入和2个输出,所以我们基本上有4个参数,我希望看到关于这4个参数的二阶导数,但输出看起来不同或无法理解。例如,上面代码的输出如下:
((tensor([[[[ 0.0217, 0.0701],
[-0.0217, -0.0701]],
[[ 0.0701, 0.2266],
[-0.0701, -0.2266]]],
[[[-0.0217, -0.0701],
[ 0.0217, 0.0701]],
[[-0.0701, -0.2266],
[ 0.0701, 0.2266]]]], device='cuda:0', grad_fn=<ViewBackward0>),
tensor([[[ 0.0718, -0.0718],
[ 0.2321, -0.2321]],
[[-0.0718, 0.0718],
[-0.2321, 0.2321]]], device='cuda:0', grad_fn=<ViewBackward0>)),
(tensor([[[ 0.0718, 0.2321],
[-0.0718, -0.2321]],
[[-0.0718, -0.2321],
[ 0.0718, 0.2321]]], device='cuda:0', grad_fn=<ViewBackward0>),
tensor([[ 0.2377, -0.2377],
[-0.2377, 0.2377]], device='cuda:0', grad_fn=<ViewBackward0>)))
有人知道这是怎么回事吗,在这种情况下,我怎么计算黑森矩阵的迹?
1条答案
按热度按时间cngwdvgl1#
模型重量形状:
手电筒。大小([2,2])〈- w1
手电筒。大小([2])〈- w2
雅可比形状:(第一个尺寸是批量大小)
J[0].形状= [1,2,2] *〈-d相对于w1的损耗 *
J[1].形状= [1,2] *〈-d相对于w2的损耗 *
黑森形状:(第一个尺寸是批量大小)
H[0][0]。形状= [1,2,2,2,2] *
H[0][1]。形状= [1,2,2,2,2] *
H[1][0]。形状= [1,2,2,2] *
H[1][1]形状= [1,2,2,2] 〈- dJ[1]相对于w2
注意H[0]的形状与J[0]的第一个值相同,H[1]和J[1]的第一个值也相同,这很有帮助。您根据参数推导了两次,因此再次重复了权重形状。