人工智能系列(七)深度学习中的梯度下降与反向传播

原力君在系列的第六篇《人工智能系列(六) 深度学习中的神经网络》中提到人工神经网络的基础是人工神经元,常用的神经元激活函数为sigmoid,应对深度学习的激活函数为ReLU、maxout等函数;多层感知机与DNN结构一致,激活函数有区别;CNN可以用来解决DNN网络参数太多的问题;RNN为带有反馈的神经网络。但是,仍然存在一个问题:有了神经网络和样本数据,我们如何训练模型得到神经网络的最优参数呢?这个问题涉及到参数优化求解,深度学习通常用反向传播梯度下降法来优化参数。本篇聊聊梯度下降和反向传播的具体内容。

梯度

神经网络的梯度是指网络参数变化时,网络的代价函数随参数变化而变化的程度,用高中学过的数学语言来说,梯度就是网络代价函数对网络参数的导数。我们假设神经网络有n个输入x=[x1,x2,…,xn],样本数据中每个x的值都对应着一个精确已知的网络输出y(x)(实际中,y(x)需要人手动获得。举个例子,你用草书写了一个“李”字,要让机器识别你写的是李,那么你要告诉网络那个草书的“李”为输入x的时候,对应的输出y(x)为“李”)。

假设目前网络的参数还不是最优的,那么对于给定的输入x,它会输出一个a(x),这个a(x)可能不等于y(x),因此我们定义了一个代价函数来表征网络输出与期望输出之间的差异:

这个代价函数对应的梯度为(这里梯度符号用倒三角表示,偏导数的内容此处不表,高中和大学均有涉及,理工科的同志应该知道)

梯度下降

梯度下降,是优化网络参数的一种方法;顾名思义,如果梯度一直下降,也就是说网络代价函数对网络参数的导数一直下降,那么最终网络的代价函数会达到一个最小值(由于网络函数的复杂性,这里可能得到的是局部最小。局部最小问题也是目前深度学习存在的一个问题,此处不表)。那么对应着最小代价函数的那组网络参数,就是我们所需要的最优网络参数。梯度下降方法的公式推导如下(如果比较反感公式,请跳过这一部分,对于梯度下降主要记住思路即可,在实际工程中,程序大牛们已经给你编好了轮子,可以直接拿来使用)

有同志可能会问了:为什么要这样?为什么参数变化等于它偏导数的负倍数就一定可以?其实,这里“为什么”解释起来比较尴尬:有些东西,可以通过公式推导得到;有些东西是瞎试出来的。像这里的处理方式,就是老祖宗们瞎试出来的,发现这么赋值能保证代价函数的变化量一直小于零,也就是说代价函数一直在减小,所以就能保证找到一个最小值(或局部最小值)。于是,后人就记住了这么一条规则:这么处理可以让函数值变小。其实,数学中有很多结论也是老祖宗们瞎试出来的,不要觉得太神秘。

反向传播

我们知道神经网络非常复杂,想要计算其代价函数对参数的导数是非常困难的,而反向传播方法给了我们一个可以近似求解神经网络梯度的方法。关于反向传播,其理论推导不能用一两句话解释清楚,这里原力君推荐大家学习在线学习课程《Neural Networks and Deep Learning》。这是一本在线教程,作者用非常简单的语言和思路为大家解释了神经网络、梯度下降、反向传播的原理,并且给出了一个数字识别的例子。为了让我们的文章显得完整,原力君在这里贴出反向传播方法的算法截图

不要慌,很多事情不需要你自己编写

大家看到前面关于梯度、梯度下降、反向传播的原理,再想想神经网络复杂的结构以及多到令人发指的参数,是不是脑袋很大?如果所有这些都需要大家自己编写的话,真的是费时费力,而且很容易出错。

不过,我们令人尊敬的程序员大牛们以及IT大公司们为我们提供了很多的开源工具和开发包。常见的用来进行深度学习的工具有keras, tensorflow, theano, lasagna, caffe, dsstne, torch等等。作为一个初学者,原力君用的就是keras,因为它太简单了。举个例子:假设我们有训练样本数据x_train,以及它对应的真实输出y_train,那么使用神经网络进行模型学习主要由三个步骤:1,确定神经网络结构;2,确定代价函数,配置优化方法;3,优化参数得到最优模型。

第一步,确定神经网络结构。下面的代码就定义了一个三层网络:输入层的输入是28*28的图像数据,输出是500维的数据,激活函数选择了sigmoid;中间隐藏层的输入就是前面输入层的500维输出,所以不用再定义,而隐藏层的输出是500维的数据,激活函数也是sigmoid;输出层的输出维数是10维,激活函数选择了softmax(也是一种激活函数,不过它将输出变成了一种概率分布,主要用来对输入数据进行分类。输入数据对应着概率最大的那个输出维度,也就是说输入数据属于这一维度对应的那个分类。)

第二步和第三步在代码中耦合在一起,mse代表的就是我们前面定义的代价函数,model.fit执行完后得到的变量model中就包含了我们所需要的最优网络模型。

一句话总结:梯度是神经网络代价函数对网络参数的导数;梯度下降,代价函数变小,则最终可以找到最小代价函数机器对应的网络参数;反向传播为我们提供了一种计算梯度的方法;开源工具如keras已经为我们提供了丰富的代码库以及接口。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181019A1VTI600?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券