比较不同数值梯度的精度?

时间:2015-06-25 22:17:21

标签: gradient numerical-analysis gradient-descent gradients

假设我有一个功能

double f(vector <double> &x) {
  // do something with x
  return answer;
}

在数学上,fx的每个组成部分的连续函数。现在我想评估x的数值梯度。有两种方法如下

方法1。

double DELTA = 1e-5;
double y1 = f(x);
vector <double> gradX(x.size());
for (int i = 0; i < x.size(); ++i) {
  x[i] += DELTA;
  double y2 = f(x);
  gradX[i] = (y2 - y1) / DELTA;
  x[i] -= DELTA;
}

方法2。

double DELTA = 1e-5;
vector <double> gradX(x.size());
for (int i = 0; i < x.size(); ++i) {
  x[i] += DELTA;
  double y2 = f(x);
  x[i] -= 2.0 * DELTA;
  double y1 = f(x);
  gradX[i] = (y2 - y1) / (2.0 * DELTA);
  x[i] += DELTA;
}

我观察到方法1 给出非常不合理的数字(6位数字),而方法2 给出更合理的数字。

方法2 是否更好?应该总是首选吗?

感谢。

修改:了解更多内容。这些实现在C中完成,并使用了一些CUDA内核。

1 个答案:

答案 0 :(得分:1)

这是预期的结果,因为方法-1是一阶精确(前向差),而方法-2是二阶精确方法(中心差)。这可以使用Taylor系列轻松证明。有关详细信息,您可以阅读有关有限差分方法的任何书籍。

要获得与一阶方法类似的精度,与二阶方法相比,您必须使用较小的DELTA作为第一阶方法。

从您的实现中可以清楚地看出,方法-2的成本更高,(对每个x评估f1和f2),使用具有较小DELTA的方法-1将是有益的。但是,如果准确性更受关注,那么您可以使用方法-2,使用较小的DELTA。