最近在学习深度学习中的梯度下降与反向传播方面的知识。偶有心得,特此记录。若有不足之处,烦请指正赐教。
在训练阶段,深度神经网络经过前向传播之后,得到的预测值与先前给出真实值之间存在差距。我们可以使用损失函数来体现这种差距。损失函数的作用可以理解为:当前向传播得到的预测值与真实值接近时,取较小值。反之取值增大。并且,损失函数应是以参数(w, b)为自变量的函数。
这里就需要理解,所谓的对于神经网络的训练指的是什么。它是指通过输入大量训练数据,使得神经网络中的各参数调整“学习”到一个合适的值。那么我们在测试时,测试数据就可以直接与这些参数进行运算,准确地得到我们想要的输出。
因此,重点在于,怎样通过大量的训练数据,使得参数自动调整到合适值。
普遍使用的是梯度下降法。它基于这样的一种认识:通过某一群参数的运算后,若得到的预测值与真实值的差距(即损失函数取值)较小,则可以认为这一群参数是“较为令人满意的”。于是明显的,能够使损失函数取其最小值的参数必然是我们想要的参数。
由浅入深,我们最容易想到的实现上述目的的方法是穷举。即取遍参数的所有可能取值,比较在不同取值情况下得到的损失函数的值,即可得到使损失函数取值最小时的参数值。然而这种方法显然是不可取的。因为在深度神经网络中,参数的数量是一个可怕的数字,动辄上万,十几万。并且,其取值有时是十分灵活的,甚至精确到小数点后若干位。若使用穷举法,将会造成一个几乎不可能实现的计算量。
第二个想到的方法就是微分。通过将损失函数进行全微分,取微分为零或较小的点,即可得到理想参数。(补充:损失函数取下凸函数,才能使得此方法可行。现实中选取的各种损失函数大多也正是如此。)可面对神经网络中庞大的参数总量,纯数学方法几乎是不可能直接得到微分零点的。
因此我们使用了梯度下降法。既然无法直接获得该点,那么我们就想要一步一步逼近该点。一个常见的形象理解是,爬山时一步一步朝着坡度最陡的山坡往下,即可到达山谷最底部。(至于为何不能闪现到谷底,原因是参数数量庞大,表达式复杂,无法直接计算)我们都知道,向量场的梯度指向的方向是其函数值上升最快的方向,也即其反方向是下降最快的方向。计算梯度的方式就是求偏导。
这里需要引入一个步长的概念。个人理解是:此梯度对参数当前一轮学习的影响程度。步长越大,此梯度影响越大。若以平面直角坐标系中的函数举例,若初始参数x=10,步长为1 。那么参数需要调整十次才能到达谷底。若步长为5,则只需2次。若为步长为11,则永远无法到达真正的谷底。
梯度这个概念对于理解神经网络中参数具体是怎样更新的有很大帮助。
同样,由简到繁。我们首先想到的使用梯度下降法的具体做法是:损失函数对每一个参数自变量求偏导。然后每个偏导数乘以预先设定的步长,以此为本次学习的参数调整量。原参数减去参数调整量,则参数可以得到修正。修正之后,本轮学习结束。可再进行前向传播。(注:学习不止一轮)
做法大体上确实如此(针对于批量梯度下降法)。我之前在理解梯度下降法时一直有一个错误的认识,即“损失函数是以预测值为自变量的函数”(其实是以参数为自变量)。这个误解使我在面对梯度一词时显得格外迷茫。因为求偏导数必定与自变量有关,而我一直误将参数调整局限于输出层。其实是对网络中所有参数求梯度。
具体的实现方法,使用的是反向传播。
这部分推荐两篇博文:深度学习笔记三:反向传播(backpropagation)算法
这一篇对于理解具体计算过程极有帮助:前向传播算法(Forward propagation)与反向传播算法(Back propagation)
反向传播有核心的四条公式。我在此谈谈自己的一点理解。我认为前两条公式就像是多米诺骨牌一样(求导的链式法则)。第一条公式求出输出层每个神经元的误差(推倒第一枚多米诺骨牌),第二条公式阐述了后面一层网络神经元的误差与前一层神经元的误差的联系(前一枚倒下可推导出下一枚也倒下)。而第三四条公式,只是说明怎样以神经元误差得到两个参数(w, b)的梯度。
注:上述“误差”与“梯度”个人感觉并无太大差别。因为梯度乘以步长就是误差。之所以分别用两个词(误差用于神经元,梯度用于参数),是为了使读者有意识地去区别神经元与参数。
参数是我们需要得到的,需要训练调整的,结合梯度下降法这一名词,在第三第四条公式中我使用了“梯度”去描述它。而隐藏层神经元(输入输出层神经元例外)的取值是一个中间值,它由参数所确定,并不是我们的最终目标产物。同样的,核心公式出现的δ符号指的都是神经元取值上的误差。理解了这一点,看公式时思路就顺畅很多。
理解神经元取值与参数是两个概念后,我们再来看看四条公式。
至于何谓本层,应该是参数与经由其产生的神经元视为一层吧。(不确定)
公式中有些细节,即激活函数。在深度神经网络中,在经过参数运算生成心的一层神经网络后,还要使用激活函数进行运算。而激活函数在反向传播中也是很重要的一部分。留心何谓激活函数,能使你更好地理解反向传播的公式。