🎨
Bible-DeepLearning
  • Introduction
  • 第6章 深度前馈网络
    • 6.1 例子:学习XOR
    • 6.2 基于梯度的学习
      • 6.2.1 代价函数
        • 6.2.1.1 使用最大似然学习条件分布
        • 6.2.1.2 学习条件统计量
      • 6.2.2 输出单元
        • 6.2.2.1 用于高斯输出分布的线性神单元
        • 6.2.2.2 用于Bernoulli输出分布的sigmoid单元
        • 6.2.2.3 用于Multinoulli输出分布的softmax单元
    • 6.3 隐藏单元
      • 6.3.1 ReLU及其扩展
      • 6.3.2 logistic sigmoid与双曲正切函数
      • 6.3.3 其他隐藏单元
      • 李宏毅补充 SELU
    • 6.4 架构设计
    • 6.5 反向传播和其他的微分算法
      • 6.5.1 计算图
      • 6.5.2 微积分中的链式法则
      • 6.5.3 递归地使用链式法则来实现反向传播
      • 6.5.4 全连接MLP中的反向传播计算
      • 6.5.5 符号到符号的导数
      • 6.5.6 一般化的反向传播
      • 6.5.7 实例:用于MLP 训练的反向传播
      • 6.5.8 复杂化
  • 第7章 深度学习中的正则化
    • 7.1 参数范数惩罚
      • 7.1.1 L2参数正则化
      • 7.1.2 L1参数正则化
    • 7.2 作为约束的范数惩罚
    • 7.3 正则化和欠约束问题
    • 7.4 数据集增强
    • 7.5 噪声鲁棒性
    • 7.6 半监督学习
    • 7.7 多任务学习
    • 7.8 提前终止
    • 7.9 参数绑定和参数共享
    • 7.10 稀疏表示
    • 7.11 Bagging 和其他集成方法
    • 7.12 Dropout
    • 7.13 对抗训练
    • 7.14 切面距离、正切传播和流形正切分类器
    • Ag补充 一些能用于提升比赛成绩的方法
  • 第8章 深度模型中的优化
    • 8.1 学习和纯优化有什么不同
      • 8.1.1 经验风险最小化
      • 8.1.2 代理损失函数和提前终止
      • 8.1.3 批量算法和小批量算法
    • 8.2 神经网络优化中的挑战
      • 8.2.1 病态
      • 8.2.2 局部极小值
      • 8.2.3 8.2.3 高原、鞍点和其他平坦区域
      • 8.2.4 悬崖和梯度爆炸
      • 8.2.5 长期依赖
      • 8.2.6 非精确梯度
    • 8.3 基本算法
      • 8.3.1 随机梯度下降
      • 8.3.2 动量
      • 8.3.3 Nesterov 动量
    • 8.4 参数初始化策略
    • 8.5 自适应学习率算法
      • 8.5.1 AdaGrad
      • 8.5.2 RMSProp
      • 8.5.3 Adam
      • 8.5.4 选择正确的优化算法
    • 8.6 二阶近似方法
      • 8.6.1 牛顿法
      • 8.6.2 共轭梯度
      • 8.6.3 BFGS
    • 8.7 优化策略和元算法
      • 8.7.1 批标准化
      • 8.7.2 坐标下降
      • 8.7.3 Polyak 平均
      • 8.7.4 监督预训练
      • 8.7.5 设计有助于优化的模型
  • 第9章 卷积网络
    • 9.1 卷积运算
    • 9.2 动机
    • 9.3 池化
    • 9.4 卷积与池化作为一种无限强的先验
    • 9.5 基本卷积函数的变体
    • 9.6 结构化输出
    • 9.7 数据类型
  • 第10章 序列建模:循环和递归网络
    • 10.1 展开计算图
    • 10.2 循环神经网络
      • 10.2.1 导师驱动过程和输出循环网络
      • 10.2.2 计算循环神经网络的梯度
      • 10.2.3 作为有向图模型的循环网络
      • 10.2.4 基于上下文的RNN序列建模
    • 10.3 双向RNN
    • 10.4 基于编码 - 解码的序列到序列架构
    • 10.5 深度循环网络
    • 10.6 递归神经网络
    • 10.7 长期依赖的挑战
    • 10.9 渗漏单元和其他多时间尺度的策略
    • 10.10 长短期记忆和其他门控RNN
      • 10.10.1 LSTM
      • 10.10.2 其他门控RNN
    • 10.11 优化长期依赖
      • 10.11.1 梯度截断
      • 10.11.2 引导信息流的正则化
    • 10.12 外显记忆
  • 第11章 实践方法论
    • 11.1 性能度量
    • 11.2 默认的基准模型
    • 11.3 决定是否收集更多数据
    • 11.4 选择超参数
      • 11.4.1 手动选择超参数
      • 11.4.3 网络搜索
      • 11.4.4 随机搜索
    • 11.5 调试策略
