神经网络进阶

课程:吴恩达深度学习

神经网络进阶(p47-?)

机器学习基础

  1. 关于训练数据:
    • 我们通常将训练数据分为这几部分:
      • 训练集:更新模型参数。
      • 简单交叉验证集(验证集 dev set):评估训练得到的多种不同模型或者是带着不同参数的同一模型的效果,再根据模型在验证集的效果对模型进行选择和调参(因此可以说验证集也参与了训练),使得模型效果在验证集达到最优,最后选出效果最好的模型。
      • 测试集(对最终所选定的神经网络系统做出无偏估计):对最终筛选出的模型的泛化能力进行评价。测试集最重要的是未知,即用一个学习集之外的数据集来对模型的效果进行评估,看看模型能否给出合适的输出。
    • 划分比例:
      • 少量数据:三七分或六二二原则
      • 大量数据:验证集和测试集占数据总量的比例会趋向于变得更小(因为验证集的目的就是验证不同的算法,检验哪种算法更有效)
    • 数据统一(同一)分布
    • 训练集,验证集,测试集的进一步解释:
      (摘自:https://zhuanlan.zhihu.com/p/48976706)
      • 最终的目的是将训练好的模型部署到真实的环境中,希望训练好的模型能够在真实的数据上得到好的预测效果(希望模型在真实数据上预测的结果误差越小越好)。模型在真实环境中的误差叫做泛化误差,最终目的是希望训练好的模型泛化误差越低越好。
      • 我们希望通过某个信号来了解模型的泛化误差,这样就可以指导我们得到泛化能力更强的模型:
        1. 使用泛化误差本身。泛化误差小的话可以接受,但通常泛化误差可能很大,这时需将部署的模型撤回,重新训练,可能需要部署和训练之间往复很多次,虽然能够更好的指导模型,但成本和效率非常差
        2. 使用模型在数据集上训练的拟合程度来作为评估模型的信号。但是往往获取的数据集并不是完全干净及有代表性:数据集可能很少、数据代表性不够、包含太多噪声或者是被一些无关特征污染,那么模型对训练数据集的拟合程度不能指导泛化误差(拟合的好并不代表模型的泛化误差就小)。
      • 训练集和测试集:更好的方式就是将数据分割成它们两部分。训练集数据训练模型,测试集上的误差作为最终模型在应对现实场景中的泛化误差。可认为此误差即为泛化误差的近似,只需让训练好的模型在测试集上的误差最小即可。
        • 通常将数据集的80%作为训练集,20%作为测试集;
        • 构建模型之前数据集进行划分,防止数据窥探偏误,避免了解太多测试集中的样本特点,防止我们主观挑选有助于测试集数据的模型。
        • 构建模型时需要将数据进行处理,包括一些数据的清洗,数据的特征缩放(标准化或者归一化)…,只需要在训练集上进行这些操作,然后将其在训练集上得到的参数应用到测试集中。
      • 验证集:
        • 神经网络的层数和每层神经网络的神经元个数以及正则化的一些参数等等,我们将这些参数称为超参数。需要调节超参数来使模型泛化能力最强。直接通过模型在测试集上的误差来调节这些参数,可能有模型在测试集上的误差为0但真实场景中使用效果非常差的情况。这一现象叫做信息泄露。不到最后不能将测试集的信息泄露。
        • 好比考试,平时做的题相当于训练集,测试集相当于最终的考试,通过最终的考试来检验最终的学习能力,将测试集信息泄露出去,相当于学生提前知道了考试题目。如果通过测试集来调节模型,相当于学生知道了考试的题目,且学会做这些题,再拿这些题考试,人人都有可能考满分,并没有起到检测学生学习能力的作用。通过测试集来近似泛化误差,也就是通过考试来检验学生的学习能力,由于信息泄露,此时的测试集即考试无任何意义。所以,学习的时候,老师会准备一些小测试来帮助查缺补漏,这些小测试也就是验证集。通过验证集来作为调整模型的依据,这样不至于将测试集中的信息泄露。
      • 将数据划分训练集、验证集和测试集。在训练集上训练模型,在验证集上评估模型,一旦找到的最佳的参数,就在测试集上最后测试一次,测试集上的误差作为泛化误差的近似。关于验证集的划分可以参考测试集的划分。吴恩达老师的视频中,如果当数据量不是很大的时候(万级别以下)的时候将训练集、验证集以及测试集划分为6:2:2;若是数据很大,可以将训练集、验证集、测试集比例调整为98:1:1;但是当可用的数据很少的情况下也可以使用一些高级的方法,比如留出方,K折交叉验证等。
  1. 偏差/方差 (Bias/Variance):
    • 在只有 x 1 , x 2 x_1, x_2 x1,x2两个特征的二维数据集中,我们可以绘制数据,将偏差和方差可视化:
      在这里插入图片描述

    • 诊断算法是否具有高方差:
      假定训练集误差是1%,验证集误差是11%,可以看出,训练集设置得非常好,而验证集设置相对较差,我们可能过度拟合了训练集,验证集并没有充分利用交叉验证集的作用,像这种情况,我们称之为“高方差”。

    • 诊断算法是否具有高偏差:
      假设训练集误差是15%,验证集误差是16%,[假设案例中(最优误差/贝叶斯误差)人数据标注的错误率几乎为0%]算法并没有在训练集中得到很好训练,数据欠拟合,这种算法偏差比较高。相反,它对于验证集产生的结果却是合理的,验证集中的错误率只比训练集的多了1%。

    • 其他例子:
      训练集误差是15%,偏差相当高,但是,验证集错误率达到30%,在这种情况下认为这种算法偏差高,因为它在训练集上结果不理想,而且方差也很高,这是方差偏差都很糟糕的情况。(数据可视化后,出现局部过拟合,局部欠拟合的情况)
      训练集误差是0.5%,验证集误差是1%,用户看到这样的结果会很开心,分类器只有1%的错误率,偏差和方差都很低。
      如果最优误差或贝叶斯误差非常高,比如15%。则对于(训练误差15%,验证误差16%)的分类器,15%的错误率对训练集来说也是非常合理的,偏差不高,方差也非常低。

    • 以上分析的前提都是假设基本误差很小,训练集和验证集数据来自相同分布。

  1. 解决偏差方差问题的思路:
    • 高偏差?
      • 选择新网络:如含有更多隐藏层或者隐藏单元的网络(通常都会有所帮助)
      • 花费更多时间来训练网络
      • 尝试更先进的优化算法
    • 高方差?
      • 采用更多数据(一般无法时刻准备足够多的训练数据或获取更多数据的成本很高)
      • 正则化
  1. 正则化
    • 理解:

      1. 一方面要使得L(w)的取值最小,必然w的绝对值会取到很大,这样模型才能完美拟合训练样本点;另一方面,当w的绝对值很大时,||w||的值又会变得很大,因此为了权衡,只有使得w取值适当,才能保证值取到最优。这样得到的拟合曲线平滑很多,因此具有泛化能力。这就是正则化存在的意义,帮助我们在训练模型的过程中,防止模型过拟合。
      2. 直观上理解:如果正则化λ设置得足够大,权重矩阵w被设置为接近于0的值,直观理解就是把多隐藏单元的权重设为0,于是基本上消除了这些隐藏单元的许多影响。这样大大简化了神经网络使其变成一个很小的网络,小到如同一个逻辑回归单元,可是深度却很大,它会使这个网络从过度拟合的状态更接近高偏差状态。但是λ会存在一个中间值,有一个接近“Just Right”的中间状态。
        直观理解就是 λ 增加到足够大,w会接近于0,实际上不会发生这种情况。我们尝试消除或至少减少许多隐藏单元的影响,最终这个网络会变得更简单,该神经网络的所有隐藏单元依然存在,但是它们的影响变得更小了。神经网络变得更简单了,貌似这样更不容易发生过拟合,因此我不确定这个直觉经验是否有用,不过在编程中执行正则化时,你实际会看到一些方差减少的结果。
    • L2正则化:

      • J ( w , b ) = 1 m ∑ i = 1 m L { y ^ i , y i } + λ 2 m ∥ ω ∥ 2 2 J\left ( w,b \right ) = \frac{1}{m} \sum_{i = 1}^{m}L \left \{ \hat{y}_{i} , y_{i} \right \} + \frac{\lambda }{2m}\left \| \omega \right \|^{2}_{2} J(w,b)=m1i=1mL{y^i,yi}+2mλω22

      • ∥ ω ∥ 2 2 = ∑ j = 1 n x ω j 2 = ω T ω \left \| \omega \right \|^{2}_{2} = \sum_{j = 1}^{n_{x}}\omega^{2}_{j} = \omega^{T}\omega ω22=j=1nxωj2=ωTω

      • 欧几里得范数的平方即为所有 ω \omega ω 参数的平方和。

      • 参数b只是单个数字,相比于参数更多的 ω \omega ω,对高偏差结果影响不大

      • λ \lambda λ 为正则化参数

      • 使用范数实现梯度下降:( ω [ l ] \omega ^{[l]} ω[l]为第l层的所有参数的矩阵)1
        ω [ l ] = ω [ l ] − α [ d ω [ l ] + λ m ω [ l ] ] \omega ^{[l]} = \omega ^{[l]} - \alpha [d\omega^{[l]} + \frac{\lambda}{m}\omega^{[l]} ] ω[l]=ω[l]α[dω[l]+mλω[l]]

    • Dropout正则化(随即失活):

      • 原理:假设神经网络存在过拟合,复制这个神经网络,dropout会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是0.52,这样会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用backprop方法进行训练。
      • 工作流程:(重复操作以下步骤)

        • 恢复被删掉的神经元(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新)
        • 从隐藏层神经元中随机选择设置大小的子集临时删除掉(备份被删除神经元的参数)。
        • 对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)
      • python实现反向随机失活(inverted dropout):构造bool型矩阵d,进行确定概率的随机false,再将d与激活函数a相乘(d与a的规模相同)。最后再将a更新为:a/=keep-prob。最后这一步除法是为了修正弥补a的期望值以及下一层z的期望值

      • 测试阶段,我们不期望输出结果是随机的,如果测试阶段应用dropout函数,预测会受到干扰。Inverted dropout函数在除以keep-prob时可以记住上一步的操作,目的是确保即使在测试阶段不执行dropout来调整数值范围,激活函数的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同。

      • 理解:

        1. 似乎每次迭代后网络变得更小,和使用正则化效果一样。
        2. 对于单个神经元(输入并生成一些有意义的输出)要通过dropout,则该单元不能依靠任何特征,因为特征都有可能被随机清除。我不愿意给任何一个输入加上太多权重,因为它可能会被删除,因此该单元将通过这种方式积极地传播开,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,并完成一些预防过拟合的外层正则化。
      • 具体实施:

        • 可以对某些容易发生过拟合的隐藏层,将其keep-prob参数设置地比其他层更低,缺点是这样就需要在交叉验证时搜索调整更多的超参数
        • 在一些层上应用dropout,而有些层不用dropout,应用dropout的层只含有一个超级参数keep-prob。
    • 其他正则化方法:

      1. 数据扩增:一般扩增训练数据来解决过拟合,代价高,而且有时候无法扩增数据,但我们可以通过添加这类图片来增加训练集。例如随意翻转3和裁剪图片,增大数据集,额外生成假训练数据。和全新的,独立的图片数据相比,这些额外的假的数据无法包含像全新数据那么多的信息,但代价几乎为零。以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。
      1. early stopping:
        • 缺点:提早停止梯度下降,停止了优化代价函数J,J的值可能不够小,同时又希望不出现过拟合,没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题。
        • 优点:只运行一次梯度下降,可以找出w的较小值,中间值和较大值,而无需尝试L2 正则化超级参数 λ \lambda λ的很多值。
  1. 归一化输入
    训练神经网络,其中一个加速训练的方法就是归一化输入,当输入特征各自的范围差距较大(x1:1-1000, x2:0-1),归一化特征值很有必要。假设一个训练集有两个特征,输入特征为2维(x1,x2),归一化需要两个步骤:

    • 零均值化:
      μ = 1 m ∑ i = 1 m x ( i ) \mu = \frac{1}{m}\sum_{i=1}^{m}x^{(i)} μ=m1i=1mx(i)
      μ \mu μ是一个向量, x等于每个训练数据x减 μ \mu μ,意思是移动训练集,直到它完成零均值化4
    • 归一化方差:
      σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 \sigma^{2} = \frac{1}{m}\sum_{i=1}^{m}(x^{(i)})^{2} σ2=m1i=1m(x(i))2
      再把所有的数据除以向量 σ 2 \sigma^{2} σ2(我觉得老师这里写错了?应该是标准差 σ \sigma σ)使得数据x1和x2这两个维度的方差均为1。

