李宏毅机器学习课程总结(3)

深度学习(Deep Learning)

深度学习神经网络的结构

       把多个逻辑回归单元头尾连接起来就组成了神经网络,每个逻辑回归单元被称为神经网络中的一个神经元。那么这些神经元要如何连接起来成为一个网络呢?最简单直接的就是全连接前馈(Fully Connected Feedforward)网络,层与层之间的神经元两两连接,数据传递的方向是从前(输入端)到后(输出端)。每个神经元单独拥有一个w和b,输入和输出都是一个向量。

       神经网络中将输入数据定义为输入层,表示为整个网络的输入;输出定义为输出层,表示为整个网络的输出。将神经网络中介于输入层和输出层之间的层统一称为隐藏层(Hidden Layer)。隐藏层的层数和每层中神经元的越多时,越不能使用全连接的方式,否则会造成运算量爆炸增长,深度网络需要精心设计。

       神经网络可以理解为通过一层层的隐藏层提取出输入数据中的某些特征,最后将特征展示在输出层,实现多分类的分类器,通常在最后加上一步softmax,输出识别为每个类别的概率。

评价网络的好坏和训练

       如何找到能实现预期效果的网络结构是很关键的,如网络需要有多少层?每层需要有多少个神经元?所以需要找到一个损失函数来评价一个网络结构或者权重的好坏,由于神经网络是一个多分类器,可以计算神经网络的输出结果与真实结果的交叉熵作为损失值,每一组输入数据的损失之和就是整个网络的损失值,即

                                                                                    \large LOSS = \sum _{n=1}^{N}C^n

而网络中的w的更新使用到的依然是梯度下降法,对于每个w的梯度使用的是反向传播(Backpropagation)的技术,需要求的是

                                                                                     \large \frac{\partial C}{\partial w} = \frac{\partial z}{\partial w}\frac{\partial C}{\partial z}

其中z是这个w所在的神经元的激活函数的输入,即\large \sum _{i=1}^{n}w_ix_i + b,所以\large \frac{\partial z}{\partial w}是很容易计算出来的,就是每个w对应的输入x,计算\large \frac{\partial z}{\partial w}的过程称为前推(Backpropagation)。

        现在的问题是如何计算\large \frac{\partial C}{\partial z},而\large \frac{\partial C}{\partial z}可以看做是

                                                                                      \large \frac{\partial C}{\partial z} = \frac{\partial a}{\partial z}\frac{\partial C}{\partial a}

其中a是对应神经元中激活函数的输出,而\large \frac{\partial a}{\partial z}可以通过对激活函数的求导得出,所以目前的重点是计算\large \frac{\partial C}{\partial a},由链式法则可以得出

                                                                            \large \frac{\partial C}{\partial a} = \frac{\partial z_1}{\partial a}\frac{\partial C}{\partial z_1}+\frac{\partial z_2}{\partial a}\frac{\partial C}{\partial z_2}

这是假设了a作为了下一层中两个神经元的输入,对应的激活函数的输入为\large z_1\large z_2,权重为\large w_1\large w_2。而\large \frac{\partial z_1}{\partial a}\large \frac{\partial z_2}{\partial a}即为权重为\large w_1\large w_2,而\large \frac{\partial C}{\partial z_1}\large \frac{\partial C}{\partial z_2}又需要重复一次上述步骤来进行计算,直到输出层y为止。

       如果依然按照从前往后运算的顺序的话,会造成很大的计算量,而如果是从后往前运算,在输出层的前一层的w可以直接计算出梯度的基础上

                                                                       \large \frac{\partial C}{\partial z_1} = \frac{\partial y_1}{\partial z_1}\frac{\partial C}{\partial y_1}\large \frac{\partial C}{\partial z_2} = \frac{\partial y_2}{\partial z_2}\frac{\partial C}{\partial y_2}

不断将后一层计算出来的梯度,传给前一层进行梯度运算,将会得到较高的运算效率,这种方法称为逆推(Backward pass)。

       这样我们就能得到每一个w的梯度,具体的训练步骤就是:①随机初始化参数\large \theta _0;②使用参数计算出预测结果y;③计算出整个网络的损失值;④使用前推和逆推计算出每个w参数的梯度g;⑤使用梯度下降进行参数更新\large \theta _1 = \theta _0 - \eta *g;⑥回到步骤②,直到训练结束。

