之前的课上我们已经学习了利用词向量表示词的方法,常见的词向量模型包括:Word2vec, GloVe, fastText。
最常见的解决方案是:
训练时:词汇表 Vocab 为 { words occurring, say, ≥ 5 times } ∪ { < UNK > } \{\text { words occurring, say, } \geq 5 \text { times }\} \cup\{<\text{UNK}>\} { words occurring, say, ≥5 times }∪{<UNK>}将所有罕见的词(数据集中出现次数小于 5)都映射为 <UNK>,为其训练一个词向量运行时:使用 <UNK>代替词汇表之外的词 OOV该解决方案存在的问题是:没有办法区分不同UNK话说,无论是身份还是意义。为了解决这一问题,提出了两种进一步的解决方案:
使用字符级模型学习期词向量,特别是在 QA 中,match on word identity 是很重要的,即使词向量词汇表以外的单词;try these tips (from Dhingra, Liu, Salakhutdinov, Cohen 2017) 如果测试时的 <UNK>单词不在你的词汇表中,但是出现在你使用的无监督词嵌入中,测试时直接使用这个向量;此外,你可以将其视为新的单词,并为其分配一个随机向量,将它们添加到你的词汇表。问题1:对于一个 word type 总是是用相同的表示,不考虑这个 word token 出现的上下文
比如 star 这个单词,有天文学上的含义以及娱乐圈中的含义我们可以进行非常细粒度的词义消歧问题2:我们对一个词只有一种表示,但是单词有不同的方面,包括语义,句法行为,以及表达 / 含义
表达:同样的意思可以是用多个单词表示,他们的词义是一样的模型结构如下:
该模型的思想概括为:
在大型通用领域的无监督语料库上使用 biLM 训练在目标任务数据上调整 LM对特定任务将分类器进行微调结构为:
Attention is all you need. 2017. Aswani, Shazeer, Parmar, Uszkoreit, Jones, Gomez, Kaiser, Polosukhin
Non-recurrent sequence-to-sequence encoder-decoder model任务:平行语料库的机器翻译预测每个翻译单词最终成本/误差函数是 softmax 分类器基础上的标准交叉熵误差该模型的结构为:
BERT (Bidirectional Encoder Representations from Transformers):
Pre-training of Deep Bidirectional Transformers for Language Understanding
在语言模型上,BERT使用的是Transformer编码器,并且设计了一个小一点Base结构和一个更大的Large网络结构。步骤大体如下:
Pre-training Task 1#: Masked LM
第一步预训练的目标就是做语言模型,即bidirectional。 意思就是如果使用预训练模型处理其他任务,那人们想要的肯定不止某个词左边的信息,而是左右两边的信息。而考虑到这点的模型ELMo只是将left-to-right和right-to-left分别训练拼接起来。直觉上来讲人们其实想要一个deeply bidirectional的模型,但是普通的LM又无法做到,因为在训练时可能会“穿越”。 在训练过程中随机mask 15%的token,而不是把像CBOW一样把每个词都预测一遍。从结构上看输入输出是长度一样的sequence,这样模型实际上在做sequence-level的LM。 Mask如何做也是有技巧的,如果一直用标记[MASK]代替会影响模型,所以随机mask的时候10%的单词会被替代成其他单词,10%的单词不替换,剩下80%才被替换为[MASK]。要注意的是Masked LM预训练阶段模型是不知道真正被mask的是哪个词,所以模型每个词都要关注。 Pre-training Task 2#: Next Sentence Prediction 因为涉及到QA和NLI之类的任务,增加了第二个预训练任务,目的是让模型理解两个句子之间的联系。训练的输入是句子A和B,B有一半的几率是A的下一句,输入这两个句子,模型预测B是不是A的下一句。预训练的时候可以达到97-98%的准确度。 Fine-tunning 分类:对于sequence-level的分类任务,BERT直接取第一个[CLS]token的final hidden state ,加一层权重后softmax预测label proba: 其他预测任务需要进行一些调整,如图: