我正在寻找关于如何在C中实现Gradient (steepest) Descent的一些建议。我发现f(x)= || Ax-y || ^ 2的最小值,其中A(n, n)和y(n)给出。
这在C中很难(我认为)因为计算梯度,Δf(x)= [df / dx(1),...,df / dx(n)]需要计算导数。
我只想把它扔到SO上,以便为编程提供一些指导,例如:
1)什么维度最好以(1,2,...)
开头2)关于如何进行偏导数的建议
3)我是否应该首先使用更简单的语言(如python)实现 - 然后转换为C
4)等等。
让我知道你的想法!提前致谢
答案 0 :(得分:3)
1)从2D开始,这样你就可以绘制下降的路径并实际看到你的算法有效。
2)df / dx =(f(x + h)-f(xh))/(2 * h)如果f评价便宜,(f(x + h)-f(x))/ h它是昂贵的。 h的选择应该平衡截断误差(主要是大h)和舍入误差(小h)。 h的典型值是~pow(DBL_EPSILON,1/3),但实际指数取决于导数的公式,理想情况下应该有一个取决于f的前因子。对于参数空间中的某些给定采样点,您可以在对数刻度中将数值导数绘制为h的函数。然后,您将清楚地看到最适合您正在采样的点的h范围。
3)无论你发现什么都比较容易。
4)难点在于找到最佳步长。您可能希望在此处使用内部循环来搜索最佳步骤。
答案 1 :(得分:0)
1)我从一个简单的一维示例开始,然后在我确定有效的情况下转到2D。
2)如前所述,您可以提供目标函数,也许您也可以提供分析梯度。如果可能的话,(几乎)总是比使用数值导数更好。
3)无论如何。
4)据推测,最陡的下降只是第一步,接下来可能会看到像CG或BFGS这样的东西。答案 2 :(得分:0)
我发现f(x)= || Ax-y || ^ 2的最小值,给出A(n,n)和y(n)。
此问题称为最小二乘法,您正在进行无约束优化。在C中编写有限差分梯度下降求解器根本不是正确的方法。首先,您可以轻松地分析计算导数,因此没有理由进行有限差分。此外,问题是凸起的,所以它甚至变得更容易。
(设A'表示A的转置)
d/dx ||Ax - y||^2 = 2*A'*(Ax - y)
因为这是一个凸问题,我们知道当导数为0时会发生全局最小值
0 = 2*A'(Ax - y)
A'y = A'Ax
inverse(A'A)*A'y = x
A'A保证可逆,因为它是正定的,所以问题减少到计算这个倒数即O(N ^ 3)。也就是说,有些库可以在C和python中做最小的正方形,所以你应该只使用它们而不是编写自己的代码。