在这里插入图片描述

在这里插入图片描述

  • 注意:用相同的均值和方差归一化训练集和测试集
  • (当数据有两个维度的特征时)归一化特征后,代价函数是一个更圆的球形轮廓,平均起来看更对称,不论从哪个位置开始,梯度下降法都能够更直接地找到最小值,可以在梯度下降法中使用较大步长,而不需要在没有进行归一化的代价函数中使用很小的步长反复执行。
  1. 梯度消失与梯度爆炸:
    在深度神经网络中(层数L大):假设每个权重矩阵初始设置值比1大/小,b=0,激活函数为线性激活函数,则 y ^ \hat{y} y^非常大/小
  1. 神经网络权重初始化:给出上述6的解决方案

    • 设置某层权重矩阵:5
      w [ l ] = n p . r a n d o m . r a n d n ( s h a p e ) ∗ n p . s q r t ( 1 n [ l − 1 ] ) w^{[l]} = np.random.randn(shape) * np.sqrt(\frac{1}{n^{[l-1]}}) w[l]=np.random.randn(shape)np.sqrt(n[l1]1)
      l层上的每个神经元都有 n [ l − 1 ] n^{[l-1]} n[l1]个输入,这些输入特征被零均值和标准方差化,z也调整到相似范围,这样做降低了梯度消失与爆炸问题
    • 网络使用ReLU激活函数: 方差设置为 2 n [ l − 1 ] \frac{2}{n^{[l-1]}} n[l1]2(也即乘上 n p . s q r t ( 2 n [ l − 1 ] ) np.sqrt(\frac{2}{n^{[l-1]}}) np.sqrt(n[l1]2))效果更好。
    • 网络使用tanh激活函数:方差就设置为 1 n [ l − 1 ] \frac{1}{n^{[l-1]}} n[l1]1 2 n [ l − 1 ] + n [ l ] \frac{2}{n^{[l-1]} + n^{[l]}} n[l1]+n[l]2
  1. 梯度检验
    • 方法:把所有网络参数(w1,b1,w2,b2…)链接成巨型向量 θ = ( θ 1... ) \theta = (\theta1...) θ=(θ1...),同样的把对应的dw和db连接成 d θ d\theta dθ,再利用双边导数定义式,循环执行 d θ a p p r o x [ i ] = J ( θ 1 , θ 2 , . . . θ i + ϵ . . . ) − J ( θ 1 , θ 2 , . . . θ i − ϵ . . . ) 2 ϵ d\theta_{approx[i]} = \frac{J(\theta_{1},\theta_{2},...\theta_{i}+\epsilon...) - J(\theta_{1},\theta_{2},...\theta_{i}-\epsilon...)}{2\epsilon} dθapprox[i]=2ϵJ(θ1,θ2,...θi+ϵ...)J(θ1,θ2,...θiϵ...)得到 d θ a p p r o x d\theta_{approx} dθapprox,与求偏导得到的 d θ i d\theta_{i} dθi对比验证(二者应该非常接近)
    • 注意事项:
      1. 不在训练中使用梯度检验,只用于调试。
      2. 如果算法的梯度检验失败,要检查所有项。
      3. 实施梯度检验时,如果使用正则化,请注意正则项。
      4. 梯度检验不能与dropout同时使用,因为每次迭代过程中,dropout会随机消除隐藏层单元的不同子集,难以计算dropout在梯度下降上的代价函数J。

