Hoppa till innehållet
AI-grafen
E· Universitetmatematik· ca 60 min· utvecklande· verifierad 2026-09-20

Jacobianer och Hessianer

Kunna ställa upp Jacobi- och Hessematriser och förstå deras roll i optimering.

Förkunskaper

Intuition

Gradienten generaliserar derivatan till flera variabler in, ett tal ut.

Jacobianen generaliserar den till flera in och flera ut: en matris där rad ii är gradienten av utdata ii.

Jij=∂fi∂xjJ_{ij} = \frac{\partial f_i}{\partial x_j}

För f:Rn→Rmf: \mathbb{R}^n \to \mathbb{R}^m är JJ en m×nm \times n-matris. Är m=1m = 1 är Jacobianen bara gradienten, liggande.

Hessianen är andraderivatorna av en skalär funktion:

Hij=∂2f∂xi∂xjH_{ij} = \frac{\partial^2 f}{\partial x_i \partial x_j}

Gradienten säger åt vilket håll det lutar. Hessianen säger hur ytan kröker sig — är den skålformad, kupolformad eller sadelformad?

MatrisStorlekSäger
Gradientnnriktningen
Jacobianm×nm \times nhur varje utdata ändras med varje indata
Hessiann×nn \times nkrökningen

Formellt

Hessianens egenvärden avgör vad punkten är (i en punkt där gradienten är noll):

Alla egenvärdenPunkten är
positivalokalt minimum (skål)
negativalokalt maximum (kupol)
blandade teckensadelpunkt
några nollobestämt — kräver högre ordning

I högdimensionella problem är sadelpunkter det vanliga. Med nn parametrar krävs att alla nn egenvärden har samma tecken för ett äkta lokalt minimum. Sannolikheten för det faller snabbt med nn, så nästan alla kritiska punkter i ett neuralt nät är sadlar. Det är goda nyheter: gradientnedstigning fastnar sällan permanent i dem, eftersom det alltid finns en riktning nedåt.

Konditionstalet κ=λmax⁡/λmin⁡\kappa = \lambda_{\max}/\lambda_{\min} mäter hur avlång skålen är. Stort κ\kappa betyder en smal ravin — gradientnedstigning zickzackar över kanterna i stället för att gå framåt, och lärhastigheten begränsas av den brantaste riktningen. Det är därför normalisering (BatchNorm, LayerNorm) hjälper: den gör skålen rundare.

Newtons metod använder krökningen för att ta perfekta steg:

xt+1=xt−H−1∇fx_{t+1} = x_t - H^{-1}\nabla f

Den konvergerar kvadratiskt — mycket snabbare än gradientnedstigning. Varför används den inte i djupinlärning?

HinderStorlek vid n=109n = 10^9
Lagra HH101810^{18} tal — omöjligt
Invertera HHO(n3)O(n^3) — omöjligt
HH måste vara positivt definitär den oftast inte

Det som faktiskt används är approximationer som bara behöver matris–vektor-produkter: L-BFGS (lagrar några få vektorer), och i praktiken Adam, som är en grov diagonal approximation av krökningen. Adams v-term skattar gradienternas kvadrat per parameter, vilket i praktiken skalar varje riktning efter sin egen krökning — utan att någonsin bilda en matris.

Hessian–vektor-produkter går att räkna ut utan att bilda HH, med två bakåtpass. Det används i pruning, i påverkansfunktioner och i viss interpretabilitetsforskning.

Kod

import numpy as np, torch

# Jacobian för f(x, y) = (x²y, 5x + sin y)
x = torch.tensor([2.0, 1.0], requires_grad=True)

def f(v):
    return torch.stack([v[0]**2 * v[1], 5 * v[0] + torch.sin(v[1])])

J = torch.autograd.functional.jacobian(f, x)
print(J)
# tensor([[4.0000, 4.0000],      ∂f₁/∂x = 2xy = 4,  ∂f₁/∂y = x² = 4
#         [5.0000, 0.5403]])     ∂f₂/∂x = 5,        ∂f₂/∂y = cos(1)

# Hessian för en skalär funktion
def g(v):
    return v[0]**2 + 3 * v[0] * v[1] + 2 * v[1]**2

H = torch.autograd.functional.hessian(g, torch.tensor([1.0, 1.0]))
print(H)                       # [[2., 3.], [3., 4.]]

ev = np.linalg.eigvalsh(H.numpy())
print(np.round(ev, 3))         # [-0.162  6.162]  ← blandade tecken
print("sadelpunkt" if ev[0] * ev[-1] < 0 else "minimum eller maximum")

# Konditionstal: hur avlång är skålen?
for A in ([[1, 0], [0, 1]], [[1, 0], [0, 100]]):
    e = np.linalg.eigvalsh(A)
    print(f"  egenvärden {e}  konditionstal {e.max() / e.min():.0f}")
#   egenvärden [1. 1.]     konditionstal 1     ← rund skål, lätt att optimera
#   egenvärden [1. 100.]   konditionstal 100   ← smal ravin, zickzack

# Hessian–vektor-produkt utan att bilda H — O(n) i stället för O(n²)
def hvp(f, x, v):
    x = x.detach().requires_grad_(True)
    grad = torch.autograd.grad(f(x), x, create_graph=True)[0]
    return torch.autograd.grad(grad @ v, x)[0]

print(hvp(g, torch.tensor([1.0, 1.0]), torch.tensor([1.0, 0.0])))   # tensor([2., 3.])
#  ← första kolumnen i H, utan att H någonsin existerat

Behärskning innebär

  • Ställer upp en Jacobimatris
  • Tolkar Hessematrisen och dess egenvärden
  • Förklarar varför andra ordningens metoder sällan används i djupinlärning

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser