第十三讲-基于上下文的表征与NLP预训练模型
1 词向量知识回顾
1.1 词向量表征
- 现在我们可以获得一个单词的表示
- 我们开始时学过的单词向量
- Word2vec,GloVe,fastText
- 我们开始时学过的单词向量
1.2 预训练的词向量
- 我们可以随机初始化词向量,并根据我们自己的下游任务训练它们
- 但在绝大多数情况下,使用预训练词向量是有帮助的,因为它们本身是自带信息的 (我们可以在更大体量的预训练语料上训练得到它们)
1.3 未知词的词向量应用建议
简单且常见的解决方案:
训练时:词汇表\(\{\text { words occurring, say }, \geq 5 \text { times }\} \cup\{<\mathrm{UNK}>\}\)
- 将所有罕见的词 (数据集中出现次数小于 5) 都映射为\(<UNK>\),为其训练一个词向量
运行时:使用\(<UNK>\)代替词汇表之外的词 OOV
问题:
- 没有办法区分不同 UNK words,无论是身份还是意义
解决方案
使用字符级模型学习词向量
- 特别是在 QA 中,match on word identity 是很重要的,即使词向量词汇表以外的单词
尝试这些建议 (from Dhingra, Liu, Salakhutdinov, Cohen 2017)
如果测试时的\(<UNK>\)单词不在你的词汇表中,但是出现在你使用的无监督词嵌入中,测试时直接使用这个向量
此外,你可以将其视为新的单词,并为其分配一个随机向量,将它们添加到你的词汇表
帮助很大或者也许能帮点忙
你可以试试另一件事
- 将它们分解为词类 (如未知号码,大写等等),每种都对应一个 \(<UNK-class>\)
1.4 单词的表示
存在两个大问题
- 对于一个 word type 总是是用相同的表示,不考虑这个 word token
出现的上下文
- 我们可以进行非常细粒度的词义消歧
- 我们对一个词只有一种表示,但是单词有不同的方面,包括语义,句法行为,以及表达 / 含义
1.5 我们一直都有解决这个问题的办法吗?
- 在NLM中,我们直接将单词向量 (可能只在语料库上训练) 插入LSTM层
- 那些LSTM层被训练来预测下一个单词
- 但这些语言模型在每一个位置生成特定于上下文的词表示
1.6 论文解读 Peters et al. (2017): TagLM – “Pre-ELMo”
- 想法:想要获得单词在上下文的意思,但标准的 RNN 学习任务只在 task-labeled 的小数据上 (如 NER )
- 为什么不通过半监督学习的方式在大型无标签数据集上训练 NLM,而不只是词向量
1.7 标签语言模型 (Tag LM )
- 步骤3:在序列标记模型中同时使用单词嵌入和 LM 嵌入
- 步骤2:为输入序列中的每个标记准备单词嵌入和 LM 嵌入
- 步骤1:预训练词嵌入和语言模型
- 与上文无关的单词嵌入 + RNN model 得到的 hidden states 作为特征输入
- Char CNN / RNN + Token Embedding 作为 bi-LSTM 的输入
- 得到的 hidden states 与 Pre-trained bi-LM (冻结的) 的 hidden states 连接起来输入到第二层的 bi-LSTM 中
1.8 命名实体识别 (NER)
- 一个非常重要的NLP子任务:查找和分类文本中的实体
1.9 论文解读 Peters et al.(2017): TagLM-"Pre-ELMo"
- 语言模型在
Billion word benchmark
的8亿个训练单词上训练
语言模型观察结果
- 在监督数据集上训练的语言模型并不会受益
- 双向语言模型仅有助于 forward 过程,提升约 0.2
- 具有巨大的语言模型设计 (困惑度 30) 比较小的模型 (困惑度 48) 提升约 0.3
任务特定的BiLSTM观察结果
- 仅使用LM嵌入来预测并不是很好:88.17 F1
- 远低于仅在标记数据上使用 BiLSTM 标记器
1.10 论文解读 Also in the air: McCann et al.2017:CoVe
也有一种思路:使用训练好的序列模型,为其他NLP模型提供上下文
思路:机器翻译是为了保存意思,所以这也许是个好目标?
使用 seq2seq + attention NMT system 中的 Encoder,即 2 层 bi-LSTM,作为上下文提供者
所得到的 CoVe 向量在各种任务上都优于 GloVe 向量
但是,结果并不像其他幻灯片中描述的更简单的 NLM 训练那么好,所以似乎被放弃了
- 也许NMT只是比语言建模更难?
- 或许有一天这个想法会回来?
2.ELMo模型
2.1 论文解读 Peters et al. (2018): ELMo: Embeddings from Language Models
单词标记向量或上下文词向量的突破
使用长上下文而不是上下文窗口学习词标记向量 (这里,整个句子可能更长)
学习深度 Bi-NLM,并在预测中使用它的所有层
训练一个双向语言模型 (LM)
目标是效果 OK 但不要太大的语言模型 (LM)
- 使用 2 个 biLSTM 层
- (仅) 使用字符CNN构建初始单词表示
- 2048 个 char n-gram filters 和 2 个 highway layers,512 维的 projection
- 4096 dim hidden/cell LSTM状态,使用 512 dim 的对下一个输入的投影
- 使用残差连接
- 绑定 token 的输入和输出的参数 (softmax),并将这些参数绑定到正向和反向语言模型 (LM) 之间
ELMo 学习 biLM 表示的特定任务组合
这是一个创新,TagLM 中仅仅使用堆叠 LSTM 的顶层,ELMo 认为 BiLSTM 所有层都是有用的
\[ \begin{aligned} R_{k} &=\left\{\mathbf{x}_{k}^{L M}, \overrightarrow{\mathbf{h}}_{k, j}^{L M}, \overleftarrow{\mathbf{h}}_{k, j}^{L M} \mid j=1, \ldots, L\right\} \\ &=\left\{\mathbf{h}_{k, j}^{L M} \mid j=0, \ldots, L\right\} \end{aligned} \]
\[ \mathbf{E L M o}_{k}^{\text {task }}=E\left(R_{k} ; \Theta^{\text {task }}\right)=\gamma^{\text {task }} \sum_{j=0}^{L} s_{j}^{\text {task }} \mathbf{h}_{k, j}^{L M} \]
\(\gamma^{t a s k}\)衡量 ELMo 对任务的总体有用性,是为特定任务学习的全局比例因子
\(s^{task}\)是 softmax 归一化的混合模型权重,是 BiLSTM 的加权平均值的权重,对不同的任务是不同的,因为不同的任务对不同层的 BiLSTM 的
首先运行 biLM 获取每个单词的表示
然后,让 (无论什么) 最终任务模型使用它们
- 冻结 ELMo 的权重,用于监督模型
- 将 ELMo 权重连接到特定于任务的模型中
- 细节取决于任务
- 像 TagLM 一样连接到中间层是典型的
- 可以在生产输出时提供更多的表示,例如在问答系统中
- 细节取决于任务
2.2 ELMo在序列标记器中的使用
2.3 ELMo :层权重
- 这两个 biLSTM NLM 层有不同的用途 / 含义
- 低层更适合低级语法,例如
- 词性标注(part-of-speech tagging)、句法依赖(syntactic dependency)、NER
- 高层更适合更高级别的语义
- 情绪、语义角色标记、问答系统、SNLI
- 低层更适合低级语法,例如
- 这似乎很有趣,但它是如何通过两层以上的网络来实现的看起来更有趣
3.ULMfit模型
3.1 ULMfit
转移 NLM 知识的一般思路是一样的
这里应用于文本分类
在大型通用领域的无监督语料库上使用 biLM 训练
在目标任务数据上调整 LM
对特定任务将分类器进行微调
使用合理大小的
1 GPU
语言模型,并不是真的很大在LM调优中要注意很多
- 不同的每层学习速度
- 倾斜三角形学习率 (STLR) 计划
学习分类器时逐步分层解冻和STLR
使用\(\left[h_{T}, \operatorname{maxpool}(\mathbf{h}), \text { meanpool }(\mathbf{h})\right]\)进行分类
使用大型的预训练语言模型,是一种提高性能的非常有效的方法
4.Transformer结构
4.1 Transformer介绍
- 所有这些模型都是以Transformer为主结构的,我们应该学习一下Transformer吧
补充说明
- Transformer 不仅很强大,而且允许扩展到更大的尺寸
4.2 Transformers 动机
我们想要并行化,但是RNNs本质上是顺序的
尽管有 GRUs 和 LSTMs,RNNs 仍然需要注意机制来处理长期依赖关系——否则状态之间的 path length 路径长度 会随着序列增长
但如果注意力让我们进入任何一个状态……也许我们可以只用注意力而不需要RNN?
4.3 Transformer 概览
- 序列到序列编码解码模型,但它是非循环非串行结构
- 任务:平行语料库的机器翻译
- 预测每个翻译单词
- 最终成本/误差函数是 softmax 分类器基础上的标准交叉熵误差
4.4 Transformer 基础
- 自学 transformer
- 主要推荐资源
- http://nlp.seas.harvard.edu/2018/04/03/attention.html
- The Annotated Transformer by Sasha Rush
- 一个使用PyTorch的Jupyter笔记本,解释了一切!
- 主要推荐资源
- 现在:我们定义 Transformer 网络的基本构建块:第一,新的注意力层
4.5 点乘注意力 Dot-Product Attention
输入:对于一个输出而言的查询\(q\)和一组键-值对\((k-v)\)
Query,keys,values,and output 都是向量
输出值的加权和
权重的每个值是由查询和相关键的内积计算结果
Query 和 keys 有相同维数\(d_k\),value 的维数为\(d_v\)
\[ A(q, K, V)=\sum_{i} \frac{e^{q \cdot k_{i}}}{\sum_{j} e^{q \cdot k_{j}}} v_{i} \]
4.6 点乘注意力矩阵表示法
- 当我们有多个查询\(q\)时,我们将它们叠加在一个矩阵\(Q\)中
- 变成\(A(Q, K, V)=\operatorname{softmax}\left(Q K^{T}\right) V\)
4.7 缩放点乘注意力
问题:\(d_k\)变大时,\(q^Tk\)的方差增大 → 一些 softmax 中的值的方差将会变大 → softmax 得到的是峰值 → 因此梯度变小了
解决方案:通过 query / key 向量的长度进行缩放
\[ A(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) V \]
4.8 编码器中的自注意力
输入单词向量是 queries,keys and values
换句话说:这个词向量自己选择彼此
词向量堆栈= Q = K = V
我们会通过解码器明白为什么我们在定义中将他们分开
4.9 多头注意力
- 简单 self-attention 的问题
- 单词只有一种相互交互的方式
- 解决方案:多头注意力
- 首先,通过矩阵\(W\)将\(Q\),\(K\),\(V\)映射到\(h=8\)的许多低维空间
- 然后,应用注意力,然后连接输出,通过线性层
\[ \operatorname{MultiHead}(\boldsymbol{Q}, \boldsymbol{K}, \boldsymbol{V})=\operatorname{Concat}\left(\right. head _{1}, \ldots , head \left._{h}\right) where \ head\ hention _{i}= Attention ( \left.Q W_{i}^{Q}, K W_{i}^{K}, V W_{i}^{V}\right) \]
4.10 完整的transformer模块
每个 Block 都有两个子层
多头 attention
两层的前馈神经网络,使用 ReLU
这两个子层都
- 残差连接以及层归一化
- LayerNorm(x+Sublayer(x))
- 层归一化将输入转化为均值是0,方差是1,每一层和每一个训练点 (并且添加了两个参数)
\[ \mu^{l}=\frac{1}{H} \sum_{i=1}^{H} a_{i}^{l} \quad \sigma^{l}=\sqrt{\frac{1}{H} \sum_{i=1}^{H}\left(a_{i}^{l}-\mu^{l}\right)^{2}} \quad h_{i}=f\left(\frac{g_{i}}{\sigma_{i}}\left(a_{i}-\mu_{i}\right)+b_{i}\right) \]
4.11 编码器输入
实际的词表示是 byte-pair 编码
还添加了一个 positional encoding 位置编码,相同的词语在不同的位置有不同的整体表征
\[ \left\{\begin{array}{l} P E(p o s, 2 i)=\sin \left(p o s / 10000^{2 i / d_{\text {model }}}\right) \\ P E(\operatorname{pos}, 2 i+1)=\cos \left(p o s / 10000^{2 i / d_{\text {model }}}\right) \end{array}\right. \]
4.12 完整编码器Encoder
encoder 中,每个 Block 都是来自前一层的\(Q,K,V\)
Blocks 被重复 6 次 (垂直方向)
在每个阶段,你可以通过多头注意力看到句子中的各个地方,累积信息并将其推送到下一层。在任一方向上的序列逐步推送信息来计算感兴趣的值
非常善于学习语言结构
4.13 注意力可视化
4.14 Transformer解码器
decoder 中有两个稍加改变的子层
对之前生成的输出进行 Masked decoder self-attention
Encoder-Decoder Attention,queries 来自于前一个 decoder 层,keys 和 values 来自于 encoder 的输出
Blocks 同样重复 6 次
4.15 Transformer的技巧与建议
细节(论文/之后的讲座)
Byte-pair encodings
Checkpoint averaging
Adam 优化器控制学习速率变化
训练时,在每一层添加残差之前进行 Dropout
标签平滑
带有束搜索和长度惩罚的自回归解码
因为 transformer 正在蔓延,但他们很难优化并且不像LSTMs那样开箱即用,他们还不能很好与其他任务的构件共同工作
5.BERT模型
5.1 论文解读 BERT: Devlin, Chang, Lee, Toutanova (2018)
BERT:用于语言理解的预训练深度双向 transformers
问题:语言模型只使用左上下文或右上下文,但语言理解是双向的
为什么LMs是单向的?
- 原因1:方向性对于生成格式良好的概率分布是有必要的 [我们不在乎这个]
- 原因2:双向编码器中单词可以
看到自己
解决方案:掩盖k%的输入单词,然后预测 masked words
不再是传统的计算生成句子的概率的语言模型,目标是填空
- 总是使用k=15%
Masking 太少:训练太昂贵
Masking 太多:没有足够的上下文
GPT 是经典的单项的语言模型
ELMo 是双向的,但是两个模型是完全独立训练的,只是将输出连接在一起,并没有使用双向的 context
BERT 使用 mask 的方式进行整个上下文的预测,使用了双向的上下文信息
5.2 BERT 模型微调
- 只学习一个建立在顶层的分类器,微调的每个任务
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!