PS:翻译来源:
http://shop.oreilly.com/product/9781939902351.do
欠了5天的翻译,今天来还债来了 , 这是第一篇
////////第一篇///////////
梯度下降和反向传播
关于基本的机器学习章节,我们一直没有解释我们在使用的学习算法的工作原理。
梯度下降是一个能够找到函数最小值的算法。注意,我们将学习定义为通过一定量的训练步骤,对模型参数的改进(improving),使得模型的loss值最小化。在这个概念里,使用梯度下降可以找到loss function(损失函数)的最小值。
如果你不知道梯度下降的话,来了解一下什么是梯度下降。梯度下降是一个数学操作,通常会使用这个符号来表示:
它类似于一个导数,但适用于输入向量和输出一个值的函数,就像我们的损失函数一样。梯度的输出是一个偏导数的向量,输出的向量的每个位置的值是每一个函数的输入向量的位置的。(PS:这里大致上是说输出的元素就是对输出的每个元素做偏导)
你可以把偏导数理解为就好像只接收一个变量的函数,用常量替换所有其他变量,然后用单变量求导过程去求解。偏导数是可以测量函数的输出相对于某一特定输入变量的变化率。换句话说,就是如果当输入的变量值增加多少输出的变量值会增加多少。
在继续讲解之前,需要提醒: 我们讨论 损失函数的输出变量是指的模型的权重而不是数据集中的特征输入。输入特征智能通过数据集合去修改,而不能被优化(Those are fixed by our dataset and cannot be optimized.)我们计算的偏导数是关于推理模型中每个单独权重的。
我们关心梯度,因为它的输出向量表示损失函数的最大增长方向。你可以把它当成一个小箭头,这个箭头将在你应该移动的每一个点上指出,以增加它的价值。
假设上图中表示的loss function(损失函数)。红点代表你所在的当前权重值。梯度使用箭头表示,表示(indicating)您应该向右侧去增加损失。而且,箭头的长度代表着如果要移动的话,大概移动多少距离。
现在,如果你按照梯度相反的方向去移动,loss值也会和之前做的相反:会下降。
在这张图中,如果我们去相反的梯度方向(蓝色箭头指向的方向),我们会走向loss减小的方向中。
如果我们每次朝着这个方向(PS蓝色箭头指向的方向),且再次计算梯度,然后重复着这个过程直到梯度的长度成为0,我们会达到损失函数的最小值。这是我们的目标,应该如下图所示:
仅此而已(that is it)我们可以简单的定义梯度下降的算法:
注意,我们应该添加n是为了放大or缩小梯度。我们把n称作学习率。由于实际上梯度向量的长度是可以衡量每个单元的损失函数(loss functgion units),却不能衡量权重单元(weight units),所以我们有必要在公式中去添加这个变量。
学习率不是模型推断出的值。它是一个超参数(hyperparameter),也可以是手动配置到模型设置中。我们需要找出正确的学习率的值。如果它的值太小了,那么需要很多学习周期才能找到损失最小值。如果它太大了,算法可能会简单的跳过最小值或者是无法找到最小值,不断的在跳过最小值。这被称为超调(overshooting)。在我们的例子损失函数图中,它将如下所示:
实际上,因为损失函数有太多的变量了所以我们无法真正的画出来损失函数。所以要知道我们被困在超调中,我们必须看一下计算出的总损耗的时间,我们可以通过使用tf.scalar_summary对损失在Tensorboard中获得。
PS: This is how a well behaving loss should diminish through time, indicating a good
learning rate这句话可以用在写作上。
蓝色的线是Tensorbord图, 红色的线代表着loss的趋势(the tendency line of the loss.)
当学习率overshooting(超调)的时候,就会成为一下的样子:
如果是出现上图的样子, 那么你应该调整学习率,让学习足够小直到不会出现超调现象(overshoot),但又要足够大以使其快速衰减,这样可以使用更少的周期来实现更快的学习。
除了学习率,也有其他的问题会在算法上影响到梯度下降。损失函数会存在局部最优解(The presence of local optima is in the loss function)。
回到小示例损失函数图中,如果我们的初始权重靠近损失函数的右侧“谷”,那么算法将如何工作?
算法会找到谷底之后停下来,因为它会认为这个地方是最优值所在的地方。所有最小值的梯度值都为0。这个算法是没法区分自己是否停留在了函数的最小值上、全局最小值,或局部最小值、在最佳值附近的地方。
在随机初始化权重的时候,我们尽量的会避免这些问题。记住,权重的初始值是人为设置的。通过使用随机的值,我们可以提高从全局最低点开始下降的机会。
我们将在后面的章节中看到,在深层网络环境中本地最小化现象是非常频繁的。解释这一点的一个简单的方法是考虑相同的输入如何可以将许多不同的路径传输到输出,从而产生相同的结果。幸运的是,有文献显示,所有这些最低标准在损失方面都是非常相似的,并没有真正比全局最低。
到目前为止,我们还没有明确地计算任何导数(derivatives),因为我们没有必要这样做。Tensorflow包括的方法tf.gradients可以象征性地计算指定图形步长的梯度,并将其作为张量输出。甚至不需要手动调用,因为tensorflow也实现了梯度下降等其他的算法。这就是为什么我们会给出高级公式却不要求大家去深入的了解实现细节和数学公式。
我们准备给出反向传播的过程。这是在计算图中有效的计算梯度的方法。
假设(assume)有一个这样简单的网络:有一个输入和一个输出,两个拥有单个神经元的隐含层。这两个隐含层以及输出神经元都会使用sigmoids并会将会用交叉熵的方式去计算loss。 网络的样子如下:
将L1定义为第一个隐含层的输出,L2是第二个隐含层的输出,L3是最后的输出层:
最后,网络的loss将会是:
为了运行梯度下降,我们需要计算loss的偏导数以及网络中3个权重的表达式。我们从输出曾的权重开始,使用链式规则计算:
L2在本案例中只是一个常数。因为太不依赖W3。
为了简化表达式,我们可以这样的定义:
偏导函数的结果表达式应该是:
现在,来计算第二个隐含层的权重W2 :
最后对w1求导数:
你应该注意到这个模式:每个层上的导数是之前的层的输出之后的层的导数的乘积。这就是链式法则的神奇之处,也是这个算法的优势所在。(That’s the magic of the chain rule and what the algorithm takes
advantage of)。
我们会向前从输入开始计算每个隐含层的输出以及到输出的输入。然后我们又返回开始计算隐含层的导出,并将结果传播出到下一层,这是为了通过再利用都已经计算出的元素少做计算传播的结果。(这里有动态归化的思想在里面)这就是为什么脚反向传播。:)
///////////////////Conclusion//////////////
注意我们如何没有使用S形或交叉熵衍生物的定义。我们可以在一个网络中使用不同的激励函数或者是损失函数,其结果可能会是一样的。
举个简单的例子,对拥有成千上百权重的网络计算损失率的话,使用该算法可以节省训练时间的数量级。进一步说(to close),在Tensorflow中有一些不同的优化算法,尽管它们都基于这种计算梯度的方法。哪个算法的效果更好,这取决于你你输入数据的形状和你要解决的问题。
Sigmoid隐含层、softmax输出层以及基于梯度下降的反向传播都是构建更加复杂模型的最常见的基本模块。我们会在下一个chapter中讲到。
下一期:
Part III.Implementing Advanced Deep
Models in TensorFlow