为什么不同的查重系统检测出来的结果有比较大的差异!!
首先,从算法的角度来看,有些系统采用基于文本匹配的算法,通过比较两篇论文之间的文本相似性来判断是否存在抄袭行为。这些系统通常使用词频、词向量和语义分析等技术来计算论文之间的相似度。
其次,还有一些系统采用了基于指纹和特征提取的算法。这些系统通过计算论文中的独特特征,如单词和短语的频率、距离和顺序等来判断是否存在抄袭行为。这种方法可以有效地检测到对论文进行简单修改或进行词汇替换的抄袭行为。
此外,还有一些系统采用了混合算法,结合了文本匹配和特征提取的方法。这些系统通常将多种算法和技术相结合,以提高论文查重的准确性和可靠性。
除了算法的差异外,不同的论文查重系统在功能和性能方面也有所区别。一些系统提供简单的文本对比功能,用户可以将两篇论文进行比较,以检测相似性。而其他系统则提供更复杂的功能,如批量检测、自动报告生成和查重数据库等。
此外,不同的系统还具有不同的性能特点。一些系统具有高速处理和准确性较高的特点,可以在短时间内对大量论文进行检测。而其他系统则可能处理速度较慢,并且对于某些文本修改技术和抄袭手法的检测效果可能不理想。
理解Bert
n-gram语言模型:根据前面n个词预测当前词,它的缺点是,一般只能取1-2,n越大计算成本越高,这就使得它关注的信息是非常局限的。
预训练语言模型:wordvec\glove\fasttext。wordvec是根据周围词预测当前词或当前词预测周围词,相比于n-gram,它关注了下文,但它仍然是关注局部信息。glove通过构建词频共现矩阵来训练词向量,将全局信息融入到词向量中。fasttext仍然是局部的,只是他分词是基于subword,对于oov词相对友好。三者共同的缺点是,无法解决一词多义问题。
高级语言模型:elmo\GPT,elmo采用1层静态向量+2层单向LSTM提取特征,并且能够解决一词多义,elmo是一个双向语言模型,但实际上是两个单向语言模型(方向相反)的拼接,这种融合特征的能力比 BERT 一体化融合特征方式弱。GPT采用Transformer的decoder单元提取特征,同样也可以解决一词多义问题,但GPT是单向的。所以,对上下文信息的融合,二者能力还不够。
bert是双向语言模型,句子没有shift_mask操作,所以是完整的上下文环境,证实了双向语言模型对文本特征表示的重要性。bert同时证实了预训练模型能够简化很多繁重任务的网络结构,在11个nlp任务上都有显著提升。
bert采用Transformer的encoder单元提取特征,encoder中包含几个重要的机制:self-attention、muti-head attention、position encoding。
bert分为bert_base和bert_large大小两个模型,bert_base采用了12个encoder单元,768维隐藏层,12个attention。bert_base采用了24个encoder单元,1024维隐藏层,16个attention。
input:单句或句对组合,有[cls]作为句子开头的标记,[sep]作为句子分隔和结束的标记。
token embedding:对于英文采用WordPiece embeddings,也就是一个单词会被拆成词根词缀的,比如图中的playing被拆成了play和ing两个token;对于中文,就是单子拆分。
segment embedding:相邻句子采用不同的标志分隔,形如111111111100000011111100000。
position embedding:在transformer中,单词之间是没有先后顺序的,而语言本身是有序的,所以采用采用正余弦函数来计算每个单词的先后顺序,这种方式有点勉强,算是折中方式。
前面讲到elmo也是双向语言模型,它是采用bi-LSTM来提取特征,如下:
比如一句话:‘北京是中国的首都’,在LSTM中从左往右,预测‘中国’的时候只能看到‘北京’,从右往左,预测‘中国’的时候只能看到‘首都’,然后将两个lstm的输出做拼接来达到上下文信息融合的目的。其实是没有完全做到双向,只是以结构的改变来接近双向语言模型。真正的双向是预测‘中国’的时候,需要同时看到‘北京’和‘首都’。由此,mask LM产生了。
mask LM的原理是将‘中国’遮盖住,同时用‘北京’和‘首都’来预测‘中国’。‘北京’和‘首都’联系起来语言模型很容易联想到就是‘中国’啦。这个思想和wordvec的CBOW模型如出一辙,就是用周围词预测当前词,只是这个思想放在厉害的transformer中,便能大显其能。
BERT的mask方式:在选择mask的15%的词当中,80%情况下使用mask掉这个词,10%情况下采用一个任意词替换,剩余10%情况下保持原词汇不变。这样mask的优点是什么?
1)被随机选择15%的词当中以10%的概率用任意词替换去预测正确的词,相当于文本纠错任务,为BERT模型赋予了一定的文本纠错能力;
2)被随机选择15%的词当中以10%的概率保持不变,缓解了finetune时候与预训练时候输入不匹配的问题(预训练时候输入句子当中有mask,而finetune时候输入是完整无缺的句子,即为输入不匹配问题)。
在Mask LM任务中,模型学到了词与词之间的关系,而NSP任务是要模型学到句子与句子之间的关系,比如问答、推理等。它将训练语料分为两类,一是将50%语料构建成正常语序的句子对,比如A-B句子对,B就是A的实际下一个句子,并做标记为isnext;二是将50%语料构建成非正常语序句子对,B是来自语料库的随机句子,并做标记为notnext。然后通过对句子对的关系做分类,预测B到底是不是A句子的下一个句子,使模型具有句子级别的识别能力。
微调的目的在于我们的任务与bert预训练任务是不一致的,但是bert是非常好的语言模型,他具备提取词法和句法的强大能力。将bert嵌入到我们的网络结构中,能够简化在语言模型方面的复杂结构。只需要将输入做成和bert适配的格式就行,而在bert后面接上全连接、CNN等简单模型进行训练,就能够使训练得到一个比较好的效果。
GPT 和 BERT 都采用Transformer,Transformer 是encoder-decoder 结构,GPT 的单向语言模型采用 decoder 部分,decoder 的部分见到的都是不完整的句子;BERT 的双向语言模型则采用 encoder 部分,采用了完整句子。他俩最主要的区别在于BERT是双向语言模型,更适合文本分类等任务,GPT是单向语言模型,更适合生成式任务。
1)低层网络捕捉了短语级别的结构信息
2)表层信息特征在底层网络(3,4),句法信息特征在中间层网络(6~9),语义信息特征在高层网络。(9~12)
3)主谓一致表现在中间层网络(8,9)
1)ROBERTA
?静态mask->动态mask:在bert中每一个epoch被mask的是相同的词,而ROBERTA在每一个epoch结束,重新随机15%的词,使不同的词被mask。
?去除句对NSP任务,输入连续多个句子:在bert中最长是512个token,输入单句或者句对不容易把512个token占满,ROBERTA输入更多句子占满512个坑位。
?训练使用更多数据 更大batch size 更长时间
2)ALBERT
?减少参数:词表 V 到隐层 H 的中间,插入一个小维度 E,即一个VxH的embedding变成两个VxE, ExH的两个fc。
?共享所有层的参数:Attention 和 FFN,在bert中每一层的Attention 和 FFN的参数是不一样的。
?SOP 替换 NSP:负样本换成了同一篇文章中的两个逆序的句子,bert中是A-->B和A-->随机,ALBERT中是A-->B,B-->A。
?BERT对MASK 15% 的词来预测。ALBERT 预测的是 n-gram 片段,包含更完整的语义信息。
?训练数据长度:90%取512,BERT90% 128
?对应BERT large:H:1024?->4096? L:24->12?窄而深->宽而浅
离开深度学习瞎折腾了一段时间后,我终于又回来了。
于是赶紧回顾了下18年之后NLP的发展,基本就是将迁移学习更广泛的用于NLP领域,以及把17年年底的《Attention is all you need》里的思想给发扬光大了,ELMO弥补了传统word2vec多义词表示的不足,GPT使用更强大的特征提取器Transformer取代LSTM,Bert使用双向Transformer进一步改进了GPT成为这两年发展的集大成者。
从Bert模型所带来的NLP界里程碑式的影响和所取得的成就来看,无疑Bert将会是未来两三年NLP应用发展的基石,于是有必要仔细的看看其模型的结构,数据是如何流动的,训练的和测试的。
不得不说现在的学习环境相对几年前好太多了,本文主要参考了以下几篇文章,然后加了点自己的理解:
Dissecting BERT Part 1: The Encoder
The Illustrated Transformer
Dissecting BERT Appendix: The Decoder
它的总体框架同lstm时代的MNT或者是attention is all you need中的 transformer 一样的 encoder-decoder 结构:
我们先来介绍一下Encoder部分。
为了理解这个架构,我们使用一个简单的具体的例子,来看一下 输入 的数据是怎么通过 encoder 一步一步变化让后到 输出 的。
bert的词嵌入由三个嵌入token embedding、segment embedding,和position embedding叠加而成。
这个过程跟以往的RNNs没什么区别,比如给定一个句子:
第一步是先将其标记化:
然后是数字化,将每个标记映射到语料词汇表中的唯一整数编号:
接下来就是得到序列中每个词的词嵌入,也就是将整数映射到一个 维的向量,这个向量是模型在训练时学习的,你可以将其视为一个查表的过程,这些向量的元素作为模型的参数,像其他权重一样通过反向传播进行了优化。
在论文中是使用WordPiece tokenization 来将英文单词转换成768( )维的向量,转化的过程类似这样:
把每个词的向量放到一起,就得到了一个 句子长度x向量维度 ( ) 尺寸的矩阵 Z :
说明一点,我们通常使用 填充 的方式来让输入序列具有相同的长度,比如通过添加"" 标记来增加某些序列的长度,还是前面的例子,填充后可能变为:
如果设定 设定为9,那我们就把句子从5填充到了9。
但是,上面的embedding并没有包含词的位置信息。于是,我们的目标是能够根据词在句子中的位置适当调整这个向量,使它带上位置信息。
作者选择的方法是使用预定的(非学习的)正余弦函数将 之间的数字加到前面的embedding中,即通过正余弦函数将位置表示为彼此的线性组合,从而实现网络学习中标记位置之间的相对关系。在Token embedding 获得的矩阵 的基础上加上位置矩阵 。
数学上,用 表示序列中标记的位置,用 表示token embedding特征向量中的位置:
具体来说,对于给定的句子 ,其位置嵌入矩阵为:
作者解释说,使用这种确定性方法的结果和学习位置表示(就像我们对词嵌入那样)的结果差不多,因此这样反而会有一些优势:
因此,添加了位置信息之后的矩阵是:
它是第一个encoder块的输入,尺寸是
共有N个编码器块连接在一起直到生成编码器的输出,特定的块负责查找输入表示之间的关系并将编码在其输出中。
直观地,通过这些块的迭代过程将帮助神经网络捕获输入序列中的词之间的更加复杂的关系,你可以把它理解成一个整体用来捕捉输入序列的语义。
encoder中使用Transformer的多头注意力机制,这意味着它将计算 份不同权重矩阵的自注意力,然后将结果连接在一起。
这些并行注意力计算的结果称之为Head,我们用下标 来表示一个特定的head和相关的权重矩阵。
如上图所示,一旦计算了所有head,它们将被连接起来,得到一个尺寸为 的矩阵,然后将它乘以一个尺寸为 的权重矩阵 进行线性变换,就得到了一个尺寸为 的最终结果,用数学公式表示就是:
其中的 通过 乘以相应权重矩阵 获得,我们通过一个简单的例子来可视化的看一下这个过程。
这图描绘了输入标记通过 token embedding 和 positional encoding ,再输入到Encoder:
接下来,我们再来看下Encoder中的操作过程,先看一下单头的self-attention:
上图描绘了一个Head的 是怎么来的,其中的 的尺寸是 , 因为Q和K需要计算相似性,所以维度应当是相同的, 的尺寸是 , 的维度可以相同也可以不同,在论文中 .
所谓的自注意力,就是 与 的点积进行 的缩放之后通过softmax获得一个概率权重,然后用这些权重分别乘以各自的 即可:
为了加深理解,我们选择其中一个头,通过图形继续可视化的看一下这个变化过程:
然后计算self-attention,
多头的话就是同时有多个上述计算过程在进行:
假设我们有8个Head,那么我们就获得8个 :
但是,显然前馈层只需要一个矩阵 ,怎么处理呢?类似多卷积核的处理,把这8个矩阵连起来,乘以一个权重矩阵 压缩到一个矩阵。
为了有一个更加全面直观的认识,我们把上面整个过程放到一个图里,
显然,第二个encoder块是不需要embedding过程的,只要把第一个encoder块的输出作为输入即可。
经过上面的介绍,你应该对这个过程已经有了足够的了解,但是,为什么可以利用向量点积来计算注意力概率呢?
于是让我们进一步深入来了解其中的原理。
这个结构体系的关键在于:
也就是每个词的q向量与每个词的k向量的点积,套用点积公式:
这意味着 和 的方向越相似,长度越大,点积就越大。词与此之间关联越大,对于理解这个词时得到的关注越大,跟我们的本意是相同的。
我们再看一下最开头的结构示意图,每个encoder块在Multi-Head Attention之后经过一个 Add & Norm层才进入下一个块。于是我们来看一下这一层做了些什么。
Add 实际就是一个残差连接,将输出加上输入,这个在每一块的self-attenton以及FFN之后都会有,然后跟随一个Layer Norm 。
Norm 是一个Layer Normlization,将 正则化,就是把它缩放到一个均值为0方差为1的域里。因为
不过一般在这一层之前,就会有一个dropout层。
每个encoder块都由 mulit-head atteion add & Norm feed forword network add & Norm 这样一个过程,下面来介绍一下这个Feed-Forward Network。
这是一个全连接层,包含两个线性变化和一个非线性函数(实际一般就是ReLu),
对于输入的 (尺寸为 ) ,通过权重矩阵 (尺寸为 )和偏置 线性变换到隐藏层 (尺寸为 ) ,然后**ReLu **激活 ,记下来再用权重矩阵 (尺寸为 ) 和偏置 的线性变换到输出层(尺寸为 ) ,表示成数学公式就是:
在最后一个encoder块输出之后连接到decoder。
Decoder和Encoder的结构是类似的,但是因为可视信息的不同,又有所差别。
Transformer解决的是翻译的问题,将一个句子翻译成另一种语言,我们希望模型能够捕捉到输入句子中词之间的关系,并且将输入句子中包含的信息与每一步已翻译的内容结合起来。继续上面的例子,我们的目标是把一个句子从英文翻译为西班牙文,这是我们获得的序列标记:
我们同之前一样来看看输入到输出数据是如何流动的。
这是我们的解码器的输入标记:
然后这是解码器的期望输出:
但是,这里存在一个问题,比如输入这边我们已经看到了'como' 的后面是'estas', 然后再用它来预测'estas' ,这显然是不合理的,因为模型在测试的时候是看不到后面的词的。
因此,我们需要修改注意力层,防止模型可以看到预测词右边的信息,与此同时,它能利用已经预测的词,即左边的信息。
继续上面的例子,我们将输入标记转换成矩阵的形式,并添加位置信息:
和encoder一样,decoder块的输出也将是大小为 的矩阵,在逐行线性变换+softmax激活后,将生成一个举证,其中每行的最大元素表示下一个单词。也就是说,分配"" 的行负责预测“Hola”, 分配"Hola"的行负责预测"," ...以此类推。比如,为了预测"estas", 我们将允许该行直接和下图中绿色区域互动,而不能和红色区域互动:
但是,在我们使用多头注意力机制的时候,所有的行都会产生交互,因此需要在输入的时候添加遮罩,这个遮罩会在注意力计算之后进行:
这是 self-attention 的计算结果:
然后我们在此基础上添加遮掩,就是把矩阵上三角的位置全部设置为 :
于是,在进行softmax激活之后,矩阵就变成了:
恰好达到了我们的要求,那些需要在训练时忽略的右侧的词的注意力全部变成了0。
当将这个注意力矩阵与 相乘时,预测的词就是模型可以访问元素右边的元素。注意,这里的多头注意力输出将是 维的,因为它的序列长度是 。
这个就是 Decoder 从 target序列 的输入,并经过 Masked Multi-Head Attention 的一个变化得到了 ,decoder的还有一部分输入来自于源语句经过 Encoder 的最终输出 (尺寸是 )。
接下来,就是与encoder一样的 Multi-Head Attention Add and Layer Norm -> FFN 的过程。
只不过,现在的 来自于 ,而 来自于 :
计算每个query相对于key的注意力之后,得到的是一个 的矩阵, 继续咱们的例子,比如注意力矩阵为:
如上图所见,这个注意力是当前Decoder输入与Encoder输出的每个词之间的注意力,咱们用这个矩阵再乘以 ,就得到了一个 的矩阵,每一行代表了源语句相对于当前输入词汇的特征:
h个Head连接起来,尺寸变为 ,它通过 的权重矩阵 线性变换到一个 的输出。
这在多个Decoder之后,最后输出的矩阵通过乘以权重矩阵 ( ) 进行线性变换,变换之后再对每一行的向量softmax, 其中选择值最大位置对应词表索引的词就是预测的词。
损失的话只需要用预测的每个词向量与真实的词的one-hot词表示计算交叉熵即可。
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!