原则上,autograd 可以处理 python 包装的 C 函数吗?
我想区分的 C 函数期望具有 REAL8 数据类型的参数,我可以通过给它float
或np.float64
参数在 python 中成功调用它。
在使用调试器仔细检查后,我发现当 autograd 将 ArrayBox 对象的float
或np.float64
更改为尝试评估梯度时,我会收到 TypeError。
有没有办法允许自动grad在这种情况下继续?
有没有其他策略可能更适合我的情况?
我可以编写任何基元来解决此问题吗?
背景:
Bilby是一个较新的python库,它包装了用C编写的旧代码(LALSIMULATION)。它提供了广泛的预编码引力波模型,我想在我的研究中使用这些预编码模型。我的第一个任务是弄清楚如何计算这些模型的准确黑森和梯度。由于其臭名昭著的数值精度,我想使用自动微分来解决这个问题,但我被卡住了。
import autograd.numpy as np
from autograd import grad
import BILBY_TAYLORF2 # My own class that wraps Bilby
model = BILBY_TAYLORF2()
gradient_likelihood = grad(model.logLikelihood)
gradient_likelihood(np.array([10., 10.]))
TypeError: in method 'SimInspiralChooseFDWaveform', argument 3 of type 'REAL8'
SimInspiralChooseFDWaveform是第一个调用C代码以供参考。
恐怕这个答案对于原始海报来说可能为时已晚,但如果其他人遇到它,这里有一些信息。
Autograd 依赖于由已定义解析导数的其他函数构造的函数。在autograd的情况下,它知道标准算子的导数,并且它还重新定义了许多numpy函数,以包括它们的解析导数(或向量雅可比积)。它跟踪所有组合在一起的功能/操作,并通过重复使用链式规则执行自动区分。
swig 包裹的 lal模拟函数只返回一个波形。它们没有定义梯度函数(或波形与数据和自身的点积的梯度,就像在 bilby 中计算似然计算那样),因此 autograd 不知道如何处理它们。autograd 教程展示了如何定义primative
函数,定义向量雅可比积并告诉 autograd 将两者与defvjp
函数链接。因此,您必须创建自己的函数来包装似然函数并提供梯度函数。当您将 lalsimuation/似然函数视为黑盒时,您不知道梯度函数的分析形式,因此它只需要使用像有限差分这样的简单方法来获得梯度(也许需要一些迭代)。这种事情的一个例子,即为黑盒函数定义梯度,在这个例子中给出了PyMC3,它可能适用于自动grad。