《Python数据分析与机器学习实战-唐宇迪》读书笔记第17章--神经网络

python数据分析个人学习读书笔记-目录索引

第17章神经网络

   本章介绍当下机器学习中非常火爆的算法——神经网络,深度学习的崛起更是让神经网络名声大振,在计算机视觉、自然语言处理和语音识别领域都有杰出的表现。这么厉害的算法肯定要来研究一番,可能大家觉得其原理会非常复杂,其实学习到本章,大家应该已经掌握了机器学习中绝大部分核心内容,再来理解神经网络,会发现在它其实没那么难。本章内容主要包括神经网络各模块工作细节、整体网络模型架构、过拟合解决方法。

17.1神经网络必备基础

   如果直接看整个神经网络,可能会觉得有些复杂,先挑一些重点知识点进行讲解,然后再把整个网络结构串在一起就容易理解了。

17.1.1神经网络概述

   神经网络其实是一个很古老的算法,那么,为什么现在才流行起来呢?一方面,神经网络算法需要大量的训练数据,现在正是大数据时代,可谓是应景而生。另一方面,不同于其他算法只需求解出几个参数就能完成建模任务,神经网络内部需要千万级别的参数来支撑,所以它面临的最大的问题就是计算的效率,想求解出这么多参数不是一件容易的事。随着计算能力的大幅度提升,这才使得神经网络重回舞台中央。

  数据计算的过程通常都涉及与矩阵相关的计算,由于神经网络要处理的计算量非常大,仅靠CPU迭代起来会很慢,一般会使用GPU来加快计算速度,GPU的处理速度比CPU至少快100倍。没有GPU的读者也不要担心,在学习阶段用CPU还是足够的,只要将数据集规模设置得小一些就能用(见图17-1)。

 邀月工作室

  图17-1 GPU计算

  神经网络很像一个黑盒子,只要把数据交给它,并且告诉它最终要想达到的目标,整个网络就会开始学习过程,由于涉及参数过多,所以很难解释神经网络在内部究竟做了什么(见图17-2)。

  深度学习相当于对神经网络算法做了各种升级改进,使其应用在图像、文本、语音上的效果更突出。在机器学习任务中,特征工程是一个核心模块,在算法执行前,通常需要替它选出最好的且最有价值的特征,这一步通常也是最难的,但是这个过程似乎是人工去一步步解决问题,机器只是完成求解计算,这与人工智能看起来还有些距离。但在神经网络算法中,终于可以看到些人工智能的影子,只需把完整的数据交给网络,它会自己学习哪些特征是有用的,该怎么利用和组合特征,最终它会给我们交上一份答卷,所以神经网络才是现阶段与人工智能最接轨的算法(见图17-3)。

 邀月工作室

  ▲图17-2 神经网络就像一个黑盒子

 邀月工作室

  ▲图17-3 神经网络解决图像分类问题

  原书作者迪哥中观点,基本上所有机器学习问题都能用神经网络来解决,但其中也会存在一些影响因素,那就是过拟合问题比较严重,所以还是那句话——能用逻辑回归解决的问题根本没有必要拿到神经网络中。神经网络的效果虽好,但是效率却不那么尽如人意,训练网络需要等待的时间也十分漫长,毕竟要求解几千万个参数,短时间内肯定完不成,所以还是需要看具体任务的要求来选择不同的算法。

  与其把神经网络当作一个分类或者回归算法,不如将它当成一种特征提取器,其内部对数据做了各种各样的变换,虽然很难解释变换原理,但是目的都是一致的,就是让机器能够更好地读懂输入的数据。

  下面步入神经网络的细节,看看它每一步都做了什么。