Powered by GitBook
On this page
  • 非常深的网络存在的问题
  • 引入批标准化方法
  • 训练阶段
  • 测试阶段
  • 效果
  • 优点:更易学习
  • 缺点:底层网络没有用
  • 批标准化的改进

Was this helpful?

  1. 第8章 深度模型中的优化
  2. 8.7 优化策略和元算法

8.7.1 批标准化

Previous8.7 优化策略和元算法Next8.7.2 坐标下降

Last updated 4 years ago

Was this helpful?

批标准化~{cite?}是优化深度神经网络中最激动人心的最新创新之一。 实际上它并不是一个优化算法,而是一个自适应的重参数化的方法,试图解决训练非常深的模型的困难。

非常深的网络存在的问题

非常深的模型会涉及多个函数或层组合。 在其他层不改变的假设下,梯度用于如何更新每一个参数。 在实践中,我们同时更新所有层。

[success] w更新算法是在假设其它层w不变的情况下计算某一层的$\Delta w$的。 但实际上所有w会同时更新。 相邻层之间w的相互作用对最终结果有比较大的影响。

当我们进行更新时,可能会发生一些意想不到的结果,这是因为许多组合在一起的函数同时改变时,计算更新的假设是其他函数保持不变。 举一个简单的例子,假设我们有一个深度神经网络,每一层只有一个单元,并且在每个隐藏层不使用激活函数:$\hat{y} = xw1 w_2 w_3 \cdots w_l$。 此处,$w_i$表示用于层$i$的权重。层$i$的输出是$h_i = h{i-1} wi$。 输出$\hat{y}$是输入$x$的线性函数,但是权重$w_i$的非线性函数。 假设我们的代价函数 $\hat{y}$上的梯度为$1$,所以我们希望稍稍降低$\hat{y}$。 然后反向传播算法可以计算梯度$g = \nabla{w} \hat{y}$。 想想我们在更新$w \leftarrow w - \epsilon g$时会发生什么。 近似$\hat{y}$的一阶泰勒级数会预测$\hat{y}$的值下降$\epsilon g^\top g$。 如果我们希望$\hat{y}$下降$0.1$,那么梯度中的一阶信息表明我们应设置学习率$\epsilon$为$\frac{0.1}{g^\top g}$。 然而,实际的更新将包括二阶,三阶,直到$l$阶的影响。 $\hat{y}$的更新值为

x(w1−ϵg1)(w2−ϵg2)⋯(wl−ϵgl),\begin{aligned} x(w_1-\epsilon g_1)(w_2-\epsilon g_2)\cdots(w_l-\epsilon g_l), \end{aligned}x(w1​−ϵg1​)(w2​−ϵg2​)⋯(wl​−ϵgl​),​

