我们正在研究一个时空过程的贝叶斯模型,并且正在使用一个No-U-Turn采样器(NUTS),该采样器需要一个对数概率模型以及相对于模型参数的梯度。更简洁地说,我们有相当复杂的对数概率函数,涉及统计分布,克罗内克乘积,指数,比率,if-else语句等,需要提供它以及它对NUTS的梯度。几个软件包(Stan和 Julia的MCMC)使用运算符重载(据我所知)自动获取渐变。
如果我们能够使用源代码转换自动差异工具来创建自己的梯度函数,那么我们是否会获得更好的性能,或者OO一样好还是更好?
我们正在研究一个时空过程的贝叶斯模型,并且正在使用一个No-U-Turn采样器(NUTS),该采样器需要一个对数概率模型以及相对于模型参数的梯度。更简洁地说,我们有相当复杂的对数概率函数,涉及统计分布,克罗内克乘积,指数,比率,if-else语句等,需要提供它以及它对NUTS的梯度。几个软件包(Stan和 Julia的MCMC)使用运算符重载(据我所知)自动获取渐变。
如果我们能够使用源代码转换自动差异工具来创建自己的梯度函数,那么我们是否会获得更好的性能,或者OO一样好还是更好?
Answers:
就性能而言,从源到源的转换被视为黄金标准。OO方法似乎几乎一样好,因为那里有更多的OO软件包,并且没有提到性能是一个重大缺点。如果找到适合您所使用语言的OO库,我将首先使用它,然后再确定是否绝对需要从源到源的转换,以及是否存在满足您需求的工具。自动计算生成的导数的典型成本大约是函数求值的三到五倍,这可以根据实际情况而定。
那里有更多的OO软件包,因为使用操作员重载比使用源到源转换要容易实现自动区分工具。实现源到源的翻译程序等于编写编译器:必须对源代码进行解析和标记化,然后将转换规则应用于结果表达式树。Andreas Griewank的书《评估导数:算法微分的原理和技术》(第二版)对折衷问题进行了更详细的介绍。
对于梯度计算,请使用AD的反向模式。在两种情况下都需要构建操作数堆栈,OO版本也需要构建操作堆栈,必须在代码的反向遍历中对其进行解释。源转换后的代码将反序操作写为已编译的其他源代码。在代码中包含操作解释器的开销可能很大。有一些Tapenade生成的代码与Adol-C的比较,这些比较有利于Tapenade。