17.1.2计算机眼中的图像

   神经网络在计算机视觉领域有着非常不错的表现,现阶段图像识别的相关任务都用神经网络来做,下面将图像当作输入数据,通过一个基本的图像分类任务来看看神经网络一步步是怎么做的。

  图17-4为一张小猫图像,大家可以清晰地看到小猫的样子,但是计算机可不是这么看的,图像在计算机中是以一个三维数组或者矩阵(例如300×100×3)的形式存储在计算机中,其中300×100代表一张图片的长和宽,3代表图像的颜色通道,例如经典的RGB,此时图像就是一个彩色图。如果颜色通道数为1,也就是300×100×1,此时图像就是一个黑白图。数组中的每一个元素代表一个像素值,在0(黑)~255(白)之间变化,像素值越大,该点的亮度也越大;像素值越小,该点越暗。

 邀月工作室

  图17-4 计算机眼中的图像

  图像分类任务就是拿到一堆图像数据后,各有各的标签,要让计算机分辨出每张图像内容属于哪一个类别。看起来好像很容易,这不就是猫嘛,特征非常明显,但是实际数据集中可能会存在各种各样的问题,如照射角度、光照强度、形状改变、部分遮蔽、背景混入等因素(见图17-5),都会影响分类的效果。

 

邀月工作室

  ▲图17-5 图像识别任务的挑战

 邀月工作室

  ▲图17-5 图像识别任务的挑战(续)

  如何解决这些问题呢?如果用传统算法,需要分析各种特征,实在是个苦活。选择神经网络算法就省事多了,这些问题都交给网络去学习即可,只要有数据和标签,选择合适的模型就能解决这些问题。

  遮蔽现象是图像识别中常见的问题,例如在密集人群中进行人脸检测,最简单有效的方法就是把存在该现象的数据以及合适的标签交给神经网络进行学习,数据是最好的解决方案。

17.1.3得分函数

   下面准备完成图像分类的任务,如何才能确定一个输入属于哪个类别呢?需要神经网络最终输出一个结果(例如一个分值),以评估它属于各个类别的可能性,如图17-6所示。

 邀月工作室

  图17-6 网络的输入和输出

  为了更容易理解,先省略网络中复杂的过程,直接来看输入和输出,输入就是图像数据,输出就是分类的结果。那么如何才能得到最终的分值呢?既然图像是由很多个像素点组成的,最终它属于哪一个类别肯定也要和这些像素点联系在一起,可以把图像中的像素点当作数据特征。输入特征确定后,接下来需要明确的就是权重参数,它会结合图像中的每一个像素点进行计算,简单来说就是从图像每一个细节入手,看看每一个像素点对最终分类结果的贡献有多大。

  假设输入数据是32×32×3,一共就有3072个像素点,每一个都会对最终结果产生影响,但其各自的影响应当是不同的,例如猫的耳朵、眼睛部位会对最终结果是猫产生积极的影响,而一些背景因素可能会对最终结果产生负面的影响。这就需要分别对每个像素点加以计算,此时就需要3072个权重参数(和像素点个数一一对应)来控制其影响大小,如图17-7所示。

 邀月工作室

  图17-7 得分函数

  如果只想得到当前的输入属于某一个特定类别的得分,只需要一组权重参数(1×3072)就足够了。那么,如果想做的是十分类问题呢?此时就需要十组权重参数,例如还有狗、船、飞机等类别,每组参数用于控制当前类别下每个像素点对结果作用的大小。

  不要忽略偏置参数b,它相当于微调得到的结果,让输出能够更精确。所以最终结果主要由权重参数w来控制,偏置参数b只是进行微调。如果是十分类任务,各自类别都需要进行微调,也就是需要10个偏置参数。

  接下来通过一个实际的例子看一下得分函数的计算流程(见图17-8)。

 邀月工作室

  图17-8 得分函数计算流程

  输入还是这张猫的图像,简单起见就做一个三分类任务,最终得到当前输入属于每一个类别的得分值。观察可以发现,权重参数和像素点之间的关系是一一对应的,有些权重参数比较大,有些比较小,并且有正有负,这就是表示模型认为该像素点在当前类别的重要程度,如果权重参数为正且比较大,就意味着这个像素点很关键,对结果是当前类别起到促进作用。

  那么怎么确定权重和偏置参数的数值呢?实际上需要神经网络通过迭代计算逐步更新,这与梯度下降中的参数更新道理是一样的,首先随机初始化一个值,然后不断进行修正即可。

  从最终分类的得分结果上看,原始输入是一只小猫,但是模型却认为它属于猫这个类别的得分只有−96.8,而属于其他类别的得分反而较高。这显然是有问题的,本质原因就是当前这组权重参数效果并不好,需要重新找到更好的参数组合。