这个更新中所产生的一个二阶项示例是$\epsilon^2 g1 g_2 \prod{i=3}^l wi$ 。 如果 $\prod{i=3}^l w_i$很小,那么该项可以忽略不计。而如果层$3$到层$l$的权重都比$1$大时,该项可能会指数级大。 这使得我们很难选择一个合适的学习率,因为某一层中参数更新的效果很大程度上取决于其他所有层。 二阶优化算法通过考虑二阶相互影响来解决这个问题,但我们可以看到,在非常深的网络中,更高阶的相互影响会很显著。 即使是二阶优化算法,计算代价也很高,并且通常需要大量近似,以免真正计算所有的重要二阶相互作用。 因此对于$n>2$的情况,建立$n$阶优化算法似乎是无望的。 那么我们可以做些什么呢?

引入批标准化方法

[success] 标准化 根据算法的过程应该是标准化,中文翻译也确实是标准化,但是英文用的却是Normalize,挺奇怪的。

批标准化提出了一种几乎可以重参数化所有深度网络的优雅方法。 重参数化显著减少了多层之间协调更新的问题。 批标准化可应用于网络的任何输入层或隐藏层。

[success] BN用于输入层,即对X做标准化。 BN用于隐藏层,即对每一层的a或者z分别做标准化。

设$H$是需要标准化的某层的小批量激活函数,排布为设计矩阵,每个样本的激活出现在矩阵的每一行中。

[success] 这里是不是翻译有问题,H不是一个函数,而是一个值。 H可以是计算出来的z或者a。 Ng建议是对z做batch norm,没有解释原因。

为了标准化$H$,我们将其替换为

H′=H−μσ,\begin{aligned} H' = \frac{H - \mu}{\sigma}, \end{aligned}H′=σH−μ​,​

其中$\mu$是包含每个单元均值的向量,$\sigma$是包含每个单元标准差的向量。 此处的算术是基于广播向量$\mu$和向量$\sigma$应用于矩阵$H$的每一行。

在每一行内,运算是逐元素的,因此$H_{i,j}$标准化为减去$\mu_j$再除以$\sigma_j$。

网络的其余部分操作$H'$的方式和原网络操作$H$的方式一样。

训练阶段

在训练阶段,

μ=1m∑iHi,:\begin{aligned} \mu = \frac{1}{m} \sum_i H_{i,:} \end{aligned}μ=m1​i∑​Hi,:​​

和

σ=δ+1m∑i(H−μ)i2,\begin{aligned} \sigma = \sqrt{ \delta + \frac{1}{m} \sum_i (H - \mu)_i^2 }, \end{aligned}σ=δ+m1​i∑​(H−μ)i2​​,​

其中$\delta$是个很小的正值,比如$10^{-8}$,以强制避免遇到$\sqrt{z}$的梯度在$z=0$处未定义的问题。 至关重要的是,\emph{我们反向传播这些操作},来计算均值和标准差,并应用它们于标准化$H$。

[success] $\mu$是H的均值。$\sigma^2$是H的方差。是所有值与均值的平方和。 $\delta$用于防止分母为0 $H{norm} = \frac{H-\mu}{\sigma}$,这样得到的是均值为0方差为1的分布 但有时候,希望将z标准化为特定的均值$\beta$和方差$\gamma$,因此进一步计算: $\tilde{z}{norm} = \gamma z + \beta$ 这里面的$\gamma$和$\beta$不是超参数,而是参数,可以用GD学到。

这意味着,梯度不会再简单地增加$h_i$的标准差或均值;标准化操作会除掉这一操作的影响,归零其在梯度中的元素。

[warning] [?] 这一段看不懂

这是批标准化方法的一个重大创新。 以前的方法添加代价函数的惩罚,以鼓励单元标准化激活统计量,或是在每个梯度下降步骤之后重新标准化单元统计量。 前者通常会导致不完全的标准化,而后者通常会显著地消耗时间,因为学习算法会反复改变均值和方差而标准化步骤会反复抵消这种变化。

