ヤコビ行列
$ n変数の$ m次元ベクトル値関数$ {\mathrm y} = {\mathrm f} ({\mathrm x})を考える。ただし、$ {\mathbf x} = (x_1, x_2, \ldots , x_n)^\top, {\mathbf y} = (y_1, y_2, \ldots y_m)^\topとする。
このとき、$ i, j成分を$ \partial y_i / \partial x_jとする$ m\times n行列$ Jをヤコビ行列という。
$ J = \left(\begin{array}{ccc} \frac{\partial y_1}{\partial x_1} & \cdots & \frac{\partial y_1}{\partial x_n} \\ \vdots &\ddots & \vdots \\ \frac{\partial y_m}{\partial x_1} &\cdots & \frac{\partial y_m}{\partial x_n} \\ \end{array}\right)
Pytorchを用いた例
code:p.py
import torch as pt
from torch.autograd.functional import jacobian
def func(x):
y = pt.zeros(2, dtype=pt.float) y0 = x0**2 + 2*x0*x1**4 + x2 y1 = x0 + x0*x1**3 + x2**3 print(y)
return y
p1 = pt.tensor(2, 1, -1, dtype=pt.float) ret1 = jacobian(func, p1)
print(ret1)
'''
'''
アイデア:
jacobianやhessianを使うと対象となる関数の本来の戻り値が使えない。そこで、グローバルで返すのはどうだろうか。
code:p.py
import torch as pt
from torch.autograd.functional import jacobian
def func(x):
global loss
y = pt.zeros(2, dtype=pt.float) y0 = x0**2 + 2*x0*x1**4 + x2 y1 = x0 + x0*x1**3 + x2**3 loss = pt.norm(y)
return y
loss = pt.tensor(0, dtype=pt.float)
p1 = pt.tensor(2, 1, -1, dtype=pt.float, requires_grad=True) ret1 = jacobian(func, p1)
print(ret1)
print(loss)
loss.backward()
print(p1.grad)
'''
tensor(7.6158, grad_fn=<LinalgVectorNormBackward0>)
None
'''
うまくいかない。。。。やはり特殊な処理を行っているのだろうか(つまり、jacobiやhessian行列を求めるために自動微分を行っていることから、それらを計算するための計算グラフが生成されている)。以下は上手く動作する(あたりまえだが)
code:p.py
import torch as pt
from torch.autograd.functional import jacobian
def func(x):
global loss
y = pt.zeros(2, dtype=pt.float) y0 = x0**2 + 2*x0*x1**4 + x2 y1 = x0 + x0*x1**3 + x2**3 loss = pt.norm(y)
return y
loss = pt.tensor(0, dtype=pt.float)
p1 = pt.tensor(2, 1, -1, dtype=pt.float, requires_grad=True) #ret1 = jacobian(func, p1) ret1 = func(p1)
print(ret1)
print(loss)
loss.backward()
print(p1.grad)