机器翻译(MT):将一段文本从一种语言自动翻译为另一种语言,用神经网络解决这个问题通常称为神经机器翻译(NMT)。
主要特征:输出是单词序列而不是单个单词。 输出序列的长度可能与源序列的长度不同。
首先,将数据集清洗、转化为神经网络的输入minbatch,分词,建立词典。# Encoder-Decoder
encoder:输入到隐藏状态
decoder:隐藏状态到输出
在Dot-product Attention中,key与query维度需要一致,在MLP Attention中则不需要。
seq2seq模型的预测需人为设定终止条件,设定最长序列长度或者输出[EOS]结束符号,若不加以限制则可能生成无穷长度序列。
注意力机制本身有高效的并行性,但引入注意力并不能改变seq2seq内部RNN的迭代机制,因此无法加速模型训练。
高维张量的矩阵乘法可用于并行计算多个位置的注意力分数。
计算点积后除以d\sqrt{d}d以减轻向量维度对注意力权重的影响。
可视化注意力权重的二维矩阵有助于分析序列内部的依赖关系。
训练
预测
简单greedy search:
维特比算法:选择整体分数最高的句子(搜索空间太大)
集束搜索:
关于Transformer描述正确的是:自注意力模块理论上可以捕捉任意距离的依赖关系。
在Transformer模型中,注意力头数为h,嵌入向量和隐藏状态维度均为d,那么一个多头注意力层所含的参数量是:4hd24hd^24hd2 h个注意力头中,每个的参数量为3d23d^23d2 ,最后的输出层形状为hd \times dhd×d,所以参数量共为4hd24hd^24hd2 。
层归一化有利于加快收敛,减少训练时间成本
层归一化对一个中间层的所有神经元进行归一化
批归一化(Batch Normalization)才是对每个神经元的输入数据以mini-batch为单位进行汇总
层归一化的效果不会受到batch大小的影响
在之前的章节中,我们已经介绍了主流的神经网络架构如卷积神经网络(CNNs)和循环神经网络(RNNs)。让我们进行一些回顾:
CNNs 易于并行化,却不适合捕捉变长序列内的依赖关系。 RNNs 适合捕捉长距离变长序列的依赖,但是却难以实现并行化处理序列。为了整合CNN和RNN的优势,[Vaswani et al., 2017] 创新性地使用注意力机制设计了Transformer模型。该模型利用attention机制实现了并行化捕捉序列依赖,并且同时处理序列的每个位置的tokens,上述优势使得Transformer模型在性能优异的同时大大减少了训练时间。
图10.3.1展示了Transformer模型的架构,与9.7节的seq2seq模型相似,Transformer同样基于编码器-解码器架构,其区别主要在于以下三点:
Transformer blocks:将seq2seq模型重的循环网络替换为了Transformer Blocks,该模块包含一个多头注意力层(Multi-head Attention Layers)以及两个position-wise feed-forward networks(FFN)。对于解码器来说,另一个多头注意力层被用于接受编码器的隐藏状态。 Add and norm:多头注意力层和前馈网络的输出被送到两个“add and norm”层进行处理,该层包含残差结构以及层归一化。 Position encoding:由于自注意力层并没有区分元素的顺序,所以一个位置编码层被用于向序列元素里添加位置信息。Fig.10.3.1 Transformer架构. Fig.10.3.1\ Transformer 架构. Fig.10.3.1 Transformer架构.
多头注意力层在我们讨论多头注意力层之前,先来迅速理解以下自注意力(self-attention)的结构。自注意力模型是一个正规的注意力模型,序列的每一个元素对应的key,value,query是完全一致的。如图10.3.2 自注意力输出了一个与输入长度相同的表征序列,与循环神经网络相比,自注意力对每个元素输出的计算是并行的,所以我们可以高效的实现这个模块。
Fig.10.3.2 自注意力结构 Fig.10.3.2\ 自注意力结构 Fig.10.3.2 自注意力结构
多头注意力层包含hhh个并行的自注意力层,每一个这种层被成为一个head。对每个头来说,在进行注意力计算之前,我们会将query、key和value用三个现行层进行映射,这hhh个注意力头的输出将会被拼接之后输入最后一个线性层进行整合。
Fig.10.3.3 多头注意力 Fig.10.3.3\ 多头注意力 Fig.10.3.3 多头注意力
假设query,key和value的维度分别是dqd_qdq、dkd_kdk和dvd_vdv。那么对于每一个头i=1,…,hi=1,\ldots,hi=1,…,h,我们可以训练相应的模型权重Wq(i)∈Rpq×dqW_q^{(i)} \in \mathbb{R}^{p_q\times d_q}Wq(i)∈Rpq×dq、Wk(i)∈Rpk×dkW_k^{(i)} \in \mathbb{R}^{p_k\times d_k}Wk(i)∈Rpk×dk和Wv(i)∈Rpv×dvW_v^{(i)} \in \mathbb{R}^{p_v\times d_v}Wv(i)∈Rpv×dv,以得到每个头的输出:
o(i)=attention(Wq(i)q,Wk(i)k,Wv(i)v) o^{(i)} = attention(W_q^{(i)}q, W_k^{(i)}k, W_v^{(i)}v) o(i)=attention(Wq(i)q,Wk(i)k,Wv(i)v)
这里的attention可以是任意的attention function,比如前一节介绍的dot-product attention以及MLP attention。之后我们将所有head对应的输出拼接起来,送入最后一个线性层进行整合,这个层的权重可以表示为Wo∈Rd0×hpvW_o\in \mathbb{R}^{d_0 \times hp_v}Wo∈Rd0×hpv
o=Wo[o(1),…,o(h)] o = W_o[o^{(1)}, \ldots, o^{(h)}] o=Wo[o(1),…,o(h)]
接下来我们就可以来实现多头注意力了,假设我们有h个头,隐藏层权重 hidden_size=pq=pk=pvhidden\_size = p_q = p_k = p_vhidden_size=pq=pk=pv 与query,key,value的维度一致。除此之外,因为多头注意力层保持输入与输出张量的维度不变,所以输出feature的维度也设置为 d0=hidden_sized_0 = hidden\_sized0=hidden_size。
基于位置的前馈网络Transformer 模块另一个非常重要的部分就是基于位置的前馈网络(FFN),它接受一个形状为(batch_size,seq_length, feature_size)的三维张量。Position-wise FFN由两个全连接层组成,他们作用在最后一维上。因为序列的每个位置的状态都会被单独地更新,所以我们称他为position-wise,这等效于一个1x1的卷积。
与多头注意力层相似,FFN层同样只会对最后一维的大小进行改变;除此之外,对于两个完全相同的输入,FFN层的输出也将相等。
除了上面两个模块之外,Transformer还有一个重要的相加归一化层,它可以平滑地整合输入和其他层的输出,因此我们在每个多头注意力层和FFN层后面都添加一个含残差连接的Layer Norm层。这里 Layer Norm 与7.5小节的Batch Norm很相似,唯一的区别在于Batch Norm是对于batch size这个维度进行计算均值和方差的,而Layer Norm则是对最后一维进行计算。层归一化可以防止层内的数值变化过大,从而有利于加快训练速度并且提高泛化性能。 (ref)