优化算法

  1. Mini-batch 梯度下降
  • 当样本m过大时,可以将训练集分为小一点的子集训练,这些子集称为mini-batch;使用mini-batch梯度下降法,一次遍历训练集,能做样本总数/mini-batch个梯度下降,多次遍历训练集,还需要另设置一组循环(epoch)。
  • 规定符号 x ( i ) , z [ l ] , X t x^{(i)}, z^[l], X^{{t}} x(i),z[l],Xt分别表示第i个训练样本,第l层的z值,第t个(含有一定数量样本的)训练集(子集)
  • 对比理解:
    • batch梯度下降法: 每次迭代需要历遍整个训练集,可以预期每次迭代成本都会下降,如果J在某次迭代中增加了,那肯定出了问题,也许学习率太大。

    • mini-batch梯度下降: 成本函数J会有噪声,但整体呈下降趋势。
      在这里插入图片描述

      • 当mini-batch = m, 即为batch梯度下降法。如上图从某处开始,相对噪声低些,幅度也大一些,可以寻找最小值
      • 当mini-batch = 1, 为随机梯度下降法。从某一点开始,重新选取一个起始点,每次迭代,只对一个样本进行梯度下降,大部分时候你向着全局最小值靠近,有时候你会远离最小值,因为那个样本恰好给你指的方向不对,因此随机梯度下降法有很多噪声,平均来看,它最终会靠近最小值,不过有时候也会方向错误,因为随机梯度下降法永远不会收敛,而是会一直在最小值附近波动,但它并不会在达到最小值并停留在此。
        随机梯度下降法的一大缺点是,会失去所有向量化带给你的加速,因为一次性只处理了一个训练样本,这样效率过于低下,所以实践中最好选择不大不小的mini-batch尺寸,实际上学习率达到最快。一方面得到了大量向量化,另一方面,不需要等待整个训练集被处理完就可以开始进行后续工作,用一下上个视频的数字,每次训练集允许我们采取5000个梯度下降步骤,实际上一些位于中间的mini-batch大小效果最好。
      • mini-batch梯度下降法: 它不会总朝向最小值靠近,但它比随机梯度下降要更持续地靠近最小值的方向,它也不一定在很小的范围内收敛或者波动,如果出现这个问题,可以慢慢减少学习率。
        mini-batch大小选择有指导原则: 首先,如果训练集较小,直接使用batch梯度下降法,可以快速处理整个训练集,这里的少是指小于2000个样本。样本数目较大,一般mini-batch大小为64到512,考虑到电脑内存设置和使用的方式,如果mini-batch大小是2的n次方,代码会运行地快一些。最后需要注意,mini-batch中,要确保 X t , Y t X^{{t}}, Y^{{t}} Xt,Yt符合CPU/GPU内存,取决于你的应用方向以及训练集的大小。如果处理的mini-batch和CPU/GPU内存不相符,不管用什么方法处理数据,算法的表现急转直下惨不忍睹。
  1. 指数加权(移动)平均:一种近似求平均的放法
    以吴恩达老师给出的气温图引入:
    在这里插入图片描述
  • 公式: v t = β v t − 1 + ( 1 − β ) θ t v_{t} = \beta v_{t-1} + (1 - \beta)\theta_{t} vt=βvt1+(1β)θt

  • 公式解释:到第t天的平均温度等于β倍上一天温度加1-β倍当天温度值。

  • β = 0.9 \beta=0.9 β=0.9 的时候,得到的结果是红线,如果它更接近于1,比如0.98,结果就是绿线,如果 β \beta β 小一点,如0.5,结果就是黄线。

  • 将公式展开,有:
    v t = ( 1 − β ) θ t + ( 1 − β ) β θ t − 1 + ( 1 − β ) β 2 θ t − 2 + . . . v_{t} = (1-\beta)\theta_{t} + (1-\beta)\beta\theta_{t-1} + (1-\beta)\beta^{2}\theta_{t-2} + ... vt=(1β)θt+(1β)βθt1+(1β)β2θt2+...
    判断该算法到底平均了大约多少天的温度:天数 = 1 1 − β \frac{1}{1-\beta} 1β1, 这时 β 1 1 − β \beta^{\frac{1}{1-\beta}} β1β1 约等于 1 e \frac{1}{e} e1

  • 相比一般的平均算法,其优点:

    • 再写公式为: v = β v + ( 1 − β ) θ t v = \beta v + (1 - \beta)\theta_{t} v=βv+(1β)θt6
    • 占用极少内存,公式使用时把最新数据代入,不断覆盖即可,当然它并不是最好的,也不是最精准的计算平均数的方法。一般的平均值计算会保存所有最近的温度数据,必须占用更多的内存,执行更加复杂,计算成本也更加高昂。
  • 偏差修正:帮助指数加权平均方法在早期获得更为精确的估测

    • 早期偏差原因:由于v的初始值为0, v 1 = ( 1 − β ) θ 1 v_{1} = (1 - \beta)\theta_{1} v1=(1β)θ1,v1值很小,进而影响前期几个连续的v值较实际值小。
    • 做法:在估测初期得到 v t v_{t} vt后,再令 v t 1 − β t \frac{v_{t}}{1 - \beta^{t}} 1βtvt得到最终修正后的结果
  1. 动量梯度下降法(Gradient Descent with Momentum)
    以下图成本函数形状为例:
    在这里插入图片描述
  • 分析:在纵轴上,希望学习慢一点(不想要这些摆动),但是在横轴上希望加快学习(快速从左向右移向最小值),所以使用动量梯度下降法。

  • 解释:纵轴上的摆动平均值接近于零,所以在纵轴方向,你希望放慢一点,平均过程中,正负数相互抵消,所以平均值接近于零。但在横轴方向,所有的微分都指向横轴方向,因此横轴方向的平均值仍然较大,因此用算法几次迭代后,你发现动量梯度下降法,最终纵轴方向的摆动变小了,横轴方向运动更快,因此你的算法走了一条更加直接的路径,在抵达最小值的路上减少了摆动。

  • 从物理意义理解:想象有一个碗,你拿一个球,微分项相当于这个球的加速度, v d W / d b v_{dW/db} vdW/db相当于速度, α \alpha α相当于时间。此时球正向下滚,球因为加速度越滚越快,而因为 β \beta β稍小于1,表现出一些摩擦力,(微分项接近于零时 v d W / d b v_{dW/db} vdW/db会越来越小接近于零)所以球不会无限加速下去。所以不像梯度下降法,每一步都独立于之前的步骤。

  • 做法:将梯度下降更改为:7
    W = W − α v d W , b = b − α v d b W = W - \alpha v_{dW}, b = b - \alpha v_{db} W=WαvdW,b=bαvdb
    v d W = β v d W + ( 1 − β ) d W , v d b = β v d b + ( 1 − β ) d b v_{dW} = \beta v_{dW} + (1 - \beta)dW , v_{db} = \beta v_{db} + (1 - \beta)db vdW=βvdW+(1β)dW,vdb=βvdb+(1β)db

  1. RMSprop(Root Mean Square Rrop)
    在这里插入图片描述
  • 与前例相同,执行梯度下降,虽然横轴方向正在推进,但纵轴方向会有大幅度摆动,为了分析这个例子,假设纵轴代表参数b,横轴代表参数W(可能有W1,W2等,为了便于理解,我们只用b和W)8
  • 做法:9
    S d W = β S d W + ( 1 − β ) ( d W ) 2 , S d b = β S d b + ( 1 − β ) ( d b ) 2 S_{dW} = \beta S_{dW} + (1 - \beta)(dW)^{2}, S_{db} = \beta S_{db} + (1 - \beta)(db)^{2} SdW=βSdW+(1β)(dW)2,Sdb=βSdb+(1β)(db)2
    W = W − α d W S d W , b = b − α d b S d b W = W - \alpha \frac{dW}{\sqrt{S_{dW}}}, b = b - \alpha \frac{db}{\sqrt{S_{db}}} W=WαSdW dW,b=bαSdb db
  • 理解:
    • 在横轴方向W方向,我们希望学习速度快,而在垂直方向b方向,我们希望减缓纵轴上的摆动,又已知:db较大(反映到图上即为每一步的纵方向跨度大)而dW较小
    • 所以我们要在b的更新中除以较大的数字,这样就可以减缓纵轴上的变化。
  • 产生的影响:
    • 纵轴上垂直方向偏离变小。
    • 可以用一个更大学习率 α \alpha α ,然后加快学习速度。
  1. Adam优化算法(Adaptive Moment Estimation)
  • 基本上是Momentum与RMSprop的结合, 被证明能有效适用于不同神经网络,适用于广泛的结构。
  • 做法:
    V d W = 0 , S d W = 0 , V d b = 0 , S d W = 0 V_{dW} = 0, S_{dW} = 0, V_{db} = 0, S_{dW} = 0 VdW=0,SdW=0,Vdb=0,SdW=0
    On iteration t:(在第t次迭代中):
    V d W = β 1 + ( 1 − β 1 ) d W , V d b = β 1 + ( 1 − β 1 ) d b V_{dW} = \beta_{1} + (1 - \beta_{1})dW, V_{db} = \beta_{1} + (1 - \beta_{1})db VdW=β1+(1β1)dW,Vdb=β1+(1β1)db
    d W = β 2 + ( 1 − β 2 ) ( d W ) 2 , S d b = β 2 + ( 1 − β 2 ) ( d b ) 2 _{dW} = \beta_{2} + (1 - \beta_{2})(dW)^{2}, S_{db} = \beta_{2} + (1 - \beta_{2})(db)^{2} dW=β2+(1β2)(dW)2,Sdb=β2+(1β2)(db)2
    V d W c o r r e c t e d = V d W ( 1 − β 1 t ) , V d b c o r r e c t e d = V d b ( 1 − β 1 t ) V_{dW}^{corrected} = \frac{V_{dW}}{(1 - \beta_{1}^{t})}, V_{db}^{corrected} = \frac{V_{db}}{(1 - \beta_{1}^{t})} VdWcorrected=(1β1t)VdW,Vdbcorrected=(1β1t)Vdb
    S d W c o r r e c t e d = S d W ( 1 − β 2 t ) , S d b c o r r e c t e d = S d b ( 1 − β 2 t ) S_{dW}^{corrected} = \frac{S_{dW}}{(1 - \beta_{2}^{t})}, S_{db}^{corrected} = \frac{S_{db}}{(1 - \beta_{2}^{t})} SdWcorrected=(1β2t)SdW,Sdbcorrected=(1β2t)Sdb
    W = W − α V d W c o r r e c t e d S d W c o r r e c t e d + ϵ , b = b − α V d b c o r r e c t e d S d b c o r r e c t e d + ϵ W = W - \alpha \frac{V_{dW}^{corrected}}{\sqrt{S_{dW}^{corrected}} + \epsilon}, b = b - \alpha \frac{V_{db}^{corrected}}{\sqrt{S_{db}^{corrected}} + \epsilon} W=WαSdWcorrected +ϵVdWcorrected,b=bαSdbcorrected +ϵVdbcorrected
  • 超参数:
    • α \alpha α: needs to be tuned
    • β 1 \beta_{1} β1: 0.9
    • β 2 \beta_{2} β2: 0.999
    • ϵ \epsilon ϵ: 1 0 − 8 10^{-8} 108
  1. 学习率衰减
    在这里插入图片描述
  • 背景解释: 使用mini-batch梯度下降法时(mini-batch数量不大,大概64或者128个样本)在迭代过程中会有噪音(蓝色线),下降朝向最小值,但是不会精确地收敛,算法最后在其附近摆动,并不会真正收敛,因为 α \alpha α是固定值,若能随着迭代次数的增加不断减小学习率,最后摆动收敛的范围会更小,这样更好。
  • 做法:
    1. α = 1 1 + d e c a y − r a t e ∗ e p o c h n u m α 0 \alpha = \frac{1}{1 + decay-rate * epoch_num}\alpha_{0} α=1+decayrateepochnum1α0 10
  1. 对于局部最优的困惑
    在这里插入图片描述
    这是曾经人们在想到局部最优时脑海里会出现的图,也许你想优化一些参数,我们把它们称之为W1和W2,平面的高度就是损失函数。在图中似乎各处都分布着局部最优。梯度下降法或者某个算法可能困在一个局部最优中,而不会抵达全局最优。这些低维的图曾经影响了我们的理解,这些理解并不正确。事实上,如果你要创建一个神经网络,通常梯度为零的点并不是这个图中的局部最优点,实际上成本函数的零梯度点,通常是鞍点。
    在这里插入图片描述
    一个具有高维度空间的函数,如果梯度为0,那么在每个方向,它可能是凸函数,也可能是凹函数。如果在2万维空间中,那么想要得到局部最优,所有的2万个方向都需要是凹函数形状,但发生的机率也许很小,也许是 2 − 20000 2^{-20000} 220000,更有可能遇到有些方向的曲线会向上弯曲,另一些方向曲线向下弯,而不是所有的都向上弯曲,因此在高维度空间,更可能碰到鞍点。

