如何确定梯度下降算法中的学习率和方差?

我上周开始学习机器学习。当我想编写一个梯度下降脚本来估计模型参数时,遇到了一个问题:如何选择合适的学习率和方差。我发现,不同的(学习率,方差)组合可能会导致不同的结果,有时甚至无法收敛。此外,如果更换到另一个训练数据集,一个精心选择的(学习率,方差)组合可能就不再有效。例如(如下脚本所示),当我将学习率设置为0.001,方差设置为0.00001时,对于’data1’,我可以得到合适的theta0_guess和theta1_guess。但对于’data2’,它们无法使算法收敛,即使我尝试了数十个(学习率,方差)组合,仍然无法达到收敛。

所以,如果有人能告诉我是否有确定(学习率,方差)组合的标准或方法,我将不胜感激。

import sysdata1 = [(0.000000,95.364693) ,    (1.000000,97.217205) ,    (2.000000,75.195834),    (3.000000,60.105519) ,    (4.000000,49.342380),    (5.000000,37.400286),    (6.000000,51.057128),    (7.000000,25.500619),    (8.000000,5.259608),    (9.000000,0.639151),    (10.000000,-9.409936),    (11.000000, -4.383926),    (12.000000,-22.858197),    (13.000000,-37.758333),    (14.000000,-45.606221)]data2 = [(2104.,400.),     (1600.,330.),     (2400.,369.),     (1416.,232.),     (3000.,540.)]def create_hypothesis(theta1, theta0):    return lambda x: theta1*x + theta0def linear_regression(data, learning_rate=0.001, variance=0.00001):    theta0_guess = 1.    theta1_guess = 1.    theta0_last = 100.    theta1_last = 100.    m = len(data)    while (abs(theta1_guess-theta1_last) > variance or abs(theta0_guess - theta0_last) > variance):        theta1_last = theta1_guess        theta0_last = theta0_guess        hypothesis = create_hypothesis(theta1_guess, theta0_guess)        theta0_guess = theta0_guess - learning_rate * (1./m) * sum([hypothesis(point[0]) - point[1] for point in data])        theta1_guess = theta1_guess - learning_rate * (1./m) * sum([ (hypothesis(point[0]) - point[1]) * point[0] for point in data])       return ( theta0_guess,theta1_guess )points = [(float(x),float(y)) for (x,y) in data1]res = linear_regression(points)print res

回答:

绘图是查看算法性能的最佳方式。要检查是否达到了收敛,可以绘制每次迭代后的成本函数的变化情况,经过一定次数的迭代后,你会发现成本函数的改进不大,这时可以认为已经收敛,请看以下代码:

cost_f = []while (abs(theta1_guess-theta1_last) > variance or abs(theta0_guess - theta0_last) > variance):    theta1_last = theta1_guess    theta0_last = theta0_guess    hypothesis = create_hypothesis(theta1_guess, theta0_guess)    cost_f.append((1./(2*m))*sum([ pow(hypothesis(point[0]) - point[1], 2) for point in data]))    theta0_guess = theta0_guess - learning_rate * (1./m) * sum([hypothesis(point[0]) - point[1] for point in data])    theta1_guess = theta1_guess - learning_rate * (1./m) * sum([ (hypothesis(point[0]) - point[1]) * point[0] for point in data])   import pylabpylab.plot(range(len(cost_f)), cost_f)pylab.show()

这将绘制以下图形(执行时学习率=0.01,方差=0.00001)

如你所见,经过一千次迭代后,改进并不大。我通常在成本函数在一轮迭代中减少不到0.001时宣告收敛,但这只是基于我自己的经验。

在选择学习率时,最好的方法也是绘制成本函数并观察其表现,并且始终记住以下两点:

  • 如果学习率太小,收敛速度会很慢
  • 如果学习率太大,成本函数可能在每次迭代中都不会减少,因此不会收敛

如果你运行代码时选择学习率 > 0.029 且方差=0.001,你将处于第二种情况,梯度下降无法收敛;而如果你选择学习率 < 0.0001,方差=0.001,你会发现你的算法需要很多次迭代才能收敛。

学习率=0.03时不收敛的例子

学习率=0.0001时收敛缓慢的例子enter image description here

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注