赞
踩
链接: 机器学习面试
链接: https://zhuanlan.zhihu.com/p/114925231
1、为什么要引入激活函数?
如果我们不使用激活函数,那么我们的网络永远都是输入的一个线性加权的组合,无法去模拟非线性的关系。这样网络的能力就受到限制。如果使用了非线性的激活函数,仅仅需要两层网络,我们就可以模拟大部分的非线性的关系了。因此,激活函数的在神经网络中起到了至关重要的作用。
因为神经网络中每一层的输入输出都是一个线性求和的过程,下一层的输出只是承接了上一层输入函数的线性变换,所以如果没有激活函数,那么无论你构造的神经网络多么复杂,有多少层,最后的输出都是输入的线性组合,纯粹的线性组合并不能够解决更为复杂的问题。而引入激活函数之后,我们会发现常见的激活函数都是非线性的,因此也会给神经元引入非线性元素,使得神经网络可以逼近其他的任何非线性函数,这样可以使得神经网络应用到更多非线性模型中。
2、激活函数需要具备的性质
一般来说,在神经元中,激活函数是很重要的一部分,为了增强网络的表示能力和学习能力,神经网络的激活函数都是非线性的,通常具有以下几点性质:
1非线性:当激活函数是非线性函数时,一个两层的神经网络就可以去逼近绝大多数函数了。但是如果激活函数是线性的话,我们的网络始终只能学习出线性的关系出来。而无法去学习出复杂的非线性关系。
2单调性:在激活函数是单调的时,我们可以保证单层网络是凸的。
3可微性:在我们使用基于梯度的优化方法时,我们需要要求我们的激活函数是可微的。因为在反向传播更新梯度时,我们需要求损失函数对权重的偏导数。因此此时要求我们的激活函数是可微的。
连续并可导(允许少数点上不可导),可导的激活函数可以直接利用数值优化的方法来学习网络参数;
4.激活函数及其导数要尽可能简单一些,太复杂不利于提高网络计算率;
5.激活函数的导函数值域要在一个合适的区间内,不能太大也不能太小,否则会影响训练的效率和稳定性。
3、常见的激活函数有哪些?
Softmax激活函数
Sigmoid函数
Tanh/双曲正切激活函数
tanh函数可以看成是sigmoid函数的变形,tanh函数相比于sigmoid函数来说,它是关于原点对称的了。但是还是会存在着计算复杂,以及梯度消失的问题。tanh函数在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。
优点:
比Sigmoid函数收敛速度更快。
相比Sigmoid函数,其输出以0为中心。
缺点:
还是没有改变Sigmoid函数的最大问题——由于饱和性产生的梯度消失。
ReLU激活函数
relu的主要贡献:
解决了梯度消失和梯度爆炸的问题
计算方便计算速度快(梯度恒定为0或1)
加速了网络的训练
缺陷:
由于负数部分恒为0,导致一些神经元无法激活(可通过设置小学习率部分解决)
输出并不是零中心化的
尽管relu也有缺点,但是仍然是目前使用最多的激活函数
leakyrelu就是为了解决relu的0区间带来的影响,在小于0的区间,梯度为很小的数(非零),leakyrelu解决了0区间带来的影响,而且包含了relu所有优点。
elu激活函数也是为了解决relu的0区间带来的影响,但是elu相对于leakyrelu来说,计算要耗时一些(有e的幂计算)。
ELU激活函数
4、激活函数的选择
对于激活函数的选用,可以根据神经网络的用途及其场景,再加上对于激活函数的值域的了解,大致可以选定适合对应用途以及场景的激活函数例如,对于分类器,最终输出的是输入样本,在某一类上的可能性(概率),而概率值一般在[0,1]之间,因而最后一层输出的时候,可以选用值域在[0,1]之间的激活函数,比如说sigmoid函数。诸如此类的问题,可以根据值域来选择激活函数的运用
我们需要利用测试集来最小化损失函数从而求得模型参数w。
一言以蔽之,损失函数(loss function)就是用来度量模型的预测值f(x)与真实值Y的差异程度的运算函数,
它是一个非负实值函数,通常使用L(Y, f(x))来表示,损失函数越小,模型的鲁棒性就越好。
损失函数使用主要是在模型的训练阶段,每个批次的训练数据送入模型后,
通过前向传播输出预测值,然后损失函数会计算出预测值和真实值之间的差异值,也就是损失值。
得到损失值之后,模型通过反向传播去更新各个参数,
来降低真实值与预测值之间的损失,使得模型生成的预测值往真实值方向靠拢,从而达到学习的目的。
KL 散度通常用来度量两个分布之间的差异。KL 散度全称叫kullback leibler 散度,也叫做相对熵(relative entropy)。
在统计学意义上来说,KL散度可以用来衡量两个分布之间的差异程度。若两者差异越小,KL散度越小,反之亦反。当两分布一致时,其KL散度为0。正是因为其可以衡量两个分布之间的差异,所以在VAE、EM、GAN中均有使用到KL散度。
KL散度 = 交叉熵 - 真实概率分布式的熵
因为交叉熵越大,KL散度越大,所以交叉熵也可以衡量两个概率分布之间的距离。
交叉熵用于描述两个概率分布之间的相互关系,其值越小说明这两个分布越相近
它的大小表示两个概率分布之间的差异,可以通过最小化交叉熵来得到目标概率分布的近似分布。
3.Focal loss
focal loss的引入主要是为了解决难易样本不均衡的问题,注意有区别于正负样本不均衡的问题。
L1 loss 平均绝对误差(MAE)
也称为Mean Absolute Error,即平均绝对误差(MAE),它衡量的是预测值与真实值之间距离的平均误差幅度,作用范围为0到正无穷。
优点: 对离群点(Outliers)或者异常值更具有鲁棒性。
缺点: 由图可知其在0点处的导数不连续,使得求解效率低下,导致收敛速度慢;而对于较小的损失值,其梯度也同其他区间损失值的梯度一样大,所以不利于网络的学习。
L2 loss 均方误差损失函数(MSE)
也称为Mean Squred Error,即均方差(MSE),它衡量的是预测值与真实1值之间距离的平方和,作用范围同为0到正无穷。
优点: 收敛速度快,能够对梯度给予合适的惩罚权重,而不是“一视同仁”,使梯度更新的方向可以更加精确。
缺点: 对异常值十分敏感,梯度更新的方向很容易受离群点所主导,不具备鲁棒性。
L1 L2的权衡
对于L1范数和L2范数,如果异常值对于实际业务非常重要,我们可以使用MSE作为我们的损失函数;另一方面,如果异常值仅仅表示损坏的数据,那我们应该选择MAE作为损失函数。此外,考虑到收敛速度,在大多数的卷积神经网络中(CNN)中,我们通常会选择L2损失。但是,还存在这样一种情形,当你的业务数据中,存在95%的数据其真实值为1000,而剩下5%的数据其真实值为10时,如果你使用MAE去训练模型,则训练出来的模型会偏向于将所有输入数据预测成1000,因为MAE对离群点不敏感,趋向于取中值。而采用MSE去训练模型时,训练出来的模型会偏向于将大多数的输入数据预测成10,因为它对离群点异常敏感。因此,大多数情况这两种回归损失函数并不适用,能否有什么办法可以同时利用这两者的优点呢?
链接: 反向传播详解
链接: 反向传播到底是怎么传播的?
允许来自代价函数的信息通过网络反向流动以便计算梯度。
反向传播并不是用于学习整个神经网络的算法,而是仅用于计算梯度的算法。
神经网络的学习算法是随机梯度下降这类基于梯度的算法。
反向传播不仅仅适用于神经网络,原则上它适用于计算任何函数的导数。
链接: 深度学习数学基础之链式法则
链接: 一文弄懂神经网络中的反向传播法——BackPropagation
链接: 深度学习之2——反向传播算法
链接: 深度学习之3——梯度爆炸与梯度消失
链接: link
梯度消失和梯度爆炸的根源主要是因为深度神经网络结构以及反向传播算法,目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过反向传播的方式,指导深度网络权值的更新。
梯度消失和梯度爆炸两种情况产生的原因可以总结成2类原因:1.深层网络的结构;2.不合适的损失函数,比如Sigmoid函数。
1.预训练和微调
预训练:无监督逐层训练,每次训练一层隐藏点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入。称为逐层预训练。在预训练完成后还要对整个网络进行微调。
2.梯度剪切、正则
梯度剪切又叫梯度截断,是防止梯度爆炸的一种方法,其思想是设置一个梯度剪切阈值,更新梯度的时候,如果梯度超过这个阈值,那就将其强制限制在这个范围之内。
3.relu、leakyrelu、elu等激活函数
4.Batch Normalization(批规范化)
6.LSTM(长短期记忆网络)
在RNN网络结构中,由于使用Logistic或者Tanh函数,所以很容易导致梯度消失的问题,即在相隔很远的时刻时,前者对后者的影响几乎不存在了,LSTM的机制正是为了解决这种长期依赖问题。
机器学习中经常会在损失函数中加入正则项,称之为正则化(Regularize)。
目的:防止模型过拟合
原理:在损失函数上加上某些规则(限制),缩小解空间,从而减少求出过拟合解的可能性
提高模型泛化能力的一个最直接的方法是采用更多的数据来训练。但是通常在现实任务中,我们拥有的数据量有限。解决该问题的一种方法是:创建一些虚拟的数据用于训练。
数据集增强仅仅用于模型的训练,而不是用于模型的预测。即:不能对测试集、验证集执行数据集增强。当比较机器学习算法基准测试的结果时,必须考虑是否采用了数据集增强。通常情况下,人工设计的数据集增强方案可以大大减少模型的泛化误差。当两个模型的泛化性能比较时,应该确保这两个模型使用同一套人工设计的数据集增强方案。
注意数据集增强和预处理的区别:数据集增强会产生更多的输入数据,而数据预处理产生的输入数据数量不变。
1线性变换
2输入噪声
1.在神经网络的输入层注入噪声也可以视作数据增强的一种形式。如:在图像识别任务中,对训练图像注入高斯噪声。
2.通常一个训练好的神经网络对噪声鲁棒性较差,改善其噪声鲁棒性的常用方法是:简单地将随机噪声施加到输入上,再进行训练。
有三种添加噪声的策略:
输入噪声注入
将噪声作用于输入的数据集,这也是上面的一种数据集增强方法。
对于某些模型,在输入上注入方差极小的噪音等价于对权重施加参数范数正则化但是输入噪声注入远比简单地收缩参数强大,尤其是噪声被添加到隐单元的输入上时。
权重噪声注入:将噪音作用于权重。这项技术主要用于循环神经网络。
权重噪声注入、输出噪声注入
权重噪声注入可以解释为:将权重视作不确定的随机变量(拥有某个概率分布),向权重注入噪声是对该随机变量采样得到的一个随机值。
在某些假设下,权重噪声注入等价于传统的参数正则化形式。
权重噪声注入、输出噪声注入
再模型训练过程中,拟合数据到一定程度是会过拟合,导致验证集的损失函数下降,这时需要终止训练(早停)。
早停是深度学习中最常用的正则化形式,因为它简单、有效。
当训练终止时,返回的不是最新的模型参数,而是验证误差最小的模型参数,因此需要频繁存储模型参数。
优点:1、它几乎不需要干涉基本的训练过程,适合任何模型。2、可以单独使用,或者与其他的正则化策略相结合。3、早停不仅有正则化的好处,还有降低计算成本的好处。
在前向传播过程中,对网络中的每个隐层,每个隐单元都以一定的概率被删除,最后得到一个规模更小的网络。在反向传播过程中,仅仅针对该小网络进行权重更新。
3.3.6 对抗训练
链接: 苏建林-对抗训练浅谈:意义、方法和思考
链接: 论文阅读:对抗训练
链接: 对抗训练——终极数据增强?
鞍点是另一类梯度为零的点
病态黑塞矩阵:
链接: https://zhuanlan.zhihu.com/p/360222065
局部极小值:
机器学习中,通常会仔细设计目标函数和约束,从而保证最优化问题是凸的。但是神经网络中,通常遇到的都是非凸的最优化问题。对于非凸函数,如神经网络,可能存在多个局部极小值。实际上这并不是一个严重的问题。如果一个训练集可以唯一确定一组模型参数,则该模型称作可辨认的如果局部极小解和全局极小解相差很大时,此时多个局部极小解会带来很大隐患。它将给基于梯度的优化算法带来很大的问题。神经网络训练中,通常不关注代价函数的精确全局极小值,而是关心将代价函数值下降到足够小,从而获得一个很好的泛化误差。关于优化算法能否到达这个目标的理论分析是极其困难的。
链接: 必看、必看、必看、收藏版|史上最全机器学习优化器Optimizer汇总
链接: 简单认识Adam优化器
SGD中一个关键参数是学习率。前面介绍的SGD算法步骤使用固定的学习率 ,实践中有必要随着时间的推移而降低学习率。使用标准的梯度下降到达极小点时,整个代价函数的真实梯度非常小,甚至为零。由于SGD 使用mini-batch的梯度作为整体梯度的估计,因此引入了噪源。该噪源并不会在极小值处消失,使得在极小点时,梯度的估计可能会比较大。因此:标准的梯度下降可以使用固定的学习率,而SGD必须使用逐渐降低的学习率。
SGD以及其它的mini-batch算法的最重要性质是:每一步参数更新的计算时间(就是计算梯度的时间)不会随着训练样本数量的增加而增加。即使训练样本数量非常庞大时,算法也能收敛。对于足够大的数据集,SGD可能在处理整个训练集的所有样本之前就收敛到测试集误差的允许范围之内了。
动量方法 (衰减因子、Nesterov 动量)
为什么要加入动量方法?
应用了学习率衰减的SGD算法存在一个问题:有些时候学习率会很小,但是明明可以应用一个较大的学习率,而SGD 并不知道这一情况。
其解决方法是采用动量方法。动量方法积累了之前梯度的指数级衰减的移动平均,然后继续沿着该方向移动。它是一种移动平均,权重是指数级衰减的:近期的权重较大,远期的权重很小。动量方法取这些加权梯度的均值,根据该均值的方向决定参数的更新方向。动量方法是一种框架,它可以应用到随机梯度下降SGD 算法中。
二阶近似方法
牛顿法
BFGS
当使用基于梯度的优化算法求解时,需要用到梯度,这个梯度本质上也是一个期望,要准确的求解这个期望的计算量非常大,因为需要计算整个数据集上的每一个样本。
机器学习算法和一般最优化算法不同的一点:机器学习算法的目标函数通常可以分解为每个训练样本上的损失函数的求和。实践中,可以从数据集中随机采样少量的样本,然后计算这些样本上的梯度的均值,将这个均值作为该期望的一个估计。当使用小批量样本来估计梯度时,由于估计的梯度往往会偏离真实的梯度,这可以视作在学习过程中加入了噪声扰动。这种扰动会带来一些正则化效果。
mini-batch 不能太大
优点:训练快(mini-batch 越大,迭代次数越少,小批量样本来估计总体梯度越可靠,则每次参数更新沿着总体梯度的负方向的概率越大。但训练误差收敛速度快,并不意味着模型的泛化性能强)
缺点:泛化性能低(mini-batch 越大,计算的梯度估计更精确,它带来更小的梯度噪声。此时噪声的力量太小,不足以将参数推出一个尖锐极小值的吸引区域。解决方案为:提高学习率,从而放大梯度噪声的贡献)
mini-batch 不能太小
不能太小。因为对于多核架构来讲,太小的batch并不会相应地减少计算时间(考虑到多核之间的同步开销)。
在使用GPU时,通常使用 2 的幂作为batch大小。
1.代价函数变化明显的参数方向(偏导数较大):学习率较小,使得更新的步长较小。
代价函数变化不明显的参数方向(偏导数较小):学习率较大,使得更新的步长较大。
2. 对于标准的batch 梯度下降优化算法,沿着负梯度的方向就是使得代价函数下降的方向。如果不同的方向设置了不同的学习率,则前进的方向不再是负梯度方向,有可能出现代价函数上升。对于mini-batch 梯度下降,由于对梯度引入了躁扰,因此可以针对不同的方向设置不同的学习率。
2. 选择哪个算法并没有一个统一的共识,并没有哪一个算法表现的最好。
目前流行的优化算法包括:SGD,具有动量的SGD,RMSProp,AdaDelta,Adam。选用哪个算法似乎主要取决于使用者对于算法的熟悉程度,以便调节超参数。
链接: Normalization1
链接: Normalization2
链接: Normalization3
为什么要进行Normalization?
在机器学习领域中,不同评价指标(即特征向量中的不同特征就是所述的不同评价指标)往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。
其中,最典型的就是数据的归一化/标准化处理。数据之间差异过大的时候就需要标准化处理。
如果不进行归一化,那么由于特征向量中不同特征的取值相差较大,会导致目标函数变“扁”。
这样在进行梯度下降的时候,梯度的方向就会偏离最小值的方向,走很多弯路,即训练时间过长。
如果进行归一化以后,目标函数会呈现比较“圆”,这样训练速度大大加快,少走很多弯路。
它并不是一个优化算法,而是一个自适应的、调整参数模型的方法。
它试图解决训练非常深的神经网络的困难。深度神经网络训练困难的一个重要原因是:深度神经网络涉及很多层的叠加,而每一层的参数更新会导致上一层的输入数据分布发生变化。这会带来两个问题:
1、下层输入的变化可能趋向于变大或者变小,导致上层落入饱和区,使得学习过早停止。
2、通过层层叠加,高层的输入分布变化会非常剧烈。这就使得高层需要不断去适应底层的参数更新变化。这就要求我们需要非常谨慎的设定学习率、初始化权重、参数更新策略。
Batch Normalization是2015年一篇论文中提出的数据归一化方法,往往用在深度神经网络中激活层之前。其作用可以加快模型训练时的收敛速度,使得模型训练过程更加稳定,避免梯度爆炸或者梯度消失。并且起到一定的正则化作用,几乎代替了Dropout。
两个优点
1、可以解决内部协变量偏移,简单来说训练过程中,各层分布不同,增大了学习难度,BN缓解了这个问题。当然后来也有论文证明BN有作用和这个没关系,而是可以使损失平面更加的平滑,从而加快收敛速度。
2、缓解了梯度饱和问题(如果使用sigmoid这种含有饱和区间的激活函数的话),加快收敛。
缺点
1、batch_size较小的时候,效果差。
这一点很容易理解。BN的过程,是使用batch中样本的均值和方差来模拟全部数据的均值和方差.在batch_size 较小的时候,模拟出来的肯定效果不好,所以记住,如果你的网络中加入了BN,batch_size最好调参的时候调大点。
2、 BN 在RNN中效果比较差。
首先我们要意识到一点,就是RNN的输入是长度是动态的,就是说每个样本的长度是不一样的。当然,我们有做pad,但是在计算均值和方差的时候,肯定不能把pad考虑进来的。举个最简单的例子,比如 batch_size 为10,也就是我有10个样本,其中9个样本长度为5,第10个样本长度为20。那么问题来了,前五个单词的均值和方差都可以在这个batch中求出来从而模型真实均值和方差。但是第6个单词到底20个单词怎么办?如果只用这一个样本进行模型的话,不就是回到了第一点,batch太小,导致效果很差。当然这种情况你可以在dataloader的时候让长度相近的在一个batch中,缓解这个问题。
3、在测试阶段的问题,分三部分说。
首先测试的时候,我们可以在队列里拉一个batch进去进行计算,但是也有情况是来一个必须尽快出来一个,也就是batch为1,这个时候均值和方差怎么办?这个一般是在训练的时候就把均值和方差保存下来,测试的时候直接用就可以。那么选取效果好的均值和方差就是个问题。
其次在测试的时候,遇到一个样本长度为1000的样本,在训练的时候最大长度为600,那么后面400个单词的均值和方差在训练数据没碰到过,这个时候怎么办?这个问题我们一般是在数据处理的时候就会做截断。
还有一个问题就是就是训练集和测试集的均值和方差相差比较大,那么训练集的均值和方差就不能很好的反应你测试数据特性,效果就会差。这个时候就和你的数据处理有关系了。
LN在RNN这种动态文本模型上为什么比BN好?
对于使用场景来说,BN在MLP和CNN上使用的效果都比较好,在RNN这种动态文本模型上使用的比较差
layer_norm针对的是文本的长度,整条序列的文本,所以比bn好
时序特征并不能用Batch Normalization,因为一个batch中的序列有长有短。如果使用BN,由于为了补齐长短不一的样例而添加进去的0使得较长序列中词语的含义向量规模相对变小,较短序列中的词转换为含义向量的规模相对变大。平白无故增添了误差抖动。
BatchNorm就是通过对batch size这个维度归一化来让分布稳定下来。
LayerNorm则是通过对Hidden size这个维度归一化来让某层的分布稳定。
使用LN保证每个序列中词语转成的含义向量在同一规模上
此外,BN 的一个缺点是需要较大的 batchsize 才能合理估训练数据的均值和方差,这导致内存很可能不够用,同时它也很难应用在训练数据长度不同的 RNN 模型上。
问题2:Transformer为什么要用LayerNorm? Batch Normalization,这个技巧能够让模型收敛的更快。 但是Batch Normalization有一个问题——它需要一个minibatch的数据,而且这个minibatch不能太小(比如1)。 另外一个问题就是它不能用于RNN,因为同样一个节点在不同时刻的分布是明显不同的。 当然有一些改进的方法使得可以对RNN进行Batch Normalization,比如论文Recurrent Batch Normalization,有兴趣的读者可以自行阅读 。 Transformer里使用了另外一种Normalization技巧,叫做Layer Normalization。 假设我们的输入是一个minibatch的数据,我们再假设每一个数据都是一个向量, 则输入是一个矩阵,每一行是一个训练数据,每一列都是一个特征。 BatchNorm是对每个特征进行Normalization, 而LayerNorm是对每个样本的不同特征进行Normalization, 因此LayerNorm的输入可以是一行(一个样本)。 因为LayerNorm的每个样本都是独立计算的,因此minibatch可以很小甚至可以是1。 实验证明LayerNorm不仅在普通的神经网络中有效,而且对于RNN也非常有效。 BatchNorm看起来比较直观,我们在数据预处理也经常会把输入Normalize成均值为0,方差为1的数据。 只不过它引入了可以学习的参数使得模型可以更加需要重新缓慢(不能剧烈)的调整均值和方差。 而LayerNorm似乎有效奇怪,比如第一个特征是年龄,第二个特征是身高, 把一个人的这两个特征求均值和方差似乎没有什么意义。 论文里有一些讨论,都比较抽象。当然把身高和年龄平均并没有什么意义, 但是对于其它层的特征,我们通过平均”期望”它们的取值范围大体一致, 也可能使得神经网络调整参数更加容易,如果这两个特征实在有很大的差异, 模型也可以学习出合适的参数让它来把取值范围缩放到更合适的区间。
卷积:分析数学中的一种运算
卷积核(kernel):也叫卷积矩阵(convolution matrix)或者掩膜(mask),本质上是一个非常小的用于运算矩阵。
互相关运算:
填充:在高和宽的两侧填充元素
步长每次运算滑动的距离
池化运算也叫亚采样或者下采样。池化运算用一个矩阵区域内部的某个总体统计量来作为神经网络在该矩阵区域的输出,它综合了该矩阵区域的信息。池化层可以减少该层的输出数量。这意味着减少了网络下一层的输入数量,可以减少网络整体参数数量,降低计算量,减少参数存储需求,提高网络计算效率。
最大池化:定义一个窗口,并从窗口内取出最大值作为总体统计量。
均值池化:定义一个窗口,并从窗口内取出平均值作为总体统计量。
其他常见的还有: 二、L2范数以及基于中心像素距离的加权平均函数作为总体统计量。
嵌入层Embedding:
将每个词改为其对应的词向量。
词向量:可以理解为词在计算机中的含义。([我]->[0.6,0.5,0.6])
特征提取:语义相近的词, 其欧氏距离或余弦距离也比较近。
卷积层Convolution:
将Embedding与kernel_sizes=(2,3,4)进行卷积(宽一样,高不同),输出3个卷积层([6,1][5,1][4,1])
一个卷积层:可以理解为词义、词序、其上下文
池化层MaxPolling:
将卷积层压缩为一个像素点(1-max pooling:取出值最大的一个表示该特征)
全连接层FullConnection :
将MaxPolling后的特征,进行全连接。
激活函数Softmax:
通过Softmax输出每个类别的概率
textCNN的流程:先将文本分词做embeeding得到词向量, 将词向量经过一层卷积,一层max-pooling, 最后将输出外接softmax 来做n分类。
textCNN 的优势:模型简单, 训练速度快,效果不错。
textCNN的缺点:模型可解释型不强,在调优模型的时候,很难根据训练的结果去针对性的调整具体的特征,因为在textCNN中没有类似gbdt模型中特征重要度(feature importance)的概念, 所以很难去评估每个特征的重要度。
1.TextCNN能用于文本分类的主要原因是什么?
除了预训练文本外,TextCNN通过利用不同的卷积核尺寸并行提取文本的信息(类似N-gram),并通过最大池化来突出最重要的关键词来实现分类。
模型可解释型不强
1、TextCNN的卷积和池化操作会丢失文本序列中的词汇顺序和位置信息等内容,但也可利用这一点来增强文本,例如白色旅游鞋,可以添加旅游鞋白色数据等,分词后白色和旅游鞋位置就可以互换来丰富语料 。
2、在长文本使用TextCNN效果可能没有在短文本中效果好(具体还需要实践确认),原因同上,因此可以尝试使用Top k池化替代最大池化提取更多的文本信息。
1.Textcnn最大的问题全局max pooling丢失了结构信息,很难发现文本中的转折关系等复杂模式。卷积过后直接是全局max pooling,只能在卷积过程中计算与某些关键词的相似度,然后通过max pooling得出模型关注的那些关键词是否在整个文本中出现,以及最相似的关键词与卷积核的相似度最大有多大。
2.textcnn只知道关键词是否在文本中出现了,以及相似度强度分布,不可能知道关键词出现了几次,以及出现这些关键词的顺序。针对这个问题,可以尝试k-max pooling优化,针对每个卷积核都不只保留最大值,而是保留前k个最大值,并且保留这些值出现的顺序,即按文本的顺序排列k个最大值。
3.模型针对的事字向量,而不是字,一个卷积核可能只学了半个关键词词向量,另外的卷积核学了另外半个关键词的词向量,最后在分类器的地方,这些特征值被累加。
五、模型优化
1.使用word2vec词向量初始化embedding,并提升词向量维度
2.限制最后一层权重向量的L2范数,可以在每次训练步骤之后更新权重值
3.将L2正则化添加到网络防止过拟合,同时提高dropout的比率
链接: DNN,CNN和RNN优缺点/区别
链接: 一文搞懂RNN
RNN最重要的是引入了 门控机制
RNN,是一种有短期记忆能力的神经网络。
RNN中,神经元可以接收 其他神经元和自己的信息,形成有环路的网络结构。这样RNN可以逆序的将错误信息一步步的往前传递。但序列过长会出现梯度爆炸和消失问题(长期依赖问题、长距离依赖问题)。
是RNN的一种特殊形式,特点是能够学习长距离依赖关系。
链接: 人人都能看懂的LSTM
遗忘门(forget gate),输入门(input gate)和输出门(output gate
LSTM的第一步是决定我们要从单元状态中舍弃什么信息。这一步由激活函数是sigmoid的神经层决定
下一步是决定我们将要在单元状态中存储哪些新的信息。这有两个部分。首先,激活函数为sigmoid的称为“输入门”的层决定我们将更新哪些值。接下来,激活函数为tanh的层创建一个新的候选值向量,,可以添加到单元状态。 下一步,我们将结合这两部分来更新状态。
接下来,将旧的单元状态更新为新的单元状态。上面的步骤已经告诉了我们要做什么,现在只需要真正的去做。
我们让旧的状态乘以来“遗忘”我们决定忘记的事情。然后我们加上,这是新的候选值,按照我们决定更新每个单元状态值的比例进行缩放。
再说回我们的语言模型,这是我们放弃旧的主语性别信息并添加新信息的地方。
最后,我们需要决定输出的内容。这个输出将基于我们的单元状态,但将是一个过滤版。首先,我们运行一个sigmoid层,决定我们要输出单元状态的哪些部分。然后,我们通过tanh函数(把值转换为[-1,1]区间)把它的单元状态与sigmoid门的输出相乘,这样我们只输出我们决定的部分。
(1)RNN的梯度消失问题导致不能“长期依赖”
RNN中的梯度消失不是指损失对参数的总梯度消失了,而是RNN中对较远时间步的梯度消失了。
链接: 一文了解RNN、LSTM和GRU的概念、异同和优缺点
链接: RNN, LSTM, GRU模型的作用, 构建, 优劣势比较,attention机制
链接: 深入浅出Word2Vec原理解析
链接: 秒懂词向量Word2vec的本质
链接: 词向量Word2vec的本质
能够将单词转化为向量来表示,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系
1CBOW
2Skip-gram
介绍word2vec的原理
介绍word2vec,训练得到的word2vec的本质
(1)Word2Vec两个算法模型的原理是什么,网络结构怎么画?
(2)网络输入输出是什么?隐藏层的激活函数是什么?输出层的激活函数是什么?
(3)目标函数/损失函数是什么?
(4)Word2Vec如何获取词向量?
(5)推导一下Word2Vec参数如何更新?
(6)Word2Vec的两个模型哪个效果好哪个速度快?为什么?
效果:CBOW像是小学时做的填空题:I come ___ China,而Skip-Gram像是给你一个 from 让你预测上下文,理论上来说应该是CBOW的效果更好,但实际情况却恰恰相反。我觉得可能是因为CBOW是取上下文的输入向量的质心从而导致一部分有效信息损失,而Skip-Gram虽然看起来荒唐,但每个单词都会得到单独的训练不会损失有效信息,其实Skip-Gram比CBOW的效果好,主要是针对低频词而言,举个例子,让你补全 It is a ___ day,是不是突然有很多可能的答案,你大概率会填写一个高频词汇,如:nice、sun 等,而不会想到要填写gorgeous,而给你gorgeous单词,其特征很明显会想到这可以用来形容day、moon、girl 等等。其次gorgeous本身用量就没有nice那么多,如果再和其他上下文放在一起取质心,很容易被忽略,从而没法充分训练。
速度:我觉得Skip-Gram的速度慢可能是因为其预测值比较多需要分别计算多个Softmax,时间复杂度为O(kn),而CBOW虽然也有多个输入,但我们求其质心简化了操作,时间复杂度为O(n)。
(7)Word2Vec加速训练的方法有哪些?
主要有两个:
①Negative Sample(负采样):以一定概率的选取负样本,使得每次迭代时只需修改一小部分参数,这是典型Categorical Distribution Sampling分布问题。即给定一些变量及其概率,随机采样使其满足变量出现的概率。
②Hierarchical Softmax(层次softmax):是一种非常高效的训练方法,模型使用Huffman二叉树的叶节点来表示语料库的所有单词。
(8)介绍下Negative Sampling,对词频低的和词频高的单词有什么影响?为什么?
词典D中的词在语料C中出现的次数有高有低,高频词被选为负样本的概率比较大,低频词被选中的概率比较小。
(9)Word2Vec和隐狄利克雷模型(LDA)有什么区别与联系?
以上问题可以通过本文和参考文章找到答案,这里不再详细解答。
(10)介绍下Hierarchical Softmax的计算过程,怎么把 Huffman 放到网络中的?参数是如何更新的?对词频低的和词频高的单词有什么影响?为什么?
Hierarchical Softmax利用了Huffman树依据词频建树,词频大的节点离根节点较近,词频低的节点离根节点较远,距离远参数数量就多,在训练的过程中,低频词的路径上的参数能够得到更多的训练,所以效果会更好。
Hierarchical Softmax利用了Huffman树依据词频建树,词频大的节点离根节点较近,词频低的节点离根节点较远,距离远参数数量就多,在训练的过程中,低频词的路径上的参数能够得到更多的训练,所以效果会更好。
(11)Word2Vec有哪些参数,有没有什么调参的建议?
Skip-Gram 的速度比CBOW慢一点,小数据集中对低频次的效果更好;
Sub-Sampling Frequent Words可以同时提高算法的速度和精度,Sample 建议取值为 ;
Hierarchical Softmax对低词频的更友好;
Negative Sampling对高词频更友好;
向量维度一般越高越好,但也不绝对;
Window Size,Skip-Gram一般10左右,CBOW一般为5左右。
(12)Word2Vec有哪些局限性?
Word2Vec作为一个简单易用的算法,其也包含了很多局限性:
Word2Vec只考虑到上下文信息,而忽略的全局信息;
Word2Vec只考虑了上下文的共现性,而忽略的了彼此之间的顺序性;
1、Transformer在哪里做了权重共享,为什么可以做权重共享?好处是什么?[1]
2、Transformer的点积模型做缩放的原因是什么?[1]
3、Transformer中是怎么做multi head attention 的,这样做multi head attention,会增加它的时间复杂度嘛?[1]
4、为什么Transformer 要做 Multi-head Attention? 它的好处在哪? [6]
5、Transformer的Encoder端和Decoder端是如何进行交互的?和一般的seq2seq有什么差别?
6、Transformer中multi-head attention中每个head为什么要进行降维?[14]
链接: Transformer图解
1.循环神经网络 后一步的计算需要前一步的结果作为输入。是串行的计算。使用卷积神经网络替换循环神经网络 减少时序的计算。
2.但卷积神经网络对长序列难以建模(卷积只能看到一个比较小的窗口),如果序列很长,需要很多层卷积,一层一层的卷积才能融合。
自注意力机制是直接并行计算的。
如果使用了自注意力机制,一次可以看一层的所有的像素。
卷积也有好处:可以做多个输出通道(一个通道认为是可以识别不一样的模式)所以提出了multi-head 的attention,可以模型卷积神经网络多输出通道的一个效果。
1、self-attention 的本质是什么?包括哪几个步骤?和普通 Attention 的差别在哪里?[4]
2、不考虑多头的原因,self-attention中词向量不乘QKV参数矩阵,会有什么问题?[4]
3、在普通 attention 中,一般有 k=v,那 self-attention 可以嘛?[4]
4、self-attention 在计算的过程中,如何对padding位做mask?[2]
5、bert的mask为何不学习transformer在attention处进行屏蔽score的技巧?[11]
6、XLNet为什么不直接在attention掩码矩阵中只把当前的单词掩盖住来获取上下文的信息呢?直接mask住左上到右下的对角线构建双向语言模型不行吗?[3]
self-attention是非线性的
Self-Attention的核心是用文本中的其它词来增强目标词的语义表示,从而更好的利用上下文的信息。
问题1:为什么要用Self-Attention?
比如我们要翻译如下句子”The animal didn’t cross the street because it was too tired”(这个动物无法穿越马路,因为它太累了)。
这里的it到底指代什么呢,是animal还是street?要知道具体的指代,我们需要在理解it的时候同时关注所有的单词,重点是animal、street和tired,
然后根据知识(常识)我们知道只有animal才能tired,而street是不能tired的。
Self-Attention用Encoder在编码一个词的时候会考虑句子中所有其它的词,从而确定怎么编码当前词。如果把tired换成narrow,那么it就指代的是street了。
而LSTM(即使是双向的)是无法实现上面的逻辑的。为什么呢?比如前向的LSTM,我们在编码it的时候根本没有看到后面是tired还是narrow,所有它无法把it编码成哪个词。
而后向的LSTM呢?当然它看到了tired,但是到it的时候它还没有看到animal和street这两个单词,当然就更无法编码it的内容了。
当然多层的LSTM理论上是可以编码这个语义的,它需要下层的LSTM同时编码了animal和street以及tired三个词的语义,然后由更高层的LSTM来把it编码成animal的语义。
但是这样模型更加复杂。下图是模型的最上一层(下标0是第一层,5是第六层)Encoder的Attention可视化图。这是tensor2tensor这个工具输出的内容。
我们可以看到,在编码it的时候有一个Attention Head(后面会讲到)注意到了Animal,因此编码后的it有Animal的语义。
查询向量Q:表示为了编码当前词,需要去注意(attend to)其它(其实也包括它自己)的词,我们需要有一个查询向量。Self-Attention里的Query不是隐状态,并且来自当前输入向量本身,因此叫作Self-Attention。
词检索的关键信息K:可以认为是这个词关键的用于被检索的信息.
Q*V:可以代表词与词之间的相似度。
将Q和K做内积,两个向量内积(余弦值cos)越大,相似度越大。除以根号dk(向量的长度)(为了降低方差),通过sotfmax得到权重。(n个非负的,加权和为1的权重)。
词真正的内容V:Value向量是真正的内容
每个时刻t都计算出Qt,Kt,Vt之后,我们就可以来计算Self-Attention了。以第一个时刻为例,我们首先计算q1和k1,k2的内积,得到score,过程如下图所示。
计算第一个时刻的过程,计算其它时刻的过程是完全一样的。
问题:为什么要用矩阵计算?
前面介绍的方法需要一个循环遍历所有的时刻t计算得到z(t),
我们可以把上面的向量计算变成矩阵的形式,
从而一次计算出所有时刻的输出,
这样的矩阵运算可以充分利用硬件资源(包括一些软件的优化),从而效率更高。
第一步还是计算Q、K和V,不过不是计算某个时刻的qt,kt,vt了,而是一次计算所有时刻的Q、K和V。计算过程如下图所示。这里的输入是一个矩阵,矩阵的第i行表示第i个时刻的输入xi。
接下来就是计算Q和K得到score,然后除以(√dk),然后再softmax,最后加权平均得到输出。全过程如下图所示。
为什么做多头注意力机制?
doct-product里的具体函数就是你的内积很单一,为了识别不一样的模式,希望有一些不一样计算像素的方式。
先让QKV投影到一个低维空间(投影的W可以学习),给你h次机会,希望你学到不一样的投影方式,在不同的度量空间里能匹配不同的模式需要的相似函数。最后把这些投影弄回来,最后做一次投影。(像卷积网络里面多个输出通道的感觉)
多头的注意力有助于网络捕捉到更丰富的特征 / 信息。
Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions. With a single attention head, averaging inhibits this.多头注意力允许模型在不同位置共同关注来自不同表示子空间的信息。使用一个单注意力头,平均会抑制这种情况。
其实可以类似于 CNN 中利用多个卷积核分别提取不同特征。
前面定义的一组Q、K和V可以让一个词attend to相关的词,我们可以定义多组Q、K和V,它们分别可以关注不同的上下文。
Multi-Head计算输出多个Z,但是后面的全连接网络需要的输入是一个矩阵而不是多个矩阵,因此我们可以把多个head输出的Z按照第二个维度拼接起来,但是这样的特征有一些多,因此Transformer又用了一个线性变换(矩阵Wo)对它进行了压缩。这个过程如下图所示。
问题2:为什么要用位置编码? 我们的目的是用Self-Attention替代RNN,RNN能够记住过去的信息,这可以通过Self-Attention“实时”的注意相关的任何词来实现等价(甚至更好)的效果。 RNN还有一个特定就是能考虑词的顺序(位置)关系,一个句子即使词完全是相同的但是语义可能完全不同,比如”北京到上海的机票”与”上海到北京的机票”,它们的语义就有很大的差别。 我们上面的介绍的Self-Attention是不考虑词的顺序的,如果模型参数固定了,上面两个句子的北京都会被编码成相同的向量。 但是实际上我们可以期望这两个北京编码的结果不同,前者可能需要编码出发城市的语义,而后者需要包含目的城市的语义。 而RNN是可以(至少是可能)学到这一点的。当然RNN为了实现这一点的代价就是顺序处理,很难并行。 为了解决这个问题,我们需要引入位置编码,也就是t时刻的输入,除了Embedding之外(这是与位置无关的),我们还引入一个向量。 这个向量是与t有关的,我们把Embedding和位置编码向量加起来作为模型的输入。 这样的话如果两个词在不同的位置出现了,虽然它们的Embedding是相同的,但是由于位置编码不同,最终得到的向量也是不同的。 位置编码有很多方法,其中需要考虑的一个重要因素就是需要它编码的是相对位置的关系。 比如两个句子:”北京到上海的机票”和”你好,我们要一张北京到上海的机票”。 显然加入位置编码之后,两个北京的向量是不同的了,两个上海的向量也是不同的了, 但是我们期望Query(北京1)Key(上海1)却是等于Query(北京2)Key(上海2)的。 具体的编码算法我们在代码部分再介绍。位置编码加入后的模型如下图所示。
attention是不会有时序信息的,输出时value的加权和,权重是Query和ket之间的距离。跟序列信息无关,根本关注不到词之间位置(给一句话,把顺序任何打乱后,attention的结果都是一样的,顺序变了但值不变。处理不了时序问题)(RNN是上一时刻的输出为下一时刻的输入,传递历史信息)(attention是在输入里面加入时序信息)
1、BN在训练和测试时的差异? [17]
2、BN中的移动平均 Moving Average是怎么做的? [17]
3、移动平均中 Momentum 参数的影响? [17]
4、Norm中的标准化、平移和缩放的作用? [17]
5、不同Norm方法中都有哪些参数要保存? [17]
6、BN和LN 有哪些差异? [17]
7、为什么BERT使用LN,而不使用BN? [17]
8、如何去理解在哪一个维度做Norm? [17]
时序数据中,样本的长度会有变化。
layer_norm针对的是文本的长度,整条序列的文本,所以比bn好
时序特征并不能用Batch Normalization,因为一个batch中的序列有长有短。如果使用BN,由于为了补齐长短不一的样例而添加进去的0使得较长序列中词语的含义向量规模相对变小,较短序列中的词转换为含义向量的规模相对变大。平白无故增添了误差抖动。
BatchNorm就是通过对batch size这个维度归一化来让分布稳定下来。
LayerNorm则是通过对Hidden size这个维度归一化来让某层的分布稳定。
使用LN保证每个序列中词语转成的含义向量在同一规模上
此外,BN 的一个缺点是需要较大的 batchsize 才能合理估训练数据的均值和方差,这导致内存很可能不够用,同时它也很难应用在训练数据长度不同的 RNN 模型上。
问题2:为什么要用LayerNorm?(时序数据中,样本的长度会有变化。) Batch Normalization,这个技巧能够让模型收敛的更快。 但是Batch Normalization有一个问题——它需要一个minibatch的数据,而且这个minibatch不能太小(比如1)。 另外一个问题就是它不能用于RNN,因为同样一个节点在不同时刻的分布是明显不同的。 当然有一些改进的方法使得可以对RNN进行Batch Normalization,比如论文Recurrent Batch Normalization,有兴趣的读者可以自行阅读 。 Transformer里使用了另外一种Normalization技巧,叫做Layer Normalization。 假设我们的输入是一个minibatch的数据,我们再假设每一个数据都是一个向量, 则输入是一个矩阵,每一行是一个训练数据,每一列都是一个特征。 BatchNorm是对每个特征进行Normalization, 而LayerNorm是对每个样本的不同特征进行Normalization, 因此LayerNorm的输入可以是一行(一个样本)。 因为LayerNorm的每个样本都是独立计算的,因此minibatch可以很小甚至可以是1。 实验证明LayerNorm不仅在普通的神经网络中有效,而且对于RNN也非常有效。 BatchNorm看起来比较直观,我们在数据预处理也经常会把输入Normalize成均值为0,方差为1的数据。 只不过它引入了可以学习的参数使得模型可以更加需要重新缓慢(不能剧烈)的调整均值和方差。 而LayerNorm似乎有效奇怪,比如第一个特征是年龄,第二个特征是身高, 把一个人的这两个特征求均值和方差似乎没有什么意义。 论文里有一些讨论,都比较抽象。当然把身高和年龄平均并没有什么意义, 但是对于其它层的特征,我们通过平均”期望”它们的取值范围大体一致, 也可能使得神经网络调整参数更加容易,如果这两个特征实在有很大的差异, 模型也可以学习出合适的参数让它来把取值范围缩放到更合适的区间。
BatchNorm就是将每一个特征的均值变为0,方差变为1.
把一个向量的均值变为0,方差变为1:把向量本省的均值减掉,除以它的方差
LayerNorm是对每个样本处理。
输入x1,x2经self-attention层之后变成z1,z2,然后和残差连接的输入x1,x2加起来,然后经过LayerNorm层输出给全连接层。全连接层也是有一个残差连接和一个LayerNorm层,最后再输出给上一层。
56层的网络无论是在训练集还是测试集上,误差率都比20层的要高。出现这种现象的原因并非是由于层数加深引发的梯度消失/梯度爆炸,因为已经通过归一化的方法解决了这个问题,对于出现这种现象的原因将在下面讨论,我们将这种反常的现象称之为“退化现象“。那么为什么会出现这样的原因呢,何凯明在文章中给出的解释是“难以对网络进行优化”。
那么在这个新的网络,由于我们copy了前四层的参数,理论上前四层已经足够满足我们的性能要求,那么新增加的层便显得有些多余,如果这个新的网络也要达到性能100%,则新增加的层要做的事情就是“恒等映射”,也即后面几个紫色的层要实现的效果为 f(x)=xf(x)=xf(x)=x 。这样一来,网络的性能一样能达到100%。而退化现象也表明了,实际上新增加的几个紫色的层,很难做到恒等映射。又或者能做到,但在有限的时间内很难完成(即网络要用指数级别的时间才能达到收敛)。这时候,巧妙的通过添加”桥梁“,使得难以优化的问题瞬间迎刃而解。
实际上,网络性能通常未能达到100%,可以假设最初的网络(只有前四层)的性能到了98%等等,如果不添加跳连接,增加三个紫色层之后的新网络同样难以进行优化(由上面极端情况的推广,也即前面四层的性能达到100%)。而通过跳连接,可以把前四层的输出先送到FC层前面,也就相当于告诉紫色层:”兄弟你放心,我已经做完98%的工作了,你看看能不能在剩下的2%中发点力,你要是找不出提升性能的效果也没事的,我们可以把你的参数逼近于0,所以放心大胆的找吧。"
我们知道,神经网络无非是拟合一个复杂的函数映射关系,而通过跳链接,可以很好的“切割”这种映射关系,实现“分步”完成。我们把整个映射看成100%,则前面四层网络实现了98%的映射关系,而残余的映射由紫色层完成,Residual 另一个翻译就是"残余,残留“的意思,也就是让每一个残差块,只关注残余映射的一小部分,真的是恰到好处。
作者:人间白头
链接:https://www.zhihu.com/question/306135761/answer/2491142607
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Decoder和Encoder是类似的,如下图所示,区别在于它多了一个Encoder-Decoder Attention层,这个层的输入除了来自Self-Attention之外还有Encoder最后一层的所有时刻的输出。Encoder-Decoder Attention层的Query来自下一层,而Key和Value则来自Encoder的输出。
解码器中的mask:解码器是一个自回归的模型:当亲的输出的输入集是上面一些时刻的输出:在做预测的时候不能看到之后时刻的输出。但在注意力机制里它每次能看到完整的输入,所有在解码器训练时,预测第t个时刻的输出时,不能看到t以后的输入输出。需要一个带掩码的自注意力机制。
1、为什么BERT在第一句前会加一个[CLS]标志? [1]
2、BERT的三个Embedding直接相加会对语义有影响吗?[1]
3、在BERT中,token分3种情况做mask,分别的作用是什么?
4、为什么BERT选择mask掉15%这个比例的词,可以是其他的比例吗?[1]
5、针对句子语义相似度/多标签分类/机器翻译翻译/文本生成的任务,利用BERT结构怎么做fine-tuning?
6、使用BERT预训练模型为什么最多只能输入512个词,最多只能两个句子合成一句?[1]
7、BERT非线性的来源在哪里?multi head attention 是线性的嘛?[1]
8、BERT 是如何区分一词多义的?[16]
9、BERT的输入是什么,哪些是必须的,为什么position id不用给,type_id 和 attention_mask没有给定的时候,默认会是什么
10、BERT训练时使用的学习率 warm-up 策略是怎样的?为什么要这么做?[13]
11、Bert 采用哪种Normalization结构,LayerNorm和BatchNorm区别,LayerNorm结构有参数吗,参数的作用?[8]
12、为什么说ELMO是伪双向,BERT是真双向?产生这种差异的原因是什么?
13、BERT和Transformer Encoder的差异有哪些?做出这些差异化的目的是什么?
14、BERT训练过程中的损失函数是什么?
15、BERT 的两个任务 Masked LM 任务和 Next Sentence Prediction 任务是先后训练的还是交替训练的
链接: Bert 如何解决长文本问题?
global norm + passage rank + sliding window
这个问题现在的解决方法是用Sliding Window(划窗),主要见于诸阅读理解任务(如Stanford的SQuAD)。Sliding Window即把文档分成有重叠的若干段,然后每一段都当作独立的文档送入BERT进行处理。最后再对于这些独立文档得到的结果进行整合。
作者:猪猪侠和狗子
链接:https://www.zhihu.com/question/327450789/answer/1024153978
来源:知乎
使用BERT预训练模型为什么最多只能输入512个词,最多只能两个句子合成一句?
为什么BERT在第一句前会加一个[CLS]标志?
问题1:bert解决了ELMo和OpenAI GPT什么问题? ELMo和GPT最大的问题就是传统的语言模型是单向的——我们是根据之前的历史来预测当前词。 但是我们不能利用后面的信息。比如句子”The animal didn’t cross the street because it was too tired”。 我们在编码it的语义的时候需要同时利用前后的信息,因为在这个句子中,it可能指代animal也可能指代street。 根据tired,我们推断它指代的是animal,因为street是不能tired。 但是如果把tired改成wide,那么it就是指代street了。 传统的语言模型,不管是RNN还是Transformer,它都只能利用单方向的信息。 比如前向的RNN,在编码it的时候它看到了animal和street,但是它还没有看到tired,因此它不能确定it到底指代什么。 如果是后向的RNN,在编码的时候它看到了tired,但是它还根本没看到animal,因此它也不能知道指代的是animal。 Transformer的Self-Attention理论上是可以同时attend to到这两个词的, 但是根据前面的介绍,由于我们需要用Transformer来学习语言模型, 因此必须用Mask来让它看不到未来的信息,所以它也不能解决这个问题的。 注意:即使ELMo训练了双向的两个RNN,但是一个RNN只能看一个方向,因此也是无法”同时”利用前后两个方向的信息的。 也许有的读者会问,我的RNN有很多层, 比如第一层的正向RNN在编码it的时候编码了animal和street的语义,反向RNN编码了tired的语义, 然后第二层的RNN就能同时看到这两个语义,然后判断出it指代animal。 理论上是有这种可能,但是实际上很难。 举个反例,理论上一个三层(一个隐层)的全连接网络能够拟合任何函数,那我们还需要更多层词的全连接网络或者CNN、RNN干什么呢? 如果数据不是足够足够多,如果不对网络结构做任何约束,那么它有很多中拟合的方法,其中很多是过拟合的。 但是通过对网络结构的约束,比如CNN的局部特效,RNN的时序特效,多层网络的层次结构, 对它进行了很多约束,从而使得它能够更好的收敛到最佳的参数。 我们研究不同的网络结构(包括resnet、dropout、batchnorm等等)都是为了对网络增加额外的(先验的)约束。
对于普通的分类任务,输入是一个序列,如图中右上所示,所有的Token都是属于同一个Segment(Id=0),我们用第一个特殊Token [CLS]的最后一层输出接上softmax进行分类,用分类的数据来进行Fine-Tuning。
对于相似度计算等输入为两个序列的任务,过程如图左上所示。两个序列的Token对应不同的Segment(Id=0/1)。我们也是用第一个特殊Token [CLS]的最后一层输出接上softmax进行分类,然后用分类数据进行Fine-Tuning。
第三类任务是序列标注,比如命名实体识别,输入是一个句子(Token序列),除了[CLS]和[SEP]的每个时刻都会有输出的Tag,比如B-PER表示人名的开始,本章的序列标注部分已经介绍过怎么把NER变成序列标注的问题了,这里不再赘述。然后用输出的Tag来进行Fine-Tuning,过程如图右下所示。
第四类是问答类问题,比如SQuAD v1.1数据集,输入是一个问题和一段很长的包含答案的文字(Paragraph),输出在这段文字里找到问题的答案。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。