社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

AI | 算法工程师必备的深度学习--深度前馈网络(下)

运筹OR帷幄 • 3 年前 • 623 次点击  

    


↑↑↑↑↑点击上方蓝色字关注我们!






『运筹OR帷幄』原创


作者:华校专


作者信息:

华校专,曾任阿里巴巴资深算法工程师、智易科技首席算法研究员,现任腾讯高级研究员,《Python 大战机器学习》的作者。

编者按:

算法工程师必备系列更新啦!继上次推出了算法工程师必备的数学基础后,小编继续整理了必要的机器学习知识,全部以干货的内容呈现,哪里不会学哪里,老板再也不用担心你的基础问题!

四、隐单元

  1. 隐单元的设计是一个非常活跃的研究领域,并且目前还没有明确的指导性理论,难以决定何时采用何种类型的隐单元。

  • 通常不能预先判断哪种类型的隐单元工作的最好,所以设计过程中需要反复试错,通过测试集评估其性能来选择合适的隐单元。
  • 一般默认采用的隐单元是修正线性单元,但是仍然有许多其他类型的隐单元。
  • 某些隐单元可能并不是在所有的输入上都是可微的。如:修正线性单元处不可微,这使得在该点处梯度失效。

  •       事实上梯度下降法对这些隐单元的表现仍然足够好,原因是:

      • 神经网络的训练算法通常并不会达到代价函数的局部最小值,而仅仅是显著地降低代价函数的值即可。

        因此实际上训练过程中一般无法到达代价函数梯度为零的点,所以代价函数取最小值时梯度未定义是可以接受的。

      • 不可微的点通常只是在有限的、少数的点上不可微,在这些不可微的点通常左导数、右导数都存在。

        神经网络训练的软件实现通常返回左导数或者右导数其中的一个,而不是报告导数未定义或者产生一个错误。

        这是因为计算机计算 0 点的导数时,由于数值误差的影响实际上不可能计算到理论上 0 点的导数,而是一个微小的偏离:向左侧偏离就是左导数,向右侧偏离就是右导数。

         3.大多数隐单元的工作都可以描述为下面三步:


             •  接受输入向量  。

             •  计算仿射变换 。

             •  用非线性函数 计算隐单元输出。

            函数  也称作激活函数,大多数隐单元的区别仅仅在于激活函数 的形式不同。

           4.神经网络的隐层由多个隐单元组成,隐层的输出为:

        4.1 修正线性单元

        1. 修正线性单元采用激活函数 ,它和线性单元非常类似,区别在于:修正线性单元在左侧的定义域上输出为零。

        • 优点:采用基于梯度的优化算法时,非常易于优化。

          当修正线性单元处于激活状态时,导数为常数1 ;当修正线性单元处于非激活状态时,导数为常数0 。修正线性单元的二阶导数几乎处处为零。

        • 缺点:无法通过基于梯度的方法学习那些使得修正线性单元处于非激活状态的参数,因为此时梯度为零。

      1. 对于修正线性单元 ,初始化时可以将 的所有元素设置成一个小的正值(如0.1),从而使得修正线性单元在初始时尽可能的对训练集中大多数输入呈现激活状态。

      2. 有许多修正线性单元的扩展存在,这些扩展保证了它们能在各个位置都保持非零的梯度。

        大多数扩展的表现与修正线性单元相差无几,偶尔表现的更好。

      3. 修正线性单元的三个扩展:当 时,使用一个非零的斜率

        • 绝对值修正absolute value rectification:使用 ,此时

        • 渗透修正线性单元leaky ReLU:将 固定成一个类似 0.01 的小值。

        • 参数化修正线性单元parametric ReLU:将 作为学习的参数。

          此时 是与训练集相关的。不同的训练集,学得的 会不同。

        4.2 maxout单元

        1. ReLU 单元及其扩展都基于一个原则:越接近线性,则模型越容易优化。采用更容易优化的线性,这种一般化的原则也适用于除了深度前馈网络之外的网络。

        1. maxout单元是修正线性单元的进一步扩展。maxout单元并不是作用于的每个元素,而是将 分成若干个小组,每个组有个元素:

          然后maxout单元对每个组输出其中最大值的元素:

        • 假设 是 100维的, ,则 为 5维的向量。
        • 至于如何分组,则没有确定性的指导准则。

        1. maxout 单元的 通常是通过对输入 执行多个仿射变换而来。

          maxout 单元有 个分组,输出为


                令 

              则有:

        1. maxout 单元的优点:

                •  接近线性,模型易于优化。

                •   经过maxout层之后,输出维数降低到输入的 。这意味着下一层的权重参数的数量降低到maxout层的

                •  由多个分组驱动,因此具有一些冗余度来抵抗遗忘灾难catastrophic forgetting

                   遗忘灾难指的是:网络忘记了如何执行它们过去已经训练了的任务。

        1. 在卷积神经网络中, max pooling层就是由maxout单元组成。

        2. maxout单元提供了一种方法来学习输入空间中的多维度线性分段函数。它可以学习具有 段的线性分段的凸函数,因此maxout单元也可以视作学习激活函数本身。

        3. 使用足够大的maxout单元能够以任意程度逼近任何凸函数。

        • 特别的, 时的maxout单元组成的隐层可以学习实现传统激活函数的隐层相同的功能,包括:ReLU函数、绝对值修正线性激活函数、leakly ReLU函数、参数化ReLU函数,也可以学习不同于这些函数的其他函数。
        • 注意:maxout层的参数化与ReLU层等等这些层不同(最典型的,maxout层的输出向量的维数发生变化),因此即使maxout层实现了ReLU函数,其学习机制也不同。

        4.3 sigmoid / tanh 单元

        1. sigmoid单元和tanh单元:其激活函数分别为sigmoid函数和tanh函数。

        2. 在引入修正线性单元之前,大多数神经网络使用sigmoid函数,或者双曲正切函数 作为激活 函数。这两个激活函数密切相关,因为

          与修正线性单元不同,sigmoid单元和tanh单元在其大部分定义域内都饱和,仅仅当 在 0 附近才有一个较高的梯度,这会使得基于梯度的学习变得非常困难。因此,现在不鼓励将这两种单元用作深度前馈网络中的隐单元。

        • 如果选择了一个合适的代价函数(如对数似然函数)来抵消了sigmoid的饱和性,则这两种单元可以用作输出单元(而不是隐单元)。
        • 如果必须选用sigmoid激活函数时,tanh激活函数通常表现更佳。因为tanh函数在 0点附近近似于单位函数

      4. sigmoid激活函数在前馈网络之外的神经网络中更为常见。

        有一些网络不能使用修正线性单元,因此sigmoid激活函数是个更好的选择,尽管它存在饱和问题。

        • 循环神经网络:修正线性单元会产生信息爆炸的问题。
        • 一些概率模型:要求输出在 0~1 之间。

        4.4 其他隐单元

        1. 存在许多其他种类的隐单元,但它们并不常用。经常会有研究提出一些新的激活函数,它们是前述的标准激活函数的变体,并表示它们表现得非常好。

          除非这些新的激活函数被明确地证明能够显著地改进时,才会发布这些激活函数。如果仅仅与现有的激活函数性能大致相当,则不会引起大家的兴趣。

        2. 隐单元的设计仍然是个活跃的研究领域,许多有效的隐单元类型仍有待挖掘。

        3. 线性隐单元:它完全没有激活函数 ,也可以认为是使用单位函数 作为激活函数 。

        • 如果网络的每一层都是由线性变换组成,则网络作为整体也是线性的。这会降低网络的表达能力,因此线性隐单元较少使用。

        • 线性隐单元提供了一种减少网络中参数的数量的有效方法。

          假设有一个隐层,它有 个输入,个输出,隐向量为 ,则 维的矩阵,需要 个参数。

          可以用两层来代替该层:第一层使用权重矩阵 ,且没有激活函数;第二层使用权重矩阵 ,且为常规激活函数。这对应了的因式分解:

          假设第一层产生了 个输出,则有:第一层的输入为 个,输出为 个;第二层的输入为 个,输出为 个。

          整体参数为 个。当很小时,可以满足 ,从而减少了参数。

          事实上第一层的输出 实际上对应着对输入 的一个编码(或者称作降维):将 维的向量压缩到维。如果 非常小,则输入 信息压缩的过程中会丢失大量的信息。

      5. softmax隐单元:激活函数为softmax函数。

        • softmax单元既可以用作输出单元,也可以用作隐单元。
        • softmax单元可以很自然地表示具有 个可能取值的离散型随机变量的概率分布,因此它也可以视作一种开关。
      6. 径向基函数隐单元:激活函数为径向基函数RBF

        其中 表示权重矩阵的第 列。

        径向基函数在 接近 时非常活跃,但是对于大部分 该函数值都饱和到 0,因此难以优化。

      7. softplus 隐单元:激活函数为softplus函数: 。这种单元是修正线性单元的平滑版本。

        通常不鼓励使用softplus激活函数,而推荐使用修正线性单元。理论上softplus函数处处可导,且它不完全饱和,所以人们希望它具有比修正线性单元更好的性能。但是根据经验来看,修正线性单元效果更好。

      8. 硬双曲正切隐单元:激活函数为硬双曲正切函数:

        它的形状和tanh以及修正线性单元类似,但是它是有界的且在点不可导。

      9. 4.5 激活函数对比

        1. sigmoid主要缺点:

        • 容易饱和从而使得梯度消失。当激活函数取值在接近0或者1时会饱和,此时梯度为近似为0。
        • 函数输出不是零中心的。这会导致后续神经元的输出数值总是正数。
      10. tanh

      11.   •  优点:函数输出是零中心的。
          •  缺点:容易饱和从而使得梯度消失。
        tanh 激活函数几乎在所有场合都是优于sigmoid 激活函数的。但是有一种情况例外:如果要求函数输出是0~1 之间(比如表征某个概率),则二者之间必须用sigmoid
      12. relu

        • 优点:对随机梯度下降的收敛有巨大的加速作用,而且非常容易计算。

        • 缺点:可能导致神经元死掉。

          当一个很大的梯度流过relu 神经元时,可能导致梯度更新到一种特别的状态:在这种状态下神经元无法被其他任何数据点再次激活。此后流过这个神经元的梯度将变成 0,该单元在训练过程中不可逆的死亡。

          如果学习率设置的过高,可能会发现网络中大量神经元都会死掉。整个训练过程中,这些神经元都不会被激活。

      13. leaky relu:为了解决 relu 死亡神经元的问题的尝试,但是效果并不明显。

      14. maxout:它是reluleaky relu 的一般性归纳,以单输出的两段为例:

        • 当分成两段且时,就退化为单输出的 relu 激活函数。

        • maxout单元拥有 relu 单元的所有优点,而没有它的缺点。

        • maxout 单元的缺点:

          对于 k 段的maxout, 假设其输出为 n 维的,输出为 ,则有:

          相对于relu 单元 , 可以看到:maxout 单元的参数数量增加到 k 倍。

          注意,前面提到:maxout 下一层的权重参数的数量降低到maxout层的 。而这里说明的是:maxout 单元本层的参数数量是relu 的 k 倍。二者不矛盾。

      15. 在同一个网络中混合使用不同类型的激活函数非常少见,虽然没有什么根本性的问题来禁止这么做。

      16. 激活函数选取准则:

        • 通常建议使用 relu 激活函数。

        • 注意设置好学习率,同时监控网络中死亡的神经元占比。

          如果神经元死亡比例过高,则使用 leaky relu 或者 maxout 激活函数。

        五、结构设计

        1. 神经网络的结构指的是:神经网络有多少个单元、这些单元如何连接。

          理想的网络结构必须根据具体任务反复试验,并评估验证集的误差来得到。

        2. 大多数神经网络被组织成以层为单位,然后层级之间为链式结构。每一层都是前一层的函数,如:第一层为、第二层为、…

        3. 链式结构中,主要的结构考虑是:网络的深度(一共多少层)、每一层的宽度(每一层的输出向量的维数)。

        • 即使只有一层隐层的网络也能够适应训练集。
        • 对于更深层的网络,每一层可以使用少得多的单元和参数,并且对于测试集的泛化性能更好。

        5.1 通用近似定理

        1. 通用近似定理universal approximation theorem表明:

          对于一个具有线性输出层,和至少一层具有任何一种“挤压”性质的激活函数(如sigmoid激活函数)的隐层的深度前馈神经网络,只要给予网络足够数量的隐单元,它可以以任意精度来近似任何一个从有限维空间到有限维空间的Borel可测函数。前馈神经网络的导数也可以以任意精度来逼近被近似函数的导数。

        • 定义在 的有界闭集上的任意连续函数是 Borel可测的,因此可以用神经网络来近似。
        • 神经网络也可以近似这样的任意一个函数:从有限维离散空间映射到另一个有限维离散空间。
        • 虽然原始定理要求特殊的激活函数(该激活函数要求:当自变量的绝对值非常大时,函数饱和),但是后来证明通用近似定理也适用于更广泛的激活函数,其中包括常用的修正线性单元。
      17. 通用近似定理表明:无论试图学习什么样的函数,一个很大的深度前馈网络一定能够表示这个函数。

        实际上不能保证训练算法能够学得这个函数,学习可能因为两个不同的原因而失败:

        • 用于训练的优化算法可能找不到合适的参数值来逼近该函数,即:优化算法缩小了模型的有效容量,使得该函数不在有效的解空间内。
        • 训练算法可能由于过拟合而选择了错误的函数。
      18. 通用近似定理说明了存在一个足够大的网络能够以任意精度逼近任意函数,但是定理并没有说这个网络有多大。最坏的情况下可能需要指数级的隐单元。

        • 具有单隐层的深度前馈网络足以表示任何函数,但是隐层可能过于庞大以至于无法正确地学习和泛化。使用更深的深度前馈网络可以减少所需的单元的数量,并且减少泛化误差。
        • 很多情况下,浅层模型所需的隐单元的数量是输入向量的维数 n 的指数级。
      19. 修正线性网络(激活函数都是relu 函数)描述的线性区域的数量为输入向量维数 n 的指数级,也是网络深度 l 的指数级。

      20. 5.2 网络结构

        1. 任何时候当选择一个特定的机器学习算法时,隐含地给定了一个先验知识:算法  应该学得什么样的函数。

          选择深度模型则给定了一个先验知识:待学的函数应该是几个更加简单的函数的组合。这意味着:待学习的问题包含一组潜在的因子,这些因子可以根据更简单的潜在因子描述。

        2. 试验表明:更深的网络泛化性能更好,而仅仅增加参数的数量对于泛化性能几乎没有不起作用。

        • 虽然一个2层网络在数学理论上能完美近似所有连续函数,但实际操作中效果相对较差。就实践经验而言,深度网络效果比单层效果好。
        • 不要因为担心出现过拟合而使用小网络,而要尽可能使用大网络,然后使用正则化技术来控制过拟合。

        下图依次表示:不同网络层数的网络的泛化性能(测试集的准确率)、不同参数数量和网络层数的网络的泛化性能。

        3. 前面介绍的前馈神经网络都是简单的以层为单位的链式结构,主要考虑网络的深度和每层的宽度。实践中的神经网络具有相当的多样性。

          • 卷积神经网络是另一种特殊的结构。

          • 有时候,层不需要位于链中。

            有的神经网络构(如ResNet )建了一条主链,然后又添加了额外的结构。如从层 i 连接到层 i+2 ,这使得梯度更容易地从输出层流向输入端。

          4.除了深度与每一层的宽度之外,结构设计考虑的另一个因素是:如何将层与层之间连接起来。

            • 默认的神经网络使用矩阵 给出的线性变换来描述层之间的连接。此时对于本层的每一个单元,其输入为上一层的所有输出。
            • 某些特殊的网络使用更少的连接,上一层的输出只是连接到本层的部分单元。这种策略减少了参数的数量,但是依赖于具体问题。
            • 很难对于通用的神经网络结构给出有效的建议。通常会给出一些特殊的结构,可以在不同的领域工作良好。如:CNN在图像识别领域工作很好。

            六、历史小记

            1. 现代前馈网络的核心思想自20世纪80年代以来没有发生重大变化。

              近年来神经网络性能的大部分改变可归因于两个因素:更大的数据集、更大的网络(由于硬件的强大和软件设施的发展)。

              算法上的部分改变也显著改善了神经网络的性能:

            • 用交叉熵代替均方误差作为损失函数。

              均方误差在20世纪80年代和90年代流行,后来逐渐被交叉熵代替。交叉熵大大提高了sigmoid输出单元和softmax输出单元的模型的性能。

            • 使用分段线性隐单元(如修正线性单元)来代替sigmoid隐单元。

          1. 修正线性单元描述了生物神经元的这些特性:

            • 对于某些输入,生物神经元是完全不活跃的。
            • 对于某些输入,生物神经元的输出和输入成比例。
            • 大多数时间,生物神经元位于不活跃的状态。
          2. 2006-2012年,人们普遍认为:前馈神经网络如果没有其他模型的辅助,则表现不佳。现在已经知道:当具备合适的资源和工程实践,前馈网络表现的非常好。

          3. 前馈网络中基于梯度的学习被用作研究概率模型的工具,它也可以应用于许多其他机器学习任务。

          4. 在 2006年,业内使用无监督学习来支持监督学习;目前更常见的是使用监督学习来支持无监督学习。



          5. 本文福利

            可以在 公众号后台 回复关键词:“ DS 获取大量由我平台编辑精心整理的学习资料,如果觉得有用, 请勿吝啬你的留言和赞哦!


            —— 完 ——



            文章须知

            文章作者:华校专 

            责任编辑:周岩 Logic 破茧

            审核编辑:阿春

            微信编辑:破茧

            本文由『运筹OR帷幄』原创发布

            如需转载请在公众号后台获取转载须知

            原文链接:http://www.huaxiaozhuan.com/深度学习/chapters/1_deep_forward.html





            Python社区是高质量的Python/Django开发社区
            本文地址:http://www.python88.com/topic/118159
             
            623 次点击