Open ChongruiYang opened 1 year ago
在Roberta的预测过程中,被遮蔽的token(mask)及其周围的tokens都被转化成向量表示。然后通过上下文tokens的向量表征来预测mask token。
具体过程如下:
所以,关键是编码器(通常是Transformer)从上下文中学习到的语义知识,以及简单的预测头如何有效利用这些知识来预测mask的token。其中,词嵌入为每个token提供了基础的语义表示,编码器进一步建模上下文语义,最后通过预测头转化为具体的token预测。 这个过程充分利用了Transformer在建模上下文依赖关系上的优势,并通过大规模的mask语言模型预训练实现了无监督学习。这也是Roberta比其前身BERT有效的主要原因。
Transformer的结构是一种多层感知机,多层感知器(Multilayer Perceptron,缩写MLP)是一种前向结构的[人工神经网络],映射一组输入向量到一组输出向量。MLP可以被看作是一个有向图,由多个的节点层所组成,每一层都全连接到下一层。除了输入节点,每个节点都是一个带有非线性激活函数的神经元(或称处理单元)。
Ref: https://zh.d2l.ai/chapter_attention-mechanisms/attention-cues.html
multi-head attention和self-attention都是注意力机制,但在实现上有以下主要区别:
计算方式:
目的:
Query,Key and Values Machinisms
Query: 实现了自主提示;Key:非自主提示
查询(自主提示)和键(非自主提示)之间的交互形成了注意力汇聚; 注意力汇聚有选择地聚合了值(感官输入)以生成最终的输出
N-W Kernel Weighting Skills:
Nadaraya (Nadaraya, 1964)和 Watson (Watson, 1964)提出了一个更好的想法, 根据输入的位置对输出 进行加权:
成为一个更加通用的注意力汇聚(attention pooling)公式:
$f(x) = \sum_{i=1}^n \alpha(x, x_i) y_i$
其中 $x$ 是查询,$(x_i, y_i)$ 是键值对。 注意力汇聚是 $y_i$ 的加权平均;
将查询和键之间的关系建模为注意力权重(attention weight), $\alpha(x, x_i) y_i$,这个权重将被分配给每一个对应值。对于任何查询,模型在所有键值对注意力权重都是一个有效的概率分布:它们是非负的,并且总和为1。如果一个键越是接近给定的查询,那么分配给这个键对应值的注意力权重就会越大,也就“获得了更多的注意力”。
这里测试数据的输入相当于查询,而训练数据的输入相当于键。 因为两个输入都是经过排序的,因此由观察可知“查询-键”对越接近, 注意力汇聚的注意力权重就越高。
注意力参数也可以带未知量以在训练中学习。
在带参数的注意力汇聚模型中, 任何一个训练样本的输入都会和除自己以外的所有训练样本的“键-值”对进行计算, 从而得到其对应的预测输出。带参数的权重拟合会相比非参数的权重拟合更加不平滑(这就存在潜在的过拟合现象)。
键值是一个整体,你可以认为一个黑盒子,是我们训练好的网络,query你是要向这个网络来查询一个输入对应的输出,根据任务,我们要通过x_test来查询y_test值。
score_function
高斯核指数部分可以视为注意力评分函数(attention scoring function), 简称评分函数(scoring function), 然后把这个函数的输出结果输入到softmax函数中进行运算。 通过上述步骤,将得到与键对应的值的概率分布(即注意力权重)。 最后,注意力汇聚的输出就是基于这些注意力权重的值的加权和。
BERT’s tokenizer: https://cloud.tencent.com/developer/beta/article/1865689
为了保证词表有足够的压缩空间,同时要兼顾词的信息量,需要将词拆分成子词
1)BPE:for chars and high frequency subword: count for a higher frequency subword vocabs.
2)Byte_level:如果遇到了unicode,基本字符集可能会很大。一种处理方法是我们以一个字节为一种“字符”,不管实际字符集用了几个字节来表示一个字符。这样的话,基础字符集的大小就锁定在了256。
/例如,像GPT-2的词汇表大小为50257 = 256 +
3)WordPiece
从名字好理解,它是一种子词粒度的tokenize算法subword tokenization algorithm,很多著名的Transformers模型,比如BERT/DistilBERT/Electra都使用了它。
它的原理非常接近BPE,不同之处在于,它在做合并的时候,并不是每次找最高频的组合,而是找能够最大化训练集数据似然的merge,即它每次合并的两个字符串A和B,应该具有最大的 P(AB)/P(A)P(B)值。合并AB之后,所有原来切成A+B两个tokens的就只保留AB一个token,整个训练集上最大似然变化量与 P(AB)/P(A)P(B)成正比。
简而言之,合并"最紧密的"可能出现的词组对,这个紧密的定义需要确定
4)Unigram Cut
WordPiece不同,Unigram的算法思想是从一个巨大的词汇表出发,再逐渐删除trim down其中的词汇,直到size满足预定义。
初始的词汇表可以采用所有预分词器分出来的词,再加上所有高频的子串。
每次从词汇表中删除词汇的原则是使预定义的损失最小。训练时,计算loss的公式为熵的计算公式
5)SentencePiece
顾名思义,它是把一个句子看作一个整体,再拆成片段,而没有保留天然的词语的概念。一般地,它把空格space也当作一种特殊字符来处理,再用BPE或者Unigram算法来构造词汇表。
比如,XLNetTokenizer就采用了_来代替空格,解码的时候会再用空格替换回来。
无论是在非基于词的BERT还是非基于词的RobertA里面,都采用的是WordPiece的分割方法来构造vocab size
1)归一化
归一化是指对数据维度进行归一化,使它们具有大致相同的规模。有两种常见的方法可以实现这种规范化。一种是将每个维度除以其标准差,一旦它以零为中心:( X /= np.std(X, axis = 0))。这种预处理的另一种形式是对每个维度进行归一化,使得维度上的最小值和最大值分别为 -1 和 1。如果您有理由相信不同的输入特征具有不同的尺度(或单位),那么应用这种预处理才有意义,但它们对学习算法的重要性应该大致相同。
PCA 和 Whitening是另一种形式的预处理。在这个过程中,数据首先如上所述被居中。然后,我们可以计算协方差矩阵,告诉我们数据中的相关结构:
PCA:特征向量列按其特征值排序。我们可以通过仅使用前几个特征向量并丢弃数据没有方差的维度来使用它来降低数据的维度。这有时也称为主成分分析 (PCA)降维。根据方差的解释比来选取
Whitening:The whitening operation takes the data in the eigenbasis and divides every dimension by the eigenvalue to normalize the scale. The geometric interpretation of this transformation is that if the input data is a multivariable gaussian, then the whitened data will be a gaussian with zero mean and identity covariance matrix. 分解的特征分量除于特征值,对每个行进行比例归一化,如果原始数据是多变量高斯分布,那么生成的数据将是零均值多变量的高斯分布
ref: https://cs231n.github.io/neural-networks-2/#init
可以看看whitening后数据分布的结果
2) 权重初始化 In the process of training a neural network, we initialize the weights which are then updated as the training proceeds. For a certain random initialization, the outputs from one or more of the intermediate layers can be abnormally large. This leads to instability in the training process, which means the network will not learn anything useful during training. 会出现梯度异常的情况
推荐的预处理是将数据居中以使其均值为零,并沿每个特征将其比例归一化为 [-1, 1],通过从标准差为的高斯分布中绘制权重来初始化权重,其中n是神经元的输入数。例如在 numpy 中:w = np.random.randn(n) * sqrt(2.0/n).
3)爆炸式激活和梯度爆炸
跑多个epoch是为了避免当前的网络权重适应了数据的分布,对训练数据的批次进行规模化调整;爆炸式激活(exploding activation)会造成这个地方的梯度异常大,在回传的同时导致前面的梯度消失。同时也会减慢训练速度。
爆炸式激活带来的梯度消失问题:
自上而下:指前向传播过程中,上层节点激活值的极大逐渐放大,影响全网络。这导致上层节点梯度也变得很大。
自下而上:指这些极大梯度在反向传播的过程中,通过与各层节点误差的相乘,使得传递至下层节点的梯度越来越小。这最终导致了前层节点无法更新权重,产生梯度消失。
总体来说,爆炸式激活首先在前向传播的自上而下过程中产生和放大,使某高层节点的激活值变得极大。这又导致了该层节点在BP中的梯度也变得很大。而这些极大梯度在反向传播的自下而上过程中逐渐衰减至消失,使模型的前层节点无法更新,产生梯度消失问题。
所以,爆炸式激活引起的梯度消失问题,可以视为是在前向传播和反向传播两个过程中,极值的产生与衰减相结合的结果。前向传播自上而下地产生极大激活值和梯度,而反向传播自下而上地使这些极值逐渐消失,最终导致前层梯度无效,这就是爆炸式激活导致的梯度消失机制。
激活值表示神经网络中某层节点的输出值,它反映了该节点的激活程度或重要性。激活值越大,表示该节点对网络输出的影响越大。
梯度表示神经网络中的权重参数对损失函数的影响程度。梯度的值决定了权重参数在优化中需要更新的方向和大小。梯度值越大,表示对应的权重参数对损失函数的影响越大,需要更新的程度越大。
在反向传播算法中,某层节点的梯度取决于其激活值以及后续层节点的梯度。后续层节点的梯度通过反向传播,与该节点的激活值相乘,得到该节点的梯度。
所以,当某层节点的激活值非常大时,在反向传播过程中,该节点会获得一个也非常大的梯度值。因为其激活值与后续层传递过来的梯度相乘,得到的结果会非常大。这对应于爆炸式激活导致的梯度爆炸问题。
同时,当某层节点获得一个非常大的梯度时,在继续反向传播至前层节点时,这个大梯度会不断地与各层节点的激活值相乘(sigmoid导数的最大值为1/4),结果会越来越小,这对应于梯度消失问题。一个大梯度在反向传播过程中会逐渐衰减至消失。
网络层数过深,也会导致仅仅在反向回传的时候,仅更新后面的参数,前面的参数从而更新缓慢
4)避免过拟合:
L2正则化,针对小规模的全部W参数,
dropout,保证一部分神经元的活跃,按照概率抽样一部分神经元,更新梯度,而不动其他的神经元
5)Normalization (Batch VS Layer)
就是加速,稳定训练过程,不因为某个batch产生针对
Batch:不适合用于序列模型,第一对于batch_size大小有要求,二是对于sequence_length长短不一的情况,对于一个batch内的特征分量可能有影响(不要在[PAD]上乱加权值,不好解释)。对batch里每个样本的同一分量做,纵向norm
Layer:适用于序列模型,横向normlization
这不是BERT和RobertA的注意力机制,只是为了帮助理解:
BigBird是在Transformer模型基础上提出的一种稀疏注意机制。相比于Transformer中的全连接注意力,BigBird的注意力机制是线性的,这使其具有更高的计算效率。
BigBird的稀疏注意力由三个主要部分组成:
具体来说,BigBird的注意力可以表示为: Attention(Q, K, V) = βqZqKV + αqMqKV + γqRqKV
其中:
与Transformer相比,BigBird的主要优点是:
所以,总体来说,BigBird是在Transformer基础上的一种稀疏注意力机制。相比于全连接注意力,它具有线性时间复杂度,不需要任何先验知识,可以在性能不下降的情况下大大提高模型的计算效率。这使其有望在更广范围内应用于NLP。