17.1.4损失函数

   在上小节预测猫、狗、船的例子中,预测结果和真实情况的差异比较大,需要用一个具体的指标来评估当前模型效果的好坏,并且要用一个具体数值分辨好坏的程度,这就需要用损失函数来计算。

  在有监督学习问题中,可以用损失函数来度量预测结果的好坏,评估预测值和真实结果之间的吻合度,即模型输出的预测值与真实值Y之间不一致的程度。一般而言,损失值越小,预测结果越准确;损失值越大,预测结果越不准确。通常情况下,训练数据(xi,yi)是固定的,可以通过调整模型参数W和b来改进模型效果。

损失函数的定义方法有很多种,根据不同的任务类型(分类或回归)和数据集情况,可以定义不同的损失函数,先来看一个简单的:

 邀月工作室

  其中,Li为当前输入数据属于正确类别的得分值与其他所有错误类别得分值的差异总和。

  当邀月工作室时,表示没有损失;当邀月工作室时,表示开始计算损失,其中Δ表示容忍程度,或者说是至少正确的比错误的强多少才不计损失。

下面实际计算一下(见图17-9)。数据有3个类别:小猫、汽车和青蛙,分别选择3张图片作为输入,假设已经得到其各自得分值。

  • 小猫对应的各类得分值:f(x1,W)=[3.2,5.1,-1.7]
  • 汽车对应的各类得分值:f(x2,W)=[1.3,4.9,2.0]
  • 青蛙对应的各类得分值:f(x3,W)=[2.2,2.5,-3.1]

 邀月工作室

  图17-9 损失值计算

  当Δ=1时,表示正确类别需比错误类别得分高出至少1个数值才算合格,否则就会有损失值。

邀月工作室

邀月工作室

邀月工作室

  从结果可以看出,第一张输入的小猫损失值为2.9,意味着做得还不够好,因为没有把小猫和汽车这两个类别区分开。第二张输入的汽车损失值为0,意味着此时模型做得还不错,成功预测到正确答案。最后一张青蛙对应的损失值为10.9,这值非常大,意味着此时模型做得很差。

  这里选择3张输入图像进行计算,得到的损失值各不相同,最终模型损失值的计算并不是由一张图像决定的,而是大量测试图像结果的平均值(例如一个batch数据):

 邀月工作室

  式(17.1)可以当作对回归任务也就是预测具体分数时的损失函数(损失函数的定义方法有很多,可以根据任务不同自己选择)。但对于分类任务来说,更希望得到一个概率值,可以借用softmax方法来完成分类任务。例如,当前的输入属于猫的概率为80%,狗的概率为20%,那么它的最终结果就是猫。

  分类任务损失值计算流程如图17-10所示,先按流程走一遍,然后再看数学公式就好理解了。首先,假设一张小猫图像经过神经网络处理后得到其属于3个类别的得分值分别为(3.2,5.1,-1.7),只看得分值,感觉差异并不大,为了使得结果差异能够更明显,进行了映射(见图17-11)。

 邀月工作室

  图17-10 分类任务损失值计算流程

  经过映射后,数值差异更明显,如果得分值是负数,基本就是不可能的类别,映射后也就更接近于0。现在只是数值进行变换,如何才能转换成概率值呢?只需简单的归一化操作即可。

  假设已经得到当前输入属于每一个类别的概率值,输入明明是一只小猫,但是结果显示猫的概率值只有13%,看起来模型做得并不好,需要计算其损失值,这里还是借助对数函数,如图17-12所示。

 邀月工作室

  ▲图17-11 数值映射

 邀月工作室

  ▲图17-12 对数函数

  需要注意一点:对数函数的输入是当前输入图像属于正确类别的概率值,也就是上述例子中的0.13,表示只关心它在正确类别上的分类效果,理想情况是它属于猫的概率为100%。

  通过对数函数可以发现,当输入的概率结果越接近于1时,函数值越接近0,表示完全做对了(100%属于正确类别),不会产生损失。如果没有完全做对,效果越差(输入越接近于0)时,对应的损失值也会越大(虽然是负的,取其相反数就会变成正的)。

  解释过后,再把每一步的操作穿插在一起,就是分类任务中损失函数的定义:

 邀月工作室

  损失函数中,还加入了正则化惩罚项,这一步也是必须的,因为神经网络实在太容易过拟合,后续就会看到,它的表现能力还是很惊人的。

  假设输入图像属于猫、汽车、青蛙3个类别的得分值为[3.2,5.1,−1.7],计算过程如下。

    1.求出各得分值的指数次幂,结果为邀月工作室

    2.归一化处理,即计算出每类的(上图中log后面小括号内的部分),结果为[0.13,0.87,0.00],因为0.87较大,所以可以将该图片分类为汽车,显然,该结果是有误差的,所以要计算损失函数。

    3.在求解损失函数时,只需要其属于正确类别的概率,本例中图片正确的分别为小猫,所以损失函数为L1=-log0.13=0.89

