我正在学习机器学习,目前正在学习线性回归的梯度下降。我刚了解到,如果学习率足够小,成本函数返回的值应该会持续下降直到收敛。当我想象这是在代码循环中完成的,似乎我可以跟踪前一次迭代的成本,如果新的成本大于之前的成本,就退出循环,因为这表明学习率过大。由于我是新手,我很想听听大家的意见,但为了避免这个问题主要基于意见,我的主要问题是:这种检测需要降低的学习率的方法有什么问题吗?如果可能的话,我希望能看到这种方法失败的一个例子。
回答:
在下面的例子中,我们将改变学习率 eta = 10^k
,其中 k={-6,-5,-4,...0}
def f(x): return 100 * (x[ 0] *x[0] - x[ 1]) **2 + (x[ 0] -1) **2def df(x): a = x[ 0] *x[0] - x[ 1] ret = np.zeros(2) ret[ 0] = 400 * a * x[0] + 2 * (x[0] - 1) ret[ 1] = -200 * a return retfor k in range(-6, 0): eta = math.pow(10.0, k) print("eta: " + str(eta)) x = -np.ones(2) for iter in range(1000000): fx = f(x) if fx < 1e-10: print(" solved after " + str(iter) + " iterations; f(x) = " + str(f(x))) break if fx > 1e10: print(" divergence detected after " + str(iter) + " iterations; f(x) = " + str(f(x))) break g = df(x) x -= eta * g if iter == 999999: print(" not solved; f(x) = " + str(f(x)))
对于过小的学习率,优化过程非常缓慢,问题在迭代预算内无法解决。对于过大的学习率,优化过程变得不稳定并很快发散。学习率必须“恰到好处”,优化过程才能正常工作。