从零开始实现一个深度学习框架 | 一文读懂Normalization (1)
往期回顾
本系列教程往期文章如下:
[2] 从零开始实现一个深度学习框架 | 打造基础学习框架篇
[3] 从零开始实现一个深度学习框架 | 激活函数,损失函数与卷积层
[4] 从零开始实现一个深度学习框架 | 常用优化算法介绍与实现
[5] 从零开始实现一个深度学习框架 | 当神经网络遇上遗传算法
完整源代码见(欢迎stars):
https://github.com/CharlesPikachu/pytoydl
注意,本系列文章默认读者是具备一定的高数和机器学习常识的,且可以无障碍使用python作为编程工具。
导语
上期我们带大家用神经网络+遗传算法训练了一个自动玩小游戏的程序:
主要是为了避免本系列文章过于枯燥,所以中间会穿插一些有趣的神经网络应用。本期我们回归正题,带大家深入理解一下神经网络中的Normalization到底是咋回事。
废话不多说,让我们愉快地开始吧~
Normalization的起源
众所周知,满足独立同分布条件的数据往往更受深度学习炼丹师们的喜爱,即:
independent and identically distributed (i.i.d.)
大家经常在论文里看到的满足 i.i.d. 一般指的 就是数据满足独立同分布了。例如,脍炙人口的朴素贝叶斯算法就必须要求数据满足独立同分布。当然,神经网络并不强制要求输入数据独立同分布,但炼丹师的无数经验告诉我们,满足独立同分布的数据往往是更有助于模型训练的。一个直观的解释就是如果神经网络每层的输入分布变化很大,那么网络就要不断地去调整适应不同分布的数据,增加了模型学习的难度。一般而言,神经网络每层输入数据不满足独立同分布的问题又被称为:
Internal Covariate Shift (ICS)
更加专业一点地描述,就是统计机器学习中一般会假设“源空间和目标空间的数据分布是一致的”,而covariate shift的含义就是源空间和目标空间的条件概率一致:
但是其边缘概率不同:
具体而言, 对于没有加独立同分布约束的神经网络,由于神经网络层内的运算,其各层的输入信号分布和输出信号的分布是不同的,但是他们所对应的样本标签是一样的。顺便提一句,叫 internal covariate shift是 因为具体到神经网络,我们是对层间信号进行分析,所以在 c o variate shift前面加了个 in terna l 。
因此,在把数据喂给神经网络之前,我们往往会对数据进行一些预处理:
-
独立:去除相关性;
-
同分布:保证具有相同的均值和方差。
这个预处理一般也叫“白化”,其中最经典的方法就是PCA白化,简单而言,就是进行和PCA降维一样的操作,但是选择的特征向量个数和数据维度相同。对于不知道PCA降维是什么的同学,可以参考如下链接进行学习:
https: //zhuanlan.zhihu.com/p/77151308参考文献
[1]. https://zhuanlan.zhihu.com/p/33173246
[2 ]. http://ufldl.stanford.edu/tutorial/unsupervised/PCAWhitening/
[3]. https://www.zhihu.com/question/38102762/answer/85238569
Normalization算法详解
前面我们说到,对于神经网络中的某个神经元:
由于存在ICS问题,输入数据
具体而言,该方案的基本思想就是对输入数据进行平移和伸缩变换,公式化的表达如下所示:
公式中的参数
接下来的
其中,第一步很好理解,就是为了保证输入数据同分布,那么第二步又是为了什么呢?一般地,我们认为这是为了保证模型的表达能力不会因为规范化操作而下降。如果对self-attention有了解的朋友可以回忆一下(这个我们以后的章节会聊到),现在用的最多的self-attention方式是不是key, value, query都是其实不一样的呢?在我看来,其实这些处理的功能在某种意义上都是类似的,即为了加强模型的表征能力。
写到这里,可能很多人会有疑惑,加上再平移和再缩放参数,不就变成和之前一样了吗?其实不是的,因为在引入normalization之前,输入
我们可以举几个简单的例子来看看引入normalization后给网络训练到底带来了哪些好处:
1. 权重伸缩不变性
即当网络权重
推导如下:
因此,我们有:
即权重的伸缩变化不会影响反向传播的梯度的雅可比矩阵,避免了反向传播过程中因为权重过大或过小导致的梯度消失和梯度爆炸问题。
另外,由于:
即网络的权重较大时,其对应的梯度会比较小,起到了参数正则化的效果,避免了网络的大幅震荡。
2. 数据伸缩不变性
即当输入数据
因此,我们有:
换句话说,数据的伸缩变换不会影响对该层的权重参数的更新,有利于保证训练的稳定性。
接下来,我们来学习一些现有的normalization方法。
1. Batch Normalization
BN可以看作一种纵向规范化方法,套入到我们前面提到的Normalization公式:
参数
其中,
放个图更加直观地展示一下BN的计算方式:
2. Layer Normalization
LN可以看作一种横向规范化方法,套入到我们前面提到的Normalization公式:
参数
即LN是对单个训练样本进行的。
放个图更加直观地展示一下LN的计算方式:
3. Instance Normalization
IN同样可以套入到我们前面提到的Normalization公式:
参数
即IN是对 单个训练样本的单个特征图进行的。
放个图更加直观地展示一下IN的计算方式:
4. Group Normalization
GN其实就是IN和LN的结合, 套入到我们前面提到的Normalization公式:
参数
其中G代表单个Group里的特征图数量,即GN是对单个训练样本的某几个特征图进行的。
放个图 更加直观地展示一下GN的计算方式:
5. Weight Normalization
前面四种normalization方法均将规范化应用于输入的特征数据
具体而言,WN会将网络权重
于是,我们只需要固定
套入到我们前面总结的公式:
可知在WN中,
6. Cosine Normalization
搞完数据和权重,研究者们又盯上了数据和权重之前的运算符,于是CN便横空出世了。具体而言,他们将原来的线性变换
于是所有的数据都被规范化到了区间
总而言之,尽管到目前为止,不同的研究者提出了各种各样的normalization,他们的适用场景虽然不同,例如LN一般用于NLP领域,而BN适用于mini-batch之间以及mini-batch和整体数据分布近似同分布的场景,但是他们都 万变不离其宗,可以套用到同一个统一的公式中。
参考文献
[1]. https://arxiv.org/abs/1803.08494
[2]. https://zhuanlan.zhihu.com/p/33173246