[warning] 后者和现在的方法有什么区别?后者是在前向传播的过程中做标准化,而现在的方法是在反向传播中做标准化?

批标准化重参数化模型,以使一些单元在定义上就总是标准化的,巧妙地回避了这两个问题。

测试阶段

在测试阶段,$\mu$和$\sigma$可以被替换为训练阶段收集的运行均值。 这使得模型可以对单一样本评估,而无需使用定义于整个小批量的$\mu$和$\sigma$。

[success] 训练时,批标准化公式中所使用的均值和方差都是基于一个batch计算的。 但在测试阶段,如果只有一个测试用例,怎么批标准化? 答:训练过程每个mini-bacth都会计算出一个均值和方差。整个迭代过程会得到均值序列和方差序列。基于这组序列做指数衰减平均得到整个训练样本的均值和方差。使用这个均值和方差对测试样本做标准化。 看来用ewa求平均是很common的方法啊。

效果

优点:更易学习

回顾例子$\hat{y} = x w1 w_2 \cdots w_l$,我们看到,我们可以通过标准化$h{l-1}$很大程度地解决了学习这个模型的问题。 假设$x$采样自一个单位高斯分布, 那么$h{l-1}$也是来自高斯分布,因为从$x$到$h_l$的变换是线性的。 然而,$h{l-1}$不再有零均值和单位方差。 使用批标准化后,我们得到的归一化$\hat{h}{l-1}$恢复了零均值和单位方差的特性。 对于底层的几乎任意更新而言,$\hat{h}{l-1}$仍然保持着单位高斯分布。 然后输出$\hat{y}$可以学习为一个简单的线性函数$\hat{y} = wl \hat{h}{l-1}$。 现在学习这个模型非常简单,因为低层的参数在大多数情况下没有什么影响;它们的输出总是重新标准化为单位高斯分布。 只在少数个例中,低层会有影响。 改变某个低层权重为$0$,可能使输出退化;改变低层权重的符号可能反转$\hat{h}{l-1}$和$y$之间的关系。 这些情况都是非常罕见的。 没有标准化,几乎每一个更新都会对$h{l-1}$的统计量有着极端的影响。 因此,批标准化显著地使得模型更易学习。

批标准化的优点: (1)使学习更快。由于没有Covariate Shift问题,因为可以使用比较大的learning rate (2)使网络更深 (3)less梯度消失/爆炸问题,对sigmoid类的激活函数尤其有效。 (4)受初始化的影响变小 (5)有一点点对抗overfitting的效果(顺便的作用)。

缺点:底层网络没有用

在这个示例中,容易学习的代价是使得底层网络没有用。

[warning] 使得底层网络没有用?

在我们的线性示例中,较低层不再有任何有害的影响,但它们也不再有任何有益的影响。 这是因为我们已经标准化了一阶和二阶统计量,这是线性网络可以影响的所有因素。 在具有非线性激活函数的深度神经网络中,较低层可以进行数据的非线性变换,所以它们仍然是有用的。 批标准化仅标准化每个单元的均值和方差,以稳定化学习,但允许单元和单元之间的关系,以及单个单元的非线性统计量之间的关系发生变化。

由于网络的最后一层能够学习线性变换,实际上我们可能希望移除一层内单元之间的所有线性关系。

[warning] 移除一层内单元之间的所有线性关系?

[warning] 后面全部没看懂?

事实上,这是~{Desjardins2015}中采用的方法,为批标准化提供了灵感。 令人遗憾的是,消除所有的线性关联比标准化各个独立单元的均值和标准差代价更高,因此批标准化仍是迄今最实用的方法。

批标准化的改进

