2025.7.9 ヘッセ行列
極値判定
多変数スカラ値関数$ fの勾配ベクトルが、ある点$ {\bf x}においてゼロベクトルだったとする。このとき、その点は停留点となり、ヘッセ行列$ Hを用いることでその停留点の性質を調べる事ができる。
$ H({\bf x}) > 0 ... $ f({\bf x})は極小値
$ H({\bf x}) < 0 ...$ f({\bf x})は極大値
$ H({\bf x}) が定値性を持たない ... $ {\bf x}は鞍点
なお、$ H({\bf x})が半正定/半負定行列の場合(つまりゼロ固有値をもつ場合)、それに対応する固有ベクトル方向の曲率は0となる。
曲率
2次形式により点$ {\bf x}における方向$ {\bf v}に沿った曲率を求めることができる。
$ {\bf v}^\top H({\bf x}) {\bf v}
scipyを使った例
関数$ f_1(x) = xの$ x=1におけるヘッセ行列と$ f_2({\bf x})=x_1^2 + x_2^2 + x_1x_2の$ {\bf x}=(1,2)におけるヘッセ行列を求める。
code:p1.py
import numpy as np
from scipy.differentiate import hessian
def func1(x):
return x
def func2(x):
x1, x2 = x
return x1**2 + x2**2 + x1*x2
print('# case 1')
x = np.array(1, dtype=float) # 入力は1-Dで与える
y = hessian(func1, x)
print(y)
print('# case 2')
x = np.array(1, 2, dtype=float)
y = hessian(func2, x)
print(y)
scipy の hessian は scipy._lib._util._RichResult 型を返す。ヘッセ行列は ddf 属性に格納されている。
code:result.py
>> y
success: [ True True
True True]
status: [0 0
0 0]
error: [ 4.263e-14 2.065e-14
3.754e-13 6.839e-14]
nfev: [121 121
121 121]
ddf: [ 2.000e+00 1.000e+00
1.000e+00 2.000e+00]
>> y.ddf
array([2., 1.,
1., 2.])
Pytorchを使った場合
code:p1.py
import torch as pt
from torch.autograd.functional import hessian
def func1(x):
return x
def func2(x):
x1, x2 = x
return x1**2 + x2**2 + x1*x2
print('# case 1')
x = pt.tensor(1, dtype=pt.float)
y = hessian(func1, x)
print(y)
print('# case 2')
x = pt.tensor(1, 2, dtype=pt.float)
y = hessian(func2, x)
print(y)
pythorch の hessian 関数はヘッセ行列をテンソル型で返す。
code:result.txt
# case 1
tensor(0.)
# case 2
tensor([2., 1.,
1., 2.])