在GPU上解决无约束的非线性优化问题


18

我正在尝试解决GPU(CUDA)上的一些不受约束的非线性优化问题。

目标函数是一个平滑的非线性函数,其梯度在分析上相对便宜,因此我无需理会数值逼近。

我想通过大多数fp32数学运算来解决此问题(由于各种原因),那么哪种非线性优化方法对舍入误差更鲁棒,同时又具有良好的性能?(例如共轭梯度/准牛顿/信任区域),有人在GPU上尝试过BFGS并获得良好结果吗?

顺便说一句,如果需要的话,Hessian相对较小(通常小于64x64),但是我需要同时解决数千个此类小规模优化问题。


4
考虑到您的问题很小,我认为算法的特定选择(例如BFGS)不会成为您最大的挑战。相反,它将使GPU <-> CPU通信开销最小化。可能最好的方法是在GPU上并行解决许多问题实例。一次全部加载它们,一次解决所有问题,一次下载所有结果。我没有关于该算法的具体建议,但是我会说GPU比循环更好。
迈克尔·格兰特

1
@Michael C. Grant:嗯,在我的情况下,通信开销可以很容易地通过计算隐藏,因此它不是瓶颈,我非常愿意在这里使用内存有限的BFGS或标准BFGS,但不确定是否有更好的方法。
user0002128 2013年

有些人用CUDA实现了LBFGS
BenC

Answers:


8

我已经在GPU上实现了多种非线性求解器,包括LBFGS,Barzilai Borwein梯度下降和非线性共轭梯度。

为此,Dai&Yuan的非线性共轭梯度是最有效的。通常,非线性共轭梯度的其他版本可能更有效(例如CG-DESCENT),但实现起来也比较棘手。

通常,LBBFG是一个非常可靠的选择,除非您真的有足够的存储空间,否则它可能是最好的起点。

共轭梯度和BFGS都需要线搜索,这是fp32成为问题的地方。我建议不要使用标准的Wolfe条件进行行搜索,而建议使用此处建议的近似Wolfe条件。本文涉及的内容很少,但重要的是公式4.1。从本质上讲,它们明确介绍了可以用来计算函数的精度。

GPU注意事项:

您有很多小问题,与我的一个大问题的用例略有不同。如果您可以并行化函数和梯度求值以使用一个块中的所有线程,请考虑在每个GPU块(或者说是扭曲)上运行1个问题。这样,如果不同的问题需要不同数量的迭代,这不是问题。

如果这不是一个选择,我将使用LBFGS求解器。如果您的函数运行良好,则可以简单地使用步长为1(避免行搜索),并以固定的迭代次数运行所有问题。


0

我建议您使用Levenberg Marquardt(信任区域变体),因为它已在许多实际应用中使用,并表现出非常好的速度与精度性能。此外,对于GPU,有一些库(例如cuLM https://github.com/zitmen/cuLM),您可以尝试一下。如果他们做不到这一点,则有大量资源可供您实施。实施LM一点也不难。您只应注意尽量减少GPU通信。简要说明一下:

http://on-demand.gputechconf.com/gtc/2012/presentations/S0231-Levenberg-Marquardt-Using-Block-Sparse-Matrices-on-CUDA.pdf


2
Levenberg-Marquart用于非线性最小二乘法。我认为他(她)没有提到最小二乘法。
Kurt

0

也许模拟的退火程序可以更好地处理舍入误差(并且很容易并行化)。

您从搜索区域的原始网格和初始“温度”参数开始

在每一步中,您都可以计算出可能的求解点(也可以接受非求解点,其几率与温度成反比)

然后仅保留该步骤的解决方案并提高温度,从而为下一次迭代提供更细粒度的网格

这样做直到温度<给定的精度极限/阈值

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.