【发布时间】:2015-09-12 17:36:19
【问题描述】:
假设我有一个函数
double f(vector <double> &x) {
// do something with x
return answer;
}
在数学上,f 是关于x 的每个分量的连续函数。现在我想评估x 的数值梯度。有以下两种方法
方法一。
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;
}
方法二。
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 内核。
【问题讨论】:
-
我投票结束这个问题,因为它不是一个真正的编程问题,它是一个数值计算问题,最好在另一个站点处理。
标签: numerical-analysis gradient-descent gradient