17.1.5反向传播

   终于要揭开神经网络迭代计算的本质了,现在已经完成了从输入数据到计算损失的过程,通常把这部分叫作前向传播(见图17-13)。但是网络模型最终的结果完全是由其中的权重与偏置参数来决定的,所以神经网络中最核心的任务就是找到最合适的参数。

 邀月工作室

  图17-13 前向传播过程

  前面已经讲解过梯度下降方法,很多机器学习算法都是用这种优化的思想来迭代求解,神经网络也是如此。当确定损失函数之后,就转化成了下山问题。但是神经网络是层次结构,不能一次梯度下降就得到所有参数更新的方向,需要逐层完成更新参数工作(见图17-14)。

 邀月工作室

  图17-14 神经网络组成

  由于网络层次的特性,在计算梯度的时候,需要遵循链式法则,也就是逐层计算梯度,并且梯度是可以传递的,如图17-15所示。

 邀月工作室

邀月工作室

  图17-15 函数组成

  既然要对参数进行更新,可以看一看不同的参数对模型的损失做了什么贡献。如果一个参数使得模型的损失增大,那就要削减它;如果一个参数能使得模型的损失减小,那就增大其作用。上述例子中,就是把x,y,z分别看成影响最终结果的3个因子,现在要求它们对结果的影响有多大:

 邀月工作室

  可以观察到,z和结果是直接联系在一起的,但是x和y和最终的结果并没有直接关系,可以额外引入一项q,令q=x+y,这样q就直接和结果联系在一起,而x和y又分别与q直接联系在一起:

 邀月工作室

  通过计算可以看出,当计算x和y对结果的贡献时,不能直接进行计算,而是间接计算q对结果的贡献,再分别计算x和y对q的贡献。在神经网络中,并不是所有参数的梯度都能一步计算出来,要按照其位置顺序,一步步进行传递计算,这就是反向传播(见图17-16)。

 邀月工作室

  图17-16 反向传播过程

  从整体上来看,优化方法依旧是梯度下降法,只不过是逐层进行的。反向传播的计算求导相对比较复杂,建议大家先了解其工作原理,具体计算交给计算机和框架完成。

 

17.2神经网络整体架构

   上一节讲解了神经网络中每一个基础模块的原理及其工作流程,接下来要把它们组合成一个完整的神经网络,从整体上看神经网络到底做了什么。

  原书作者迪哥:有些书籍中介绍神经网络时,会从生物学、类人脑科学开始讲起,但是神经网路中真的有轴突、树突这些结构吗?笔者认为,还是直接看其数学上的组成最直截了当,描述越多,其实越加大理解它的难度。

