从https://github.com/HIPS/autograd/issues/439我收集到有一个未记录的函数autograd.make_jvp
,它以快进模式计算雅可比。
该链接指出:
给定一个函数 f,向量 x 和 v 在 f 的域中,make_jvp(f)(x)(v)
计算 f(x) 和在 x 处求值的 f 的雅可比行列式,右乘向量 v。
要获得 f 的完整雅可比行列式,您只需要编写一个循环来评估make_jvp(f)(x)(v)
f 域的标准基础中的每个 v。我们的反向模式雅可比算子以相同的方式工作。
从你的例子:
import autograd.numpy as np
from autograd import make_jvp
def f(params):
mu_, log_sigma_ = params
Z = timeline * mu_ / log_sigma_
return Z
timeline = np.linspace(1, 100, 40000)
gradient_at_mle = make_jvp(f)(np.array([1.0, 1.0]))
# loop through each basis
# [1, 0] evaluates (f(0), first column of jacobian)
# [0, 1] evaluates (f(0), second column of jacobian)
for basis in (np.array([1, 0]), np.array([0, 1])):
val_of_f, col_of_jacobian = gradient_at_mle(basis)
print(col_of_jacobian)
输出:
[ 1. 1.00247506 1.00495012 ... 99.99504988 99.99752494
100. ]
[ -1. -1.00247506 -1.00495012 ... -99.99504988 -99.99752494
-100. ]
这在 google collab 上运行约 0.005 秒。
编辑:
像这样的函数cdf
还没有为常规定义,jvp
但是您可以make_jvp_reversemode
在定义它的地方使用另一个未记录的函数。用法类似,只是输出只是列而不是函数的值:
import autograd.numpy as np
from autograd.scipy.stats.norm import cdf
from autograd.differential_operators import make_jvp_reversemode
def f(params):
mu_, log_sigma_ = params
Z = timeline * cdf(mu_ / log_sigma_)
return Z
timeline = np.linspace(1, 100, 40000)
gradient_at_mle = make_jvp_reversemode(f)(np.array([1.0, 1.0]))
# loop through each basis
# [1, 0] evaluates first column of jacobian
# [0, 1] evaluates second column of jacobian
for basis in (np.array([1, 0]), np.array([0, 1])):
col_of_jacobian = gradient_at_mle(basis)
print(col_of_jacobian)
输出:
[0.05399097 0.0541246 0.05425823 ... 5.39882939 5.39896302 5.39909665]
[-0.05399097 -0.0541246 -0.05425823 ... -5.39882939 -5.39896302 -5.39909665]
请注意,由于它使用缓存,这make_jvp_reversemode
将比常数因子稍快。make_jvp