材料
- Understanding LSTM Networks
- 🎦 李沐:动手学习深度学习V2
- 📓 动手学深度学习
- 📄 Attention Is All You Need
- 📄 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
语言模型
- RNN: RNN和LSTM都是上个世纪的算法,201x年深度学习火了以后被挖出来.
- LSTM: RNN改进型,基本的想法就是乘法改加法,让反向传播可以传的更远一点. 和后来的ResNet的想法就有异曲同工的意思.
- GRU: 出现的比较晚,LSTM改进型, 一方面让计算变少,也去掉了LSTM增加出来的一个状态.
- LSMT / GRU: 实现的效果差不多. GRU的运算速度快一些, 基本都在被比较多的使用.不会去使用原始的RNN.
- Transformer: 仅使用线性层和Attention机制.
RNN
RNN/LSTM/GRU
RNN模型是在序列上从0开始迭代到T, 迭代太多次后, 在计算梯度的时候矩阵连乘后梯度很容易爆炸或者消失.
- 梯度消失: LSTM/GRU主要就是来缓解梯度消失的问题. 也在一定程度上缓解爆炸的问题.
- 梯度爆炸: 一般可以通过剪裁梯度(Gradient Clipping)来强行修改太大的梯度, 让结果不会出现nan.
Deeper and Dropout
每个时间步可以在多个层上传递然后输出. 在不同层之间可以使用Dropout, 不能在时间步之间使用,会让隐藏状态丢失效果不好. 所以一般的RNN实现都需要多层才能使用Dropout.
Bidirectional
序列都是按照正向计算的,但是反向的信息某些情况下也有点意思, 所以, 两层正着反着都算一遍, 然后结果拼接起来.
但是双向RNN不适合生成, 生成的时候没有后面的序列信息, 所以比较适合用来做特征提取.
Sequence to Sequence 序列到序列
翻译是其中特别重要的领域.其他的比如文字到图片,图片到文字也是类似.
Encoder-Decoder Architecture 编码器-解码器架构
- Encoder: 抽取特征, 类似于CNN层
- Decoder: 解码器将Encoder抽取的特征用另外的形式表达出来. 翻译就是用另外一个语言来表达Encoder的思想.
Seq2seq
使用RNN作为编码器和解码器,来解决翻译的问题. 特别是Encoder
中使用的Bidirectional RNN
.
Beam Search 束搜索
在预测一个序列的时候, 我们的目标是这个序列的联合概率最大:
- 贪心: 永远只取下一个最大可能的值做为解. 局部最优往往不是全局最优.
- 穷举: NP hard
- Beam Search: 每次我保留K个最好的答案, 然后来找出下个K个最好的子序列.
所以Beam Search是一个折中的方案, 一般K可能会选择5-10之间, 大概率就可以获取一个不错的结果.
Attention 注意力
受人类眼睛的注意力机制的启发.考虑随意线索, 根据query来选择环境中合适的key-value pair.
非参数注意力池化层
- 平均池化: 简单, 没用
- Nadaraya-Watson核回归(60年代): 使用核方法, 选择相近的数据. 和现在使用的方法相近.
注意力分数和权重
- Additive Attention(加性注意力): query和key转换为和value一样的长度, 转换矩阵可以学到参数. 分数通过tanh缩放成注意力权重.
- Scaled Dot-Product Attention: 当query和key的维度相同, query和key之间直接乘法就可以得到注意力分数,分数通过除以√d来缩放成最终注意力权重.
Abhdanau Attention
将注意力的机制放在解码器,每一步用当前输入去查询encoder output, 让模型来注意需要注意的部分.
Self Attention 自注意力
query
, key
and value
都是自己. Self Attention这个算法对位置不敏感, 需要将位置信息加入到输入中.
- Positional Encoding, 位置编码: 将位置通过固定的函数编码加到输入中.
- Positional Embedding, 位置内嵌: 用一个层来学习位置信息,编码后拼接到输入.
Transformer中使用的是Positional Encoding方法
We also experimented with using learned positional embeddings [9] instead, and found that the two
versions produced nearly identical results (see Table 3 row (E)). We chose the sinusoidal version
because it may allow the model to extrapolate to sequence lengths longer than the ones encountered
during training.
所以按照这个理解, 如果我们数据量足够的时候使用Positional Embedding是个更简单的选择.
CNN | RNN | Self Attention | |
---|---|---|---|
计算复杂度 | O(knd^2) | O(nd^2) | O(n^2d) |
并行度 | O(n) | O(1) | O(n) |
最长路径 | O(n/k) | O(n) | O(1) |
- RNN的路径有点长,所以需要使用Bidirectional RNN, Attention机制来缓解, 让他可以注意到更靠前的输入.
- CNN的并行度相比于RNN要好特别多.
- Self Attention当序列很长的时候计算复杂度比较大. 不过TPU这种专门的芯片会特别有效率.
Transformer
原始论文是一个Encoder-Decoder Architecture. 不再使用RNN,仅使用全连接和注意力机制.
Multi-Head Self Attention 多头注意力
希望通过多个self attention可以学到不同的东西.
Multi-head attention allows the model to jointly attend to information from different representation
subspaces at different positions.
使用了一个特别的trick, 多个self-attention计算太大了, 所以将自己维度分成多片进行self attention. 就是希望不增加计算量的前提下享受到一定的Multi-head self attention的好处.
Due to the reduced dimension of each head, the total computational cost
is similar to that of single-head attention with full dimensionality.
Masked multi-head attention
: 训练时在Decoder的Self Attention中不能注意到后面的内容, 所以需要Mask一下.
Positionwise FFN 基于位置的前馈网络
这是两层的全连接层, 但是不会将批量中序列中所有维度拉平然后进行转换, 而是序列中每个元素向量单独进行转换. 所以及时kernel=1的CNN层.但这就是Pytorch的默认实现,所以就是普普通通的Linear😂.
Another way of describing this is as two convolutions with kernel size 1.
Add & Normalization
Add就是一个Residual connection, 常见技巧, 添加后网络可以做的很深.
Layer Normalization: 这里不能使用Batch Normalization, BN和Batch长度有关,特别Decoder的时候,长度是变化的,会不稳定.
BERT
在NLP中做迁移学习(Transfer Learning). 目标是做一个类似于CNN的预训练的模型可以微调做不同的任务. BERT就是只使用Transformer中Encoder部分.
有两个不同的模型:
- Base: parameters 110M, (blocks=12, hidden size = 768, heads = 12)
- Large: parameters 340M, (blocks = 24, hidden size = 1024, heads = 26)
在Transformer的主要创新:
- 在大规模数据上训练 > 3B词: 训练出了一个很大很深的网络.
- 将每个样本变成一个句子对: 输入和目标值同时输入, 使用Segmentation Embedding标记是输入还是输出, 使用Positional Embedding来学习位置信息.
训练任务
- 带掩码的语言模型 (Masked LM): mask work
- 下一句子预测(Next Sentence Prediction, NSP): 预测后面是否是相邻的句子.
常见度量(Metrics)
Perplexity 困惑度
就是Cross entropy loss再做e的指数. 还是信息论. 不过历史原因就使用Perplexity.
- 1: 最完美的状态,一模一样
- 无穷大: 最差的状态
BLEU
主要用在翻译这种Seqence to Sequence的场景
- 奖励长的句子, 长的句子生成会比较难一点
- 惩罚短的句子: 短的句子容易太短没意义