17.2.1整体框架

   神经网络整体架构如图17-17所示,只要理解这张图,神经网络就能理解得差不多。可以看出,神经网络是一个层次结构,包括输入层、隐藏层和输出层。

 邀月工作室

  图17-17 神经网络整体架构

  • (1)输入层。图17-17的输入层中画了3个圆,通常叫作3个神经元,即输入数据由3个特征或3个像素点组成。
  • (2)隐藏层1。输入数据与隐藏层1连接在一起。神经网络的目标就是寻找让计算机能更好理解的特征,这里面画了4个圆(4个神经元),可以当作通过对特征进行某种变换将原始3个特征转换成4个特征(这里的3和4都是假设,实际情况下,数据特征和隐层特征都是比较大的)。

  原始数据是3个特征,这是由数据本身决定的,但是,隐藏层的4个特征表示什么意思呢?这个很难解释,神经网络会按照某种线性组合关系将所有特征重新进行组合,之前看到的权重参数矩阵中有正有负,有大有小,就意味着对特征进行何种组合方式。神经网络是黑盒子的原因也在于此,很难解释其中过程,只需关注其结果即可。

  • (3)隐藏层2。在隐藏层1中已经对特征进行了组合变换,此时隐藏层2的输入就是隐藏层1变换后的结果,相当于之前已经进行了某种特征变换,但是还不够强大,可以继续对特征做变换处理,神经网络的强大之处就在于此。如果只有一层神经网络,与之前介绍的逻辑回归差不多,但是一旦有多层层次结构,整体网络的效果就会更强大。
  • (4)输出层。最终还是要得到结果的,就看要做的任务是分类还是回归,选择合适的输出结果和损失函数即可,这与传统机器学习算法一致。

  神经网络中层和层之间都是全连接的操作,也就是隐层中每一个神经元(其中一个特征)都与前面所有神经元连接在一起,这也是神经网络的基本特性。全连接计算如图17-18所示,所谓的全连接,其实就是通过矩阵将数据或者特征进行变换。例如,输入层的数据是[1,3],表示一个本数据,3个特征(也可以是一个batch数据)。通过权重参数矩阵w1:[3,4]进行矩阵乘法操作,结果就是[1,4],相当于对原始输出特征进行转换,变成4个特征。接下来还需要通过w2、w3分别对中间特征进行转换计算,最终得到一个结果值,可以当作回归任务。如果是分类任务,例如十分类,输出层可以设计成10个神经元,也就是当前输入属于每一个类别的概率值,w3也相应地变成[4,10]。

 邀月工作室

  图17-18 全连接计算

  如果直接对输入数据依次计算,其经过式(17.5)和式(17.6)参考变换得到结果看起来是一种线性变换,但是神经网络能处理的问题肯定不止线性问题,所以,在实际构造中,还需引入非线性函数,例如Sigmoid函数,但是现阶段一般不用它,先来看一个更简单的函数:

 邀月工作室

  Max(0,x)函数看起来更直截了当,它是非常简单的非线性函数,暂且用它来当作对神经网络进行非线性变换的方法,需要把它放到每一次特征变换之后,也就是在基本的神经网络中,每一个矩阵相乘后都需要加上一个非线性变换函数。

  再继续堆叠一层,计算方法相同:

 邀月工作室

17.2.2神经元的作用

   概述神经网络的整体架构之后,最值得关注的就是特征转换中的神经元,可以将它理解成转换特征后的维度。例如,隐藏层有4个神经元,就相当于变换得到4个特征,神经元的数量可以自己设计,那么它会对结果产生多大影响呢?下面看一组对比实验。选择相同的数据集,在网络模型中,只改变隐藏层神经元个数,得到的结果如图17-19所示。数据集稍微有点难度,是一个环形。当隐藏层神经元个数只有1个时,好像是只切了一刀,并没有达到想要的结果,说明隐藏层只利用一个特征,还是太少了。当隐藏层神经元个数为2时,这回像是切了两刀,但还是差那么一点,没有完全分对,看起来还是特征多一点好。如果继续增加,隐藏层神经元个数为3时,终于达到目标,数据集能完全分开。

 邀月工作室

  图17-19 神经元个数对结果影响

  当隐藏层神经元数量增大的时候,神经网络可以利用的数据信息就更多,分类效果自然会提高,那么,是不是神经元的数量越多越好呢?先来算一笔账吧,假设一张图像的大小为[800,600,3],这是常规的图像尺寸,其中一共有800×600×3=1440000个像素点,相当于输入数据(也就是输入层)一共有1440000个神经元,因此要画1440000个圆,给打个折,暂且算有100万个输入像素点。当隐藏层神经元个数为1时,输入层和隐藏层之间连接的矩阵就是[100W,1]。当隐藏层神经元个数为2时,权重参数矩阵为[100W,2]。增加一个隐藏层神经元时,参数不只增加一个,而是增加一组,相当于增加了100W个权重参数。

  因此在设计神经网络时,不能只考虑最终模型的表现效果,还要考虑计算的可行性与模型的过拟合风险。

  神经网络为什么现阶段才登上舞台呢?这很大程度上是由于以前的计算机性能根本无法满足这么庞大的计算量,而且参数越多,过拟合也越严重。

  图17-19所示的数据集可能有点简单,大家一看就知道支持向量机也能解决这类问题,下面换一个复杂的试试,如图17-20所示。