局部最优一般不是问题,但是平稳段会减缓学习,平稳段是一块导数长时间接近于0的区域,花上很长时间慢慢抵达平稳段的这个点后,左边或右边的随机扰动,才可使算法能够走出平稳段。Momentum或是RMSprop,Adam这样的算法在这些平稳段情况下,能够加快速度,尽早往下走出平稳段。


超参数调整

  1. 对几个超参数重要性的认识:
    • 学习速率 α \alpha α
    • β \beta β(momentum), 隐藏层的单元数, mini-batch size
    • 层数, 学习率衰减因子
    • β 1 , β 2 , ϵ \beta_{1}, \beta_{2}, \epsilon β1,β2,ϵ,一般取0.9, 0.999, 1 0 − 8 10^{-8} 108不变
  1. 超参数调试值选择:
    • 网格法(从物理角度直观去看,我更愿意概括为坐标系法):
      • 如果有n个超参数需要调优,(对于深度学习领域,可以这样做:)建立n维坐标系,坐标系的每个轴即表示需要调试的参数,然后随机选择点11,并对这些点进行效果检验。
    • 超参数取值的合理范围(坐标系法中各个轴所代表参数的取值范围确定)
      • 一些超参数可以在一定范围内均匀取值:对于隐藏单元数量,可以在[50,100]之间均匀取值;神经网络层数考虑范围为[2,4],那么可以取2,3,4。
      • 使用对数标尺(不再使用线性轴):若学习速率 α \alpha α的考虑范围为[0.0001,1],(均匀取值则90%的数值都落在[0.1,1]之间,这样并不合适。在某些情况,某个区间精度要求很高,极小的差距就会对最终结果有很大影响)应该分别取0.0001,0.001,0.01,0.1,1几个特殊点,在对数轴上均匀取值。
        • 一种更容易的操作方法:在 [ 1 0 a , 1 0 b ] [10^{a}, 10^{b}] [10a,10b]取值,则在r ∈ \in [a,b]区间均匀随机取值。
        • python实现:
        a = -4
        b = 0
        r = -4*np.random.rand() 
        
  1. 搜索超参数:

    1. “熊猫方式”:照看一个模型,通常是有庞大的数据组,但没有许多计算资源或足够的CPU和GPU的前提下,只可以一次负担起试验一个模型或一小批模型,在这种情况下,即使当它在试验时,你也可以逐渐改良。比如,第0天,你将随机参数初始化,然后开始试验,然后你逐渐观察自己的学习曲线,也许是损失函数 J ,或者数据设置误差或其它的东西,在第1天内逐渐减少,那这一天末的时候,试着增加一点学习速率,看看它会怎样,也许结果证明它做得更好,那是你第二天的表现。两天后,它依旧做得不错,也许可以填充下Momentum或减少变量。然后进入第三天,每天,你都会观察它,不断调整你的参数。也许有一天,你会发现你的学习率太大了,所以你可能又回归之前的模型,像这样每天花时间照看此模型。所以这是一个人们照料一个模型的方法,观察它的表现,耐心地调试学习率。
    2. “鱼子酱方式”:同时试验多种模型:设置一些超参数,运行一天甚至多天后获得对应学习曲线,这可以是损失函数J或实验误差或损失或数据误差的损失,但都是你曲线轨迹的度量。同时你可以开始一个有着不同超参数设定的不同模型,所以,你的第二个模型会生成一个不同的学习曲线。与此同时,你可以试验第三种模型等等。或者你可以同时平行试验许多不同的模型。用这种方式可以试验许多不同的参数设定,然后只是最后快速选择工作效果最好的那个。
  2. 标准化11网络的激活函数 (Normalizing Activations in a Network)/Batch Normalization 批标准化


