BERT 简介
Self-supervised Learning

-
每个人都应该熟悉监督学习,当我们做监督学习时,我们只有一个模型,这个模型的输入是x,输出是y。
假设你今天想做情感分析,你就是让机器阅读一篇文章,而机器需要对这篇文章进行分类,是正面的还是负面的,你必须先找到大量的文章,你需要对所有的文章进行label。我们需要有标签和文章数据来训练监督模型
-
"Self-supervised "是用另一种方式来监督,没有标签。假设我们只有一堆没有label的文章,但我们试图找到一种方法把它分成两部分。
我们让其中一部分作为模型的输入数据,另一部分作为标签。
假设你有没有label的数据,例如,一篇文章叫x,我们把x分成两部分,一部分叫x',另一部分叫x'',我知道现在的说明很抽象。稍后,当我们真正谈论BERT时,你可以更好地理解Self-supervised的含义,以及如何在明明没有办法进行监督训练的情况下,最终还是找到了自己进行监督训练的方法。
我们把x分成两部分,x'和x'',然后把x'输入模型,让它输出y。如果我们在模型训练中使用标签,我们称之为监督学习。由于在Self-supervised学习中不使用标签,我们可以说,Self-supervised学习也是一种无监督的学习方法。但之所以叫Self-supervised Learning,是为了让定义更清晰。
-
"Self-supervised Learning "这个词,当初Yann LeCun说过,其实并不是一个老词。根据2019年4月在Facebook上的一个帖子,他说,我现在说的这个方法,他叫Self-supervised Learning。为什么不叫无监督学习呢?因为无监督学习是一个比较大的家族,里面有很多不同的方法,为了让定义更清晰,我们叫它 "自监督",比如我们之前 提到的cycle gan,也是无监督学习的一个案例,我们也不使用标注的配对数据,但是,它和Self-supervised Learning还是有点区别。在无监督学习的范畴内,有很多方法,Self-supervised Learning就是其中之一。
Masking Input
Self-supervised Learning是什么意思呢,我们直接拿BERT模型来说。
首先,BERT是一个transformer的Encoder,我们已经讲过transformer了,我们也花了很多时间来介绍Encoder和Decoder,transformer中的Encoder它实际上是BERT的架构,它和transformer的Encoder完全一样,里面有很多Self-Attention和Residual connection,还有Normalization等等,那么,这就是BERT。

如果你已经忘记了Encoder里有哪些部件,你需要记住的关键点是,BERT可以输入一行向量,然后输出另一行向量,输出的长度与输入的长度相同。
BERT一般用于自然语言处理,用于文本场景,所以一般来说,它的输入是一串文本,也是一串数据。
当我们真正谈论Self-Attention的时候,我们也说不仅文本是一种序列,而且语音也可以看作是一种序列,甚至图像也可以看作是一堆向量。BERT同样的想法是,不仅用于NLP,或者用于文本,它也可以用于语音和视频。
接下来我们需要做的是,随机盖住一些输入的文字,被mask的部分是随机决定的,例如,我们输入100个token,什么是token?在中文文本中,我们通常把一个汉字看作是一个token,当我们输入一个句子时,其中的一些词会被随机mask。

mask的具体实现有两种方法。

- 第一种方法是,用一个特殊的符号替换句子中的一个词,我们用 "MASK "标记来表示这个特殊符号,你可以把它看作一个新字,这个字完全是一个新词,它不在你的字典里,这意味着mask了原文。
- 另外一种方法,随机把某一个字换成另一个字。中文的 "湾"字被放在这里,然后你可以选择另一个中文字来替换它,它可以变成 "一 "字,变成 "天 "字,变成 "大 "字,或者变成 "小 "字,我们只是用随机选择的某个字来替换它
所以有两种方法来做mask,一种是添加一个特殊的标记 "MASK",另一种是用一个字来替换某个字。
两种方法都可以使用。使用哪种方法也是随机决定的。因此,当BERT进行训练时,向BERT输入一个句子,先随机决定哪一部分的汉字将被mask。
mask后,一样是输入一个序列,我们把BERT的相应输出看作是另一个序列,接下来,我们在输入序列中寻找mask部分的相应输出,然后,这个向量将通过一个==Linear transform==。

所谓的Linear transform是指,输入向量将与一个矩阵相乘,然后做softmax,输出一个分布。
这与我们在Seq2Seq模型中提到的使用transformer进行翻译时的输出分布相同。输出是一个很长的向量,包含我们想要处理的每个汉字,每一个字都对应到一个分数。
在训练过程中。我们知道被mask的字符是什么,而BERT不知道,我们可以用一个one-hot vector来表示这个字符,并使输出和one-hot vector之间的交叉熵损失最小。

或者说得简单一点,我们实际上是在解决一个分类问题。现在,BERT要做的是,预测什么被盖住。被掩盖的字符,属于 "湾"类。
在训练中,我们在BERT之后添加一个线性模型,并将它们一起训练。所以,BERT里面是一个transformer的Encoder,它有一堆参数。这两个需要共同训练,并试图预测被覆盖的字符是什么,这叫做mask。
Next Sentence Prediction
事实上,当我们训练BERT时,除了mask之外,我们还会使用另一种方法,这种额外的方法叫做==Next Sentence Prediction== 。
它的意思是,我们从数据库中拿出两个句子,这是我们通过在互联网上抓取和搜索文件得到的大量句子集合,我们在这两个句子之间添加一个特殊标记。这样,BERT就可以知道,这两个句子是不同的句子,因为这两个句子之间有一个分隔符。

我们还将在句子的开头添加一个特殊标记,这里我们用CLS来表示这个特殊标记。
现在,我们有一个很长的序列,包括两个句子,由SEP标记和前面的CLS标记分开。如果我们把它传给BERT,它应该输出一个序列,因为输入也是一个序列,这毕竟是Encoder的目的。
我们将只看CLS的输出,我们将把它乘以一个Linear transform。

现在它必须做一个二分类问题,有两个可能的输出:是或不是。这个方法被称为Next Sentence Prediction ,所以我们需要预测,第二句是否是第一句的后续句。
然而,后来的研究发现,对于BERT要做的任务来说,Next Sentence Prediction 并没有真正的帮助。例如,有一篇论文叫 "Robustly Optimized BERT Approach",简称RoBERTa。在这篇论文中,它明确指出,实施Next Sentence Prediction ,几乎没有任何帮助。然后,这个概念不知不觉地成为主流。
在这之后,另一篇论文说下一句话预测没有用,所以在它之后的许多论文也开始说它没有用。例如,SCAN-BERT和XLNet都说Next Sentence Prediction 方法是无用的。它可能是无用的原因之一是,Next Sentence Prediction 太简单了,是一项容易的任务。
这个任务的典型方法是,首先随机选择一个句子,然后从数据库中或随机选择要与前一个句子相连的句子。通常,当我们随机选择一个句子时,它看起来与前一个句子有很大不同。对于BERT来说,预测两个句子是否相连并不是太难。因此,在训练BERT完成Next Sentence Prediction 的任务时,