邀月工作室

  图17-20 神经网络效果

  这回找到一个有个性的数据集,此时3个神经元已经不能满足需求,当神经元个数增大至5时,才能完成这个任务。可以发现神经网络的效果还是比较强大的,只要神经元个数足够多,就能解决这些复杂问题。此时有一个大胆的想法,如果随机构建一个数据集,再让神经网络去学习其中的规律,它还能解决问题吗?

  图17-21是使用相同的神经网络在随机创建的几份数据集上的效果。由于问题比较难,神经元数量增加到15个,结果真能把随机数据集完全切分开,现在给大家的感觉是不是神经网络已经足够强大了。机器学习的出发点是要寻找数据集中的规律,利用规律来解决实际问题,现在即便一份数据集是随机构成的,神经网络也能把每一个数据点完全分开。

 邀月工作室

  图17-21 神经网络在随机数据集上的效果

  神经网络虽然强大,但这只是在训练集上得到的效果,此时来看决策边界已经完全过拟合。如图17-22所示,被选中的数据点看起来可能是异常或者离群点。由于它的存在,使得整个模型不得不多划分出一个决策边界,实际应用时,如果再有数据点落在该点周围,就会被错误地预测成红色类别。

 邀月工作室

  图17-22 过拟合现象

  这样的网络模型在实际测试中效果肯定不好,所以神经网络中最大的问题就是过拟合现象,需要额外进行处理。

17.2.3正则化

   神经网络效果虽然强大,但是过拟合风险实在是高,由于其参数过多,所以必须进行正则化处理,否则即便在训练集上效果再高,也很难应用到实际中。

  最常见的正则化惩罚是L2范数,即邀月工作室,它对权重参数中所有元素求平方和,显然,只与权重有关系,而和输入数据本身无关,只惩罚权重。

  在计算正则化惩罚时,还需引入惩罚力度,也就是λ,表示希望对权重参数惩罚的大小,还记得信用卡检测案例吗?它就是其中一个参数,选择不同的惩罚力度在神经网络中的效果差异还是比较大的。

  正则化惩罚力度如图17-23所示,当惩罚力度较小时,模型能把所有数据点完全分开,但是,数据集中会存在一些有问题的数据点,可能由于标注错误或者其他异常原因所导致,这些数据点使得模型的决策边界变得很奇怪,就像图17-23(a)所示那样,看起来都做对了,但是实际测试集中的效果却很差。

  当惩罚力度较大时,模型的边界就会变得比较平稳,虽然有些数据点并没有完全划分正确,但是这样的模型实际应用效果还是不错的,过拟合风险较低。

  通过上述对比可以发现,不同的惩罚力度得到的结果完全不同,那么如何进行选择呢?还是一个调参的问题,但是,通常情况下,宁可选择图17-23(c)中的模型,也不选择图17-23(a)中的模型,因为其泛化能力更强,效果稍微差一点还可以忍受,但是完全过拟合就没用了。

 邀月工作室

  图17-23 正则化惩罚力度