深度学习训练分析及优化

       深度学习的流程可以概括为:①设计好网络的模型,即定义了一个f的集合;②评价每个f的好坏;③在集合中找到一个最好的f。

      首先要看我们的网络能不能在训练集上有好的表现,有些时候如果网络设计的不好,或者训练中出现了某些问题(如卡在局部最优、卡在鞍点等),会导致网络在训练集上就表现较差。在训练集上表现好后,将网络放到测试集上测试,在测试集表现不好有可能是过拟合。需要注意的是,并不是所有的在训练集上表现好在测试集上表现不好都是因为过拟合,也有可能是没有训练好。

       深度网络中存在着网络梯度消失问题,具体现象是在反向传播中靠近输入端的层中的参数,得到的梯度非常小,但是靠近输出端的层的参数得到的梯度较大,导致前后层的训练速度差距较大,当后面的层训练好时,前面的层可能才走了一小步。产生梯度消失现象的原因主要是激活函数\large \sigma(z)的问题,\large \sigma(z)函数会将输入的无论绝对值多大的z,都输出成0到1中的某个值,在深度网络中,经过多个\large \sigma(z)函数的持续压缩,靠前的层对输出y的影响非常小,所以得到的梯度就非常小。为了解决这个问题,我们可以将激活函数设置为ReLU函数

                                                        \large ReLU(z) = z, z>=0 ; ReLU(z) = 0, z<0

ReLU函数具有的优势在:①计算速度快;②被证明有在生物学上的利用;③可以看做是无穷多个\large \sigma(z)函数的叠加。同时也能解决梯度消失的问题。同时,ReLU函数也有多种形式,是Maxout方法的一种特殊形式。Maxout将同一层中的若干的神经元的输出分在一组,输出每一组中最大的那个z,作为激活函数的输出a。由于不同的输入数据,会导致每次训练每组中产生最大z的神经元不同,所以每个神经元都能得到应有的训练,所以Maxout是可行的。

       对于学习率的更新问题,由于深度神经网络中函数复杂,损失函数在一个方向上变大或变小的并不一定均匀,即随训练次数的增加,有的时候可能需要较大的学习率,RMSProp是AdaGrad的进阶版,在RMSProp中,赋予了当前梯度更大的权重,即学习率的更新为

                                                                \large \sigma _0 = g_0,\sigma _{t} = \sqrt{\alpha (\sigma_{t-1})^2 + (1-\alpha ) (g_t)^2}

同时,为了解决训练时可能卡在鞍点或局部最优点的问题,参考了实际生活中物体运动的规律,给参数的更新加上一个惯性(Momentum),参数的移动方向不只是依赖于梯度,还会依赖于前一次移动的方向。即实际移动方向和步长v为

                                                                          \large v_0 = 0, v_{t+1} =\lambda v_t -\eta g_t

使用了Momentum后,参数的训练就有可能可以避免卡在鞍点或者局部最优,但是也有可能跳不出较深的局部最优点。Adam方法就是同时使用了RMSProp和Momentum。

       Early Stopping是为了避免在训练集上过度训练,以至于让分类器在测试集上的LOSS不降反增,超过了在测试集上LOSS的最低点。在实际应用中,通常是使用验证集来代替测试集,在验证集上LOSS最小时停止训练,而不是直到训练集上LOSS最小时才停止。为了实现 Early Stopping,我们通常使用正则化技术,正则化是让f更加平滑,让网络中的参数绝对值更小,即抑制参数与0的距离增加,起到抑制训练效果的作用。正则化通常分为L1和L2正则化。L1正则化项为

                                                                                 \large \lambda \frac{1}{2}\left \| \theta \right \|_1,\left \| \theta \right \|_1 = \left | w_1 \right | + \left | w_2 \right | + ...

L2正则化项为

                                                                                   \large \lambda \frac{1}{2}\left \| \theta \right \|_2,\left \| \theta \right \|_2 = w_1^2+ w_2^2 + ...

经过数学推导可以发现,L1是让参数每次更新时,减少或者增加一个固定的值,使参数靠近0,而L2是让参数每次更新时,都先乘上一个0到1之间的小数,使参数靠近0。两种正则化项各有优点,需要结合具体网络来选择,w值很大时,L1比L2参数变小得更慢,w值很小时,L1比L2参数变小得更快。

       Dropout是用来解决网络在训练集上表现较好而在测试集上表现较差的问题,方法是在每一次训练时,对网络中的每个神经元有p的概率会被丢掉,相当于从网络中“删除掉”,参数更新时也不对这些被丢掉的神经元中的参数进行更新。在测试集中不进行“删除”操作,但是需要将每个参数都乘上1-p,使得在测试集中每个神经元计算出来的z≈训练集中每个神经元计算出来的z。

为什么深度网络更好

      经过试验,我们发现,深层网络远比同样结点数但是只有一层隐藏层的“矮胖”网络表现得好。这是为什么呢?我们可以将深度网络理解为一层一层地模组化(Modularization),例如我们需要训练出一个能分类长发女,长发男,短发女和短发男的分类器,深度网络不会将数据直接分成某一类,而是通过训练,模组化出多个次级分类器,如分类男女的分类器和分类长发短发的分类器,将这些次级分类器提供给后面的层使用。而这些模组都是自动地从数据中学习出来的,模组化能高效地使用数据,在训练数据较少时,例如上述的长发男数据可能较少,通过模组化也能实现较高准确率的分类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值