softmax多元分类

在这里插入图片描述

  1. softmax输出:

    • 做法:神经网络最后一层采用softmax激活函数
      z [ l ] = W [ l ] a [ l − 1 ] + b [ l ] z^{[l]} = W^{[l]}a^{[l-1]} + b^{[l]} z[l]=W[l]a[l1]+b[l]
      t = e z [ l ] , a [ l ] = e z [ l ] ∑ i = 1 4 t i t = e^{z^{[l]}}, a^{[l]} = \frac{e^{z^{[l]}}}{\sum_{i = 1}^{4}t_{i}} t=ez[l],a[l]=i=14tiez[l]
    • 公式解释:
      • z [ l ] , a [ l ] z^{[l]}, a^{[l]} z[l],a[l]此时为 4 × 1 4 \times 1 4×1的向量,临时变量t也为 4 × 1 4 \times 1 4×1的向量, t i t_{i} ti表示t向量中的第i个数值。最后一个公式,也即 a [ l ] a^{[l]} a[l]的输出,相当于就是对t进行了归一化。当样本数为m时,输出矩阵shape为 4 × m 4 \times m 4×m
    • 在网络没有隐藏层(输入层的下一层即为softmax输出层时),这个简单网络仍可以实现分类,但决策边界为线性。如下图:
      在这里插入图片描述
  2. 训练带有softmax输出层的网络:(仍以最上方的图片为例说明)

    • 单个样本的损失函数: L ( y ^ , y ) = − ∑ j = 1 4 y j l o g y j ^ L(\hat{y}, y) = -\sum_{j = 1}^{4} y_{j}log\hat{y_{j}} L(y^,y)=j=14yjlogyj^
    • y y y 4 × 1 4 \times 1 4×1的向量,表示样本的标签(向量中的每个值可能为1或者0),上述的损失函数实际上变成了 L ( y ^ , y ) = − l o g y 某个 j ^ L(\hat{y}, y) = -log\hat{y_{某个j}} L(y^,y)=logy某个j^
    • 整个训练集的损失函数 J = 1 m ∑ j = 1 m L ( y ^ ( j ) , y ( j ) ) J = \frac{1}{m}\sum_{j = 1}^{m}L(\hat{y}^{(j)}, y^{(j)}) J=m1j=1mL(y^(j),y(j))

  1. 系数 1 − α λ m 1-\alpha\frac{\lambda}{m} 1αmλ小于1,因此L2范数正则化被称为“权重衰减” ↩︎

  2. keep-prob称为保留某个隐藏单元的概率,此例中为0.5。对于不同隐藏层可以设置不同keep-prob参数大小 ↩︎

  3. 一般不想上下颠倒图片? ↩︎

  4. x ( i ) x^{(i)} x(i)表示第i个训练数据 ↩︎

  5. n [ l − 1 ] n^{[l-1]} n[l1]为输入到第l层神经单元的数据数量,np.random.randn(shape)返回一个或一组指定维度的样本,具有标准正态分布 ↩︎

  6. 注意v的初始值为0 ↩︎

  7. 一般 β \beta β取0.9,且不需要考虑偏差修正,因为10次迭代之后,移动平均已经过了初始阶段。 ↩︎

  8. 实际中,你会处于参数的高维度空间,所以需要消除摆动的垂直维度,实际上可能是某几个参数的合集。实际中dW是一个高维度的参数向量,db也是一个高维度参数向量,但是你的直觉是,在你要消除摆动的维度中,最终会计算出一个更大的和值,这个微分平方和的加权平均值。这就是RMSprop,全称是均方根,因为你将微分进行平方,然后最后使用平方根。 ↩︎

  9. 为避免与momentum混淆,之后将此处 β \beta β更换为 β 2 \beta_{2} β2;同时要确保算法不会除以0,这样就要求在分母上加一个 ϵ \epsilon ϵ(就是在根号那一项后面直接加),10^{-8}就很不错。 ↩︎

  10. decay-rate称为衰减率,epoch-num为代数(第一次遍历训练集叫做第一代,以此类推) α 0 \alpha_{0} α0为初始学习率,注意这个衰减率是另一个你需要调整的超参数
    2. α = ( 小于 1 的值 ) e p o c h n u m α 0 \alpha = (小于1的值)^{epoch_num}\alpha_{0} α=(小于1的值)epochnumα0
    3. α = k e p o c h n u m α 0 \alpha = \frac{k}{\sqrt{epoch_num}}\alpha_{0} α=epochnum kα0
    4. 离散下降… ↩︎

  11. 由于很难提前知道哪个超参数最重要,故采用随机。
    - 或许在这样的n维空间中,有部分区域的点对应的效果比较好,那么对这片区域进行放大,更细致密集地进行取点。
    - 关键字总结: 随机取值,由粗糙到精细的搜索。 ↩︎ ↩︎

  12. 这里的 γ , β \gamma,\beta γ,β理解为向量(实际上就是 γ [ l ] \gamma^{[l]} γ[l], β [ l ] \beta^{[l]} β[l]),这样可以使某一层的不同隐藏单元学习获得不同的分布;同时这里的 β \beta β不是超参数,不要与前面优化算法中提到的 β \beta β混淆;这两个新的参数可以用之前提到的任一优化算法执行(梯度下降,Adam…)。
    4. 得到 z ~ n o r m [ l ] \tilde{z}^{[l]}_{norm} z~norm[l]后,再通过激活函数计算出 a [ l ] a^{[l]} a[l]
    5. 最后补充说明:实际上运用BN时可以去掉线性函数中的 b b b参数(为0),因为 β \beta β最终会学习一个合理的值(均值)。
    - 理解:
    - 直观解释:每一层的权重参数训练好后,更能经受得住“输入变化”
    - "Covariate shift"问题:已经学习了x到y的映射,如果x的分布改变了,那么可能需要重新训练学习算法。
    - 深度网络就会有上述这样的问题:对于一中间位置的隐藏层,前面层的权重参数不断变化会影响该中间位置隐藏层的“输入”。
    - 对该中间隐藏层使用BN后,可以保证无论前面怎么变化,该层的z的均值和方差不变,进而使后层的学习有更坚实的基础。
    - BN减弱了前层参数的作用与后层参数的作用之间的联系,它使得网络每层都可以自己学习,稍稍独立于其它层,这有助于加速整个网络的学习。
    - BN还有轻微的正则化效果:对于每个mini-batch,由于是部分样本,据此每个batch计算出的均值方差会略有不同,进一步使每个隐藏层的激活值上增加了噪音,这使后部单元不过分依赖任何一个隐藏单元,类似于dropout,因此有轻微的正则化效果。因为添加的噪音很微小,所以并不是很大的正则化效果。应用较大的mini-batch可以减少正则化效果。(如果想得到强大的正则化效果,可以将BN和dropout一起使用)
    - 测试过程中进行单个样本的预测时,如何得到BN操作过程中的 μ , σ 2 \mu, \sigma^{2} μ,σ2
    - 首先明确,一个样本的均值和方差没有意义。
    - 理论上可以在最终的网络中运行整个训练集来得到这两个参数。
    - 实际中为了将神经网络运用于测试,就需要在训练过程中,采用指数加权平均估算 μ , σ 2 \mu, \sigma^{2} μ,σ2(追踪最新均值),训练完成后得到最终的 μ , σ 2 \mu, \sigma^{2} μ,σ2值用于预测。 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值