17.2.4激活函数

   在神经网络的整体架构中,将数据输入后,一层层对特征进行变换,最后通过损失函数评估当前的效果,这就是前向传播。接下来选择合适的优化方法,再反向传播,从后往前走,逐层更新权重参数。

  如果层和层之间都是线性变换,那么,只需要用一组权重参数代表其余所有的乘积就可以了。这样做显然不行,一方面神经网络要解决的不仅是线性问题,还有非线性问题;另一方面,需要对变换的特征加以筛选,让有价值的权重特征发挥更大的作用,这就需要激活函数。

  常见的激活函数包括Sigmoid函数、tanh函数和ReLu函数等,最早期的神经网络就是将Sigmoid函数当作其激活函数。数学表达式为:

 邀月工作室

  其图形如图17-24所示。

 邀月工作室

  图17-24 Sigmoid函数

  早期的神经网络为什么没有流行起来呢?一方面是之前所说的计算性能所限,另一方面就是Sigmoid函数自身的问题,在反向传播的过程中,要逐层进行求导,对于Sigmoid函数来说,当数值较小时(例如−5到+5之间),导数看起来没有问题。但是一旦数值较大,其导数就接近于0,例如取+10或−10时,切线已经接近水平了。这就容易导致更大的问题,由于反向传播是逐层进行的,如果某一层的梯度为0,它后面所有网络层都不会进行更新,这也是Sigmoid函数最大的问题。

  Tanh函数表达式为:

 邀月工作室

  其图形如图17-25所示。

 邀月工作室

  图17-25 tanh函数

  Tanh函数的优点是它能关于原点对称,但是,它同样没有解决梯度消失的问题,因此被淘汰。

  ReLu函数表达式为:

 邀月工作室

  其图形如图17-26所示。

  Relu函数的作用十分简单,对于输入x,当其小于0时,输出都是0,在大于0的情况下,输出等于输入本身。同样是非线性函数,却解决了梯度消失的问题,而且计算也十分简便,加快了网络的迭代速度。

  现阶段激活函数的选择基本都是Relu函数或是它的变形体,后续实验中还会再看到Relu函数。

 邀月工作室

  图17-26 Relu函数

 

17.3网络调优细节

   在设计神经网络过程中,每一个环节都会对最终结果产生影响,这就需要考虑所有可能的情况,那么是不是训练网络时,需要进行很多次实验才能选中一个合适的模型呢?其实也没有那么复杂,基本处理的方法还是通用的。

17.3.1数据预处理

   目前,神经网络是不是已经强大到对任何数据都能产生不错的效果呢?要想做得更好,数据预处理操作依然是非常核心的一步,如果数据更规范,网络学起来也会更容易。

对数值数据进行预处理最常用的就是标准化操作,如图17-27所示,首先各个特征减去其均值,相当于以原点对称,接下来再除以各自的标准差,让各个维度取值都统一在较小范围中。

 邀月工作室

  图17-27 标准化操作

  对图像数据也是需要预处理操作,保证输入的大小规模都是统一的,例如都是32×32×3,如果各自大小不同,还需resize到统一规模,这点是必需的,因为在基本的神经网络中,所有参数计算都是矩阵相乘,如果输入不统一,就没法进行特征变换。不仅如此,通常图像数据的像素点取值范围是在0~255之间,看起来浮动比较大,可以使用归一化方法来把所有像素点值压缩到0~1之间。

  文本数据更要进行预处理操作,最起码要把文本或者词语转换成向量。为了满足神经网络的输入,还需限制每一篇文本的长度都是统一的,可以采用多退少补原则来处理文本长度,后续在实验中还会详细解释其处理方法。

  简单介绍几种数据预处理方法后发现,基本的出发点还是使数据尽可能规范一些,这样学习神经网络更容易,过拟合风险也会大大降低。

  在神经网络中,每一个参数都是需要通过反向传播来不断进行迭代更新的,但是,开始的时候也需要有一个初始值,一般都是随机设置,最常见的就是随机高斯初始化,并且取值范围都应较小,在初始阶段,不希望某一个参数对结果起到太大的影响。一般都会选择一个较小的数值,例如在高斯初始化中,选择均值为0且标准差较小的方法。

17.3.2Drop-Out

   过拟合一直是神经网络面临的问题,Drop-Out给人的感觉就像是七伤拳,它能解决一部分过拟合问题,但是也会使得网络效果有所下降,下面看一下它的结构设计。

  过拟合问题源于在训练过程中,每层神经元个数较多,所以特征组合提取方式变得十分复杂,相当于用更多参数来拟合数据。如果在每一次训练迭代过程中随机杀死一部分神经元,如图17-28所示,就可以有效地降低过拟合风险。为了使得整体网络架构在实际应用时保持不变,强调每次迭代都进行随机选择,也就是对一个神经元来说,可能这次迭代没有带它玩,下次迭代就把它带上了。所以在测试阶段照样可以使用其完整架构,只是在训练阶段为了防止过拟合而加入的策略。

 邀月工作室

  图17-28 Drop-Out

  Drop-Out方法巧妙地将神经元的个数加以控制,已经成为现阶段神经网络中必不可少的一部分,通常每次迭代中会随机保留40%~60%的神经元进行训练。

