Keras中的SGD优化不会垂直于水平曲线移动?

时间:2017-09-04 13:42:48

标签: python keras gradient-descent

我正在使用Keras进行线性回归。我的数据集由50个1D输入点和50个1D输出点组成。为了执行线性回归,我正在训练具有单层和单个神经元的神经网络,没有激活功能。神经网络定义为

model = Sequential()
model.add(Dense(1, input_dim=1, kernel_initializer='zeros', 
bias_initializer='zeros'))

我要求Keras找到w和b的最佳值,使用SGD作为优化器,将均方误差作为损失函数。

model.compile(loss='mean_squared_error', optimizer=SGD(lr=0.01))
model.fit(x,y,epochs=100, callbacks=[history], verbose=0, batch_size=50);

其中history是我创建的回调,用于在优化的每一步保存当前的权重和偏差。

然后我继续绘制损失函数的水平曲线,以及w x b空间中的优化轨迹。输出如下。

gradient descent trajectory

优化轨迹以红色圆圈显示,全局最优值显示为蓝色“x”。这似乎是合理的,因为我们从[0,0]开始,并且在每次迭代之后我们接近全局最优。最终,渐变开始变得如此之小,以至于我们停止改进。

然而,我知道通过使用梯度下降,人们总是会在当前点(即垂直于水平曲线)的渐变方向上移动。这种优化轨迹似乎并不像那样。 Keras SGD优化器是否正在做其他事情?或者我错过了什么?

编辑: 尽管该图似乎说明了水平曲线是平行线,但它们实际上是椭圆体,但非常细长。选择不同的范围来绘制它们会显示出来。

编辑2: 为了避免与我如何绘制此问题中显示的图像有任何混淆,我现在创建了一个gist with the code

4 个答案:

答案 0 :(得分:2)

您必须记住,您使用的SGDStochastic Gradient Descent。在下图中可以看到使用SGD与香草GD进行比较后得到的轨迹差异的可视化: enter image description heresource

您可以看到SGD轨迹与水平线不垂直,但移动方式不同。也许这已经在解释你的轨迹形式了。

答案 1 :(得分:1)

首先,您应该意识到,由于您没有使用激活函数,您的神经网络只能表示线性系统(相当于矩阵乘法)。非线性激活函数带来了神经网络的代表性能力。

您实际上没有执行线性回归。如果要这样做,例如使用2次多项式,则应将平方参数作为输入添加。由于http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html

,Scikit-learn提供了这种转换

假设您具有两个输入x和y的函数,执行线性回归,就像您使用具有x, x^2, xy, y, y^2和一个输出神经元的输入层一样。

编辑: 但是,在(w,b)空间中,您实际上应该能够达到全局最小值。但是,没有关于收敛速度的结果。如果你看一下你的损失函数,你可以注意到它在一个方向上被拉伸很多:它相当于说Hessian矩阵有两个具有非常不同大小的特征值。这意味着你将能够在一个方向(最大的eingenvalues之一)快速学习,但在另一个方向慢慢学习。

在神经网络优化中,计算Hessian矩阵是不可能的,因为它需要在每个步骤进行许多计算。然而,一些学习算法能够逃脱鞍点和严重条件(如你的)优化问题。 SGD表现不佳,几乎不再使用。看看http://ruder.io/optimizing-gradient-descent/,知道所有这些优化器都包含在Keras中。对你来说,我会首先尝试增加动力以提高收敛速度,正如你所说,如果等待足够长时间,它实际上可以收敛。

答案 2 :(得分:1)

打扰一下,如果你已经考虑到这一点,我就看不出你是如何创建图表的。

渐变取决于输入数据。

神经元具有公式w.x + b,其中x是输入。

w和b函数的梯度为:(x,1)。

因此,它取决于输入。

但也不要忘记渐变也会受到损失函数的影响,在你的情况下,这些差异会影响差异。

要查看关卡曲线,您必须应用连锁规则。

Loss = [(wx + b) - y]^2

所以你的渐变是:

W: 2.[(wx + b) - y].x
B: 2.[(wx + b) - y].1

答案 3 :(得分:1)

正交(0.2 vs -5斜率),但图表的x / y单位不相同。在给定方向上缩放不会保持正交性。