标准化一个单元的均值和标准差会降低包含该单元的神经网络的表达能力。 为了保持网络的表现力,通常会将批量隐藏单元激活$H$替换为$\gamma H' + \beta$,而不是简单地使用标准化的$H'$。 变量$\gamma$和$\beta$是允许新变量有任意均值和标准差的学习参数。 乍一看,这似乎是无用的——为什么我们将均值设为$0$,然后又引入参数允许它被重设为任意值$\beta$? 答案是新的参数可以表示旧参数作为输入的同一族函数,但是新参数有不同的学习动态。 在旧参数中,$H$的均值取决于$H$下层中参数的复杂关联。 在新参数中,$\gamma H' + \beta$的均值仅由$\beta$确定。

[success] 例如sigmoid Unit会希望均值是0.5,同时方差不要太大,这样可以充分利用sigmoid函数近似线性的区间。 这里面也是对隐藏层做BN和对输入层做BN的区别。 使用$\gamma$和$\beta$主要是因为activation可以对z的分布有倾向。而输入层没有activation,因此输入层的BN都是均值为0方差为1.

新参数很容易通过梯度下降来学习。

大多数神经网络层会采取$\phi(XW+ b)$的形式,其中$\phi$是某个固定的非线性激活函数,如整流线性变换。 自然想到我们应该将批标准化应用于输入$X$还是变换后的值$XW+b$。 {Ioffe+Szegedy-2015}推荐后者。 更具体地,$XW+b$应替换为$XW$的标准化形式。 偏置项应被忽略,因为参数$\beta$会加入批标准化重参数化,它是冗余的。

[success] 因此不管怎么偏置,归一化之后都没有意义了。

一层的输入通常是前一层的非线性激活函数(如整流线性函数)的输出。 因此,输入的统计量更符合非高斯分布,而更不服从线性操作的标准化。

\chap?所述的卷积网络,在特征映射中每个空间位置同样地标准化$\mu$和$\sigma$是很重要的,能使特征映射的统计量在不同的空间位置,仍然保持相同。

[success] 流程总结

z=wxznorm=z−μσ2+δz~norm=γznorm+βa=f(z~norm)\begin{aligned} z = wx \\ z_{norm} = \frac{z - \mu}{\sqrt{\sigma^2 + \delta}} \\ \tilde{z}_{norm} = \gamma z_{norm} + \beta \\ a = f(\tilde{z}_{norm}) \end{aligned}z=wxznorm​=σ2+δ​z−μ​z~norm​=γznorm​+βa=f(z~norm​)​

[success]

[success] Ng补充:为什么BN能加速训练 原因一: 让所有维度的输入数据(输入层的X或者隐藏层的z)都处于同一scale,缓解“不同维度lr不同”的问题,不用因为照顾某一维度而把lr调低。因此能够speed up training。 原因二: it makes weight in later deep layer(例如第10层) more rebunst to changes to weight in earlier layers(例如第0层) 先解释一下Covariate Shift。举个例子,用左图的训练数据训练的模型来预测右图的数据,预测结果肯定不好。这是因为数据分布发生的迁移。 当映射X->y中的X变化时,需要重新训练算法,就是Covariate Shift。 Covarite Shift是怎么影响NN的? 在一个深层网络中,假设某一层的输出是a,在这一轮的参数调整中,l+1层到L层的参数调整目标是致力于拟合a到$\hat y$的映射.可是当这些参数调整好以后却发现a已经变了,a与$\hat y$之间的映射也变了。因此已经调好的参数又要重新调整。 为什么BN能消除Covariate Shift? BN所做的,是减少a的分布。上一层的输出即这一层的输入。如果不对上一层的结果做批标准化,这一层的输入会变化范围很大。因此这一层的效果会受到很大的影响。如果a的变化在一定范围内,就可以减少上一层a的变化对下一层的影响。那么这一层的效果也会比较稳定。同时减少后面层的参数调整对前面层的依赖,因此层之间会更加独立。 ‘ 原因三(弱): mean/variance是基于一个mini-batch计算的,这会引入z的噪声。有时候噪声是一种好事,它有正则化的效果,就像dropout一样。batch_size越大,引入的噪声越小。