Attention -> Transformer -> Bert
Attention
https://arxiv.org/pdf/1706.03762.pdf
网上博客很多,但讲Attention有两个版本
- Q、K、V结构。https://www.cnblogs.com/cx2016/p/12800385.html
- 从注意力机制开始讲。比如《深度学习》
《动手学深度学习》里把这两个串到一起了,很不错。
Q代表解码器的每一层,K、V代表编码器每一层的隐藏变量。Q、K、V形式是把Anntetion进行矢量化,方便计算。
Transformer
- attention是在seq2seq的基础上给隐藏层变量添加了新的信息,这些信息=输入层各隐藏向量的加权和
- self-attention中 1/sqrt(k)缩放
Dot-product attention 和 additive attention 理论复杂度差不多,但是实际上dot-product attention 更快,因此选择了前者。当k较小时,两者的效果差不多,k较大时,dot-product 较差,猜测是k较大时,容易引起梯度出现极小值,因此缩放 1/sqrt(k),抵消此部分影响。 - Self-attention中怎么把batch_size 加进去:self-attention进行Q、K、V计算时,是三维数组进行的计算,(a, b, c) * (c, x, y),只要相邻的两维长度相同即可
- 正则
- Residual add 之前进行dropout
- FFN:relu激活之后进行dropout
- multi-head attention:利用self-attention将多个head concat,再乘以一个转化矩阵
- FFN有两个线性层,神经元个数:d_model -> dim_feedforward -> d_model;中间层用relu激活,末层不需要
- 影响序列长度依赖性的一个重要因素,就是信号在输入-输出的网络结构中传输的长度,该长度越短,依赖性学习的就越好。因为信息丢失?
- 从计算复杂度上讲,句子长度n越小,self-attention的性能就优于RNN,因为self-attention的复杂度为 n ^ 2 * d,RNN的复杂度为 n * d ^ 2。那么n很大的时候,self-attention的性能就会下降,要怎么优化呢?
- attention对模型解释性的贡献
- 残差网络使得参数迭代过程更加平滑
- Layer normalization使模型训练更快
- 疑问
- Transformer解码层为什么都要mask:6层中第一层需要,其他层要不要都行,为了方便都要了
核心源码
- Transformer解码层为什么都要mask:6层中第一层需要,其他层要不要都行,为了方便都要了
def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, activation="relu"):
super(TransformerEncoderLayer, self).__init__()
self.self_attn = MultiheadAttention(d_model, nhead, dropout=dropout)
# Implementation of Feedforward model
self.linear1 = Linear(d_model, dim_feedforward)
self.dropout = Dropout(dropout)
self.linear2 = Linear(dim_feedforward, d_model)
self.norm1 = LayerNorm(d_model)
self.norm2 = LayerNorm(d_model)
self.dropout1 = Dropout(dropout)
self.dropout2 = Dropout(dropout)
self.activation = _get_activation_fn(activation)
def __setstate__(self, state):
if 'activation' not in state:
state['activation'] = F.relu
super(TransformerEncoderLayer, self).__setstate__(state)
def forward(self, src: Tensor, src_mask: Optional[Tensor] = None, src_key_padding_mask: Optional[Tensor] = None) -> Tensor:
src2 = self.self_attn(src, src, src, attn_mask=src_mask,
key_padding_mask=src_key_padding_mask)[0]
src = src + self.dropout1(src2)
src = self.norm1(src)
src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))
src = src + self.dropout2(src2)
src = self.norm2(src)
return src
Bert
Contextualized word Embedding: 输入整句话,考虑上下文,输出每个单词的Embedding
- Unidirectional Transformer -> Biddirectional Transformer
- Standard LM -> Masked LM
- Only Token-level prediction -> Next Sentence prediction