17.3.3数据增强

   神经网络是深度学习中的杰出代表,深度学习之所以能崛起还是依靠大量的数据,如图17-29所示。当数据量较少时,深度学习很难进行,最好用更快速便捷的传统机器学习算法。

 邀月工作室

  图17-29 深度学习对数据量的要求

  由于神经网络要在原始的输入数据中找到最合适的特征提取方法,所以数据量一定要够,通常都是以万为单位,越多越好。但是,如果在一项任务中,没有那么多数据该怎么办呢?此时也可以自己创作。

  对于一张图像数据来说,经过平移、翻转、旋转等操作,就可以得到另外一张图像,这就是最常用的图像生成策略,可以让数据呈现爆炸式的增长,直接翻十倍都不成问题。Opencv工具包可以对图像执行各种操作,以完成数据增强任务,如图17-30所示。

 邀月工作室

  图17-30 数据增强

  现在给大家推荐一个工具—keras中的数据增强函数,简直太方便了。如果用opencv做变换,基本所有操作都需要自己完成,稍微有些麻烦,使用下面这个函数之后,等着收图就可以了,其原理也是一样的,按照参数进行设置,同时对图像执行平移、旋转等操作,详细内容可以查阅其API文档。

 

  在进行图像增强的同时,不要忘记标签也要随之变化,如果是分类任务,还比较容易,但在回归任务中,还需得到标签变换后的新坐标。

  在训练网络时,可能会遇到一些挑战,例如数据中各种潜在的问题(如图像中的遮蔽现象),最好的解决方案还是从数据入手,毕竟对数据做处理,比对网络进行调整更容易理解,所以,当大家进行实际任务遇到挑战时,可以尝试先从数据下手,效果更直接明了。

17.3.4网络结构设计

   神经网络模型可以做得比较复杂,需要大家进行详细的设计,例如神经元个数、网络层数等。这样做起来岂不是要做大量的实验?由于实际中训练一个任务要花费2~3天,所以效率会大大降低。最简单快速的方法就是使用经典网络模型,也就是大家公认的、效果比较不错的网络模型,在处理实际问题的时候,都是直接用经典模型进行实验研究,很少自己从头去尝试新的结构,如果要改进,也是在其基础上进行改进升级。所以,并不建议大家在处理实际任务的时候,脑洞大开来设计网络结构,还是老老实实用经典的,这也是最省事的。在解决问题的时候,最好先查阅相关论文,看看大牛们是怎么做的,如果问题类似,最好借助于别人的解决方案。

 

本章小结:

  本章向大家介绍了神经网络模型,先按照其工作流程分析每一步的原理和作用,最后将完整的网络模型结合在一起。对比不同实验效果,很容易观察到神经网络强大的原因在于它使用了大量参数来拟合数据。虽然效果较传统算法有很大提升,但是在计算效率和过拟合风险上都有需要额外考虑的问题。

  对于图像数据来说,最大的问题可能就是其像素点特征比较丰富,如果使用全连接的方式进行计算,矩阵的规模实在过于庞大,如何改进呢?后续要讲到的卷积神经网络就是专门处理图像数据的。

  在网络训练迭代过程中,每次传入的样本数据都是相互独立的,但是有些时候需要考虑时间序列,也就是前后关系的影响,看起来基本的神经网络模型已经满足不了此项需求,后续还要对网络进行改进,使其能处理时间序列数据,也就是递归神经网络。可以看出,神经网络只是一个基础模型,随着技术的发展,可以对其做各种各样的变换,以满足不同数据和任务的需求。

  对于神经网络的理解,从其本质来讲,就是对数据特征进行各种变换组合,以达到目标函数的要求,所以,大家也可以把神经网络当作特征提取和处理的黑盒子,最终的分类和回归任务只是利用其特征来输出结果。

 

第17章完。推荐《Python数据分析与机器学习实战-唐宇迪》读书笔记第18章--TensorFlow实战

python数据分析个人学习读书笔记-目录索引

 

该书资源下载,请至异步社区:https://www.epubit.com

 

posted @ 2020-04-13 14:53  邀月  阅读(518)  评论(0编辑  收藏  举报