深度学习--机器学习相关(1)
1.训练集、测试集、验证集
在做一个训练任务的时候,能获取的所有的数据包含两类, 一类有特征和标签;另一类有特征没有标签需要预测标签,即测试集。在第一类有特征有标签的数据中, 一 般会分为训练集和验证集。训练集就是课本,验证集就是模考卷子,测试集就是考试。
最常见的问题就是验证集究竟是否参与到训练过程中。如果不参与,那么岂不是浪费 了这些有标签的数据吗?这里引入n-fold 的方法。把所有的给了标签的数据三等分,然后每一份都作为一个验证集,这样每一个验证集对应的训练集应该占全部有标签数据的三分之二,而且每一个训练集和对应的验证集之间的数据不重复。训练3个模型,每一个模型只用训练集数据训练,然后用对应的验证集进行检验,判断模型是否训练完成。最后在预测测试集标签时将3个模型的输出求均值。这样的方法可以增强模型的泛化能力,而且可以利用所有的可用数据并且防止数据泄露问题。
2.epoch 、batch 、mini-batch
讲到机器学习神经网络,绕不开的就是这几个基础概念。现在假设要处理的是图片分 类任务,总共有10张图片作为全部的训练集。
(1)sample 每一张训练集中的图片,称为一个样本,总共有十个样本。
(2)Epoch 假想一个人在背书学习的时候,只看一遍书够吗?不够的,要翻来覆去反复多次地看。这里也是一样,10张图片模型看过一遍称为一个 Epoch, 但是模型没学好又 看了一遍,就是2个Epoch 。Epoch 就是全部训练集的学习次数。
(3)batch (批) 计算机的内存是有限的, 一般是不能把全部的训练数据集同时放到内存中进行计算。只能从十张图片中拿五张出来,进行训练,更新参数,之后把内存中的数据清空,再放入另外五张图片。这样, 一个Epoch 中就有两个 batch, 每一个batch 会更新一次 模型的参数。
(4)mini-batch 在论文中应该会出现这个概念。这个是用在多处理器同时训练的情况下的。依然是上面的例子,假设为了加快训练速度,准备了5个处理器并行训练,这样一 个Batch 就 会 被 分 成 5 个mini-batch,每 一 个mini-batch就是 一 张图片。在这种情况下,是每一个 mini-batch 更新 一 次参数而不是一 个batch更新 一 次参数。
一个 batch包含全部的训练数据,就是每一个Epoch 中只有一个batch的时候,学习算法称为“批量梯度下降”;假设batch 中只有一个样本,称为“随机梯度下降”;更一 般的,batch 的大小在两者之间时,称为“小批量梯度下降”。
3.规范化
本节主要讲解批规范化(Batch Normalization,BN)。虽 然 到 目 前 为 止 出 现 多 种 规 范 化 手段,但是常见的依然是BN 。其好处是加快模型训练速度和收敛,稳定深层网络模型并缓解网络层数过深造成的梯 度消失的问题。现在基本是卷积神经网络的标准配置, 一层卷积层一个BN 层一个卷积层 一个 BN 层,也许在BN 层后再加一个Dropout 层。
内部协变量偏移
在BN 相关论文中,提出了内部协变量偏移(Internal Covariate Shift,ICS)问题。简单来说,就是发现深度学习中有 ICS 这样一个问题,需要用BN 去解决。首先来了解一下什么是独立同分布(Independently Identically Distribution,IID)假设。 在训练神经网络的时候会分出来训练集和测试集,理想状态下希望这两个数据集是独立同分布的,独立在于两者没有相关,不会发生数据泄露的问题,同分布是希望两者是从同样的分布中采样出来的,即两者的本质是一样的。例如, 一个学生在复习高考,他在刷模拟卷子。 这个模拟卷子就是训练集,高考卷子就是测试集,测试他的学习效果如何。独立就是高考原题不太可能出现在模拟卷试题中,如果出现了,在机器学习中有一个名词来形容这个问题——数据泄露。同分布就是希望做的模拟题和未来的高考题的考的知识点,这些本质的东西是一样的,可以通过学习模拟题来提高答对高考题的概率。
那么什么是协变量偏移(Covariate Shift)? 这个问题是不可避免的,依然用高考来举 例,现在准备2020年高考,但是市面上的所有模拟题、参考书都是基于2019年以前的高考 题目。严格来说,2020年高考模拟题应该是与2019年之前高考真题同分布,没有人知道 2020年高考真题是一个什么分布,这就是协变量偏移。可以把协变量理解为一个一个的样 本、 一道一道的题,2020年模拟题和2020年高考题发生了偏移。
深度网络的内部协变量偏移问题就是每一层的网络输入分布问题。假设神经网络有两 层,那么输入数据自然是训练集和测试集了,在经过第一层的非线性变换后,训练集和测试 集在第一层的输出都达到了第二层的输入口,这时候两者的第二层的输入数据是否依然保持同分布?如果还有第三层、第四层……
在模型的内部,数据经过了非线性变换很难能够保持同分布。如果网络深度比较深,那 么第一层网络的参数变化了,然后第二层的输入分布就会变化,然后这个变化就会层层累积 到深层的网络中,因此上层就会不断地适应底层的参数更新,这样就造成收敛速度慢,波动 大,学习率、初始化权重等都很难设置。一般神经网络的底层就是浅层,上层就是深层,数据从底层向深层流动。新手只需大致明白ICS 是什么问题。在设计模型的时候,对于新手加上BN 层就没问题。
批 规 范 化
BN 可以解决ICS 问 题 ,BN的数学表达如下:
(1)x 是一组数
(2)x 先减去均值,再除以标准差。就是把x 变成均值为0,方差为1的标准分布。
(3)BN 层中有两个可以学习的参数,gamma 和 beta。gamma 控制了y 的方差,beta 控制了y 的均值,所以最后y 并不是一个标准分布,y 的分布是要学习的。
(4)一不朽一般是0.00001,值很小,只是为了防止分母为0。
那么经过BN 层时,x 不是[1,2],不是一个样本,而是所有样本的某一个维度,x 是[1,3]和 [2,4]。
假设 gamma 和 beta 学习非常理想,则底层参数的改变不会影响上层的分布,因为分布是由gamma 和 beta 决定的,这样就可以缓解训练困难的问题;而且gamma 和 beta 合适的 话,可以把数据约束在梯度没有消失的区域,这样也可以缓解梯度消失的问题。
gamma 和 beta 两个学习参数是 BN 的精髓,假设没有这两个参数,那么 BN 就只能把 分布改成标准分布,这样已经破坏了原来的真正的分布,预测的就会不准。而且诸多实验证明BN 有种种优点,例如优化激活函数、梯度平缓、正则化等。
梯度平缓通常指的是在梯度下降算法中,当梯度(即损失函数对参数的偏导数)的值变得非常小,接近于零时,参数更新的幅度也会变得很小,这意味着我们接近了损失函数的最小值。在这种情况下,算法可能会非常缓慢地收敛,因为每一步的更新都非常小。
梯度下降是一种常用的优化算法,用于最小化损失函数。算法通过计算损失函数在当前参数下的梯度,然后沿着梯度的反方向更新参数,以此减小损失函数的值。这个过程会不断重复,直到满足某个停止条件,比如梯度的大小小于一个预设的阈值,或者迭代次数达到上限。
正则化是机器学习中用来防止模型过拟合的一种技术。过拟合是指模型在训练数据上表现得很好,但是在新的、未见过的数据上表现不佳,即模型的泛化能力差。正则化通过在损失函数中添加一个额外的项来实现,这个额外的项通常与模型的复杂度相关,目的是惩罚模型的复杂度。
BN vs LN
这里再简单提一下层规范化(Layer Normalization,LN)。
(1)2015提出的 BN 。规范的是每一个 batch中的数据。从上述的例子中可以看到,需要一个Batch 中有多组数据才能进行规范,如果batch 中只有一个样本,那么BN 的结果没有意义。(2)2016年提出了LN 。称为层规范化。因为BN 极大地依赖于 batch 中数据的好坏,所以LN 只考虑一个样本,是横向比较。BN 是计算一个 batch 中不同样本的同一个特征的均值和方差,;LN 是计算一个样本中的不同特征的均值和方差。在图像卷积网络中是BN 效果好,在RNN 中是LN 效果好。
SGD与 MBGD
在“神经网络”章节中已经推导了梯度下降的公式,最终可以表示为:
就是对每一个参数更新的算法。也可以写成梯度算子的表达:
C 就是 Loss,写成C(Cost) 和L(Loss) 都可以。以下写成L
这里的损失L 是由 Loss 函数计算得到的,每一个样本经过模型得到的标签估计值和 标签真实值之间就可以得到一个损失, 一个 batch 里面有多少样本,就可以得到多少损失, 然后把一个 batch 的损失求均值就是梯度下降算法中的L, 也就是式中的C。
假设一个batch 内包含很多的数据,这样计算损失的时候就需要消耗大量的计算力。 所以为了解决这个问题,随机梯度下降(Stochastic Gradient Descent,SGD)出现了。之前普通的梯度下降是需要计算一个batch 中所有样本的损失然后求均值,而SGD 就是随机选取 一个样本,仅仅计算这一个样本的损失,然后用这个损失来近似整个batch 的损失。听起来就像是为了提高运行速度,省略了一些步骤。
(1)批量梯度下降(Batch Gradient Descent,BGD)。这个就是最原始的形式。每一次 迭代都用全部样本的损失的平均值来计算梯度。所以如果全部样本非常多,模型的收敛速 度就会非常慢,训练时间非常长,因此不常用。
(2)SGD 。 每次迭代只用一个样本来对参数进行更新,速度快了,但是准确度下降,其 实现在也不是很常用。
(3)小批量梯度下降(Mini-Batch Gradient Descent,MBGD)。这个就是引入了常说的 Batch 的概念。把全部的数据分成Batch, 然后每一个 batch 进行一次迭代,这个常用。
总共有100个样本,那么对于BGD 来说,每次更新参数都需要计算100个样本; 对于SGD 来说,每次更新参数只需要计算一个样本;对于MBGD 来说,假设 Batch_size 为 10,那么就是每次更新参数计算10个样本,是一种对 BGD 和 SGD 的均衡。其实BGD 中并没有引入batch的概念,而MBGD 中才引入了常说的 batch的概念。这样理解就行。