深度学习d4:机器翻译及相关技术;注意力机制与Seq2seq模型;Transformer
机器翻译
指将一段文本从一种语言自动翻译到另一种语言
-
读取和预处理数据
# 将一个序列中所有的词记录在all_tokens中以便之后构造词典,然后在该序列后面添加PAD直到序列 # 长度变为max_seq_len,然后将序列保存在all_seqs中 def process_one_seq(seq_tokens, all_tokens, all_seqs, max_seq_len): all_tokens.extend(seq_tokens) seq_tokens += [EOS] + [PAD] * (max_seq_len - len(seq_tokens) - 1) all_seqs.append(seq_tokens) # 使用所有的词来构造词典。并将所有序列中的词变换为词索引后构造NDArray实例 def build_data(all_tokens, all_seqs): vocab = text.vocab.Vocabulary(collections.Counter(all_tokens), reserved_tokens=[PAD, BOS, EOS]) indices = [vocab.to_indices(seq) for seq in all_seqs] return vocab, nd.array(indices)
使用
def read_data(max_seq_len): # in和out分别是input和output的缩写 in_tokens, out_tokens, in_seqs, out_seqs = [], [], [], [] #读取法语-英语数据集 with io.open('../data/fr-en-small.txt') as f: # lines = f.readlines() for line in lines: #法语和英语之间用\t分割的 in_seq, out_seq = line.rstrip().split('\t') #把法语和英语用空格分隔开 in_seq_tokens, out_seq_tokens = in_seq.split(' '), out_seq.split(' ') if max(len(in_seq_tokens), len(out_seq_tokens)) > max_seq_len - 1: continue # 如果加上EOS后长于max_seq_len,则忽略掉此样本 #预处理序列 process_one_seq(in_seq_tokens, in_tokens, in_seqs, max_seq_len) process_one_seq(out_seq_tokens, out_tokens, out_seqs, max_seq_len) #构造词典 in_vocab, in_data = build_data(in_tokens, in_seqs) out_vocab, out_data = build_data(out_tokens, out_seqs) return in_vocab, out_vocab, gdata.ArrayDataset(in_data, out_data)
-
含注意力机制的编码器—解码器
编码器:
将输入语言的词索引通过词嵌入层得到词的表征,然后输入到一个多层门控循环单元中。class Encoder(nn.Block): def __init__(self, vocab_size, embed_size, num_hiddens, num_layers, drop_prob=0, **kwargs): super(Encoder, self).__init__(**kwargs) #嵌入层 self.embedding = nn.Embedding(vocab_size, embed_size) #循环神经网络 self.rnn = rnn.GRU(num_hiddens, num_layers, dropout=drop_prob) def forward(self, inputs, state): # 输入形状是(批量大小, 时间步数)。将输出互换样本维和时间步维 embedding = self.embedding(inputs).swapaxes(0, 1) return self.rnn(embedding, state) def begin_state(self, *args, **kwargs): return self.rnn.begin_state(*args, **kwargs)
注意力机制:
-
Dense的flatten选项
当输入维度大于2时(即不止行列时),dense会默认把除第一维歪的维度均视作特征维,然后自动转换为行为样本、列为特征的二维矩阵。但若只希望将输入的最后一维作为特征,其他维度不变,那么就把Dense实例的flatten选项设为False。
训练时的模型:
预测时的模型:
两个是不一样的!
注意力机制
由来 :翻译的过程像是解码器的每一时间步对输入序列中不同时间步的表征或编码信息分配不同的注意力一样。
以循环神经网络为例,注意力机制通过对编码器所有时间步的隐藏状态做加权平均来得到背景变量。解码器在每一时间步调整这些权重,即注意力权重,从而能够在不同时间步分别关注输入序列中的不同部分并编码进相应时间步的背景变量。(因人而异)
记ct′\boldsymbol{c}_{t'}ct′是解码器在时间步t′t't′的背景变量,那么解码器在该时间步的隐藏状态可以改写为
st′=g(yt′−1,ct′,st′−1).\boldsymbol{s}_{t'} = g(\boldsymbol{y}_{t'-1}, \boldsymbol{c}_{t'}, \boldsymbol{s}_{t'-1}).st′=g(yt′−1,ct′,st′−1).
难点在于:
- 计算背景变量
首先,函数 𝑎 根据解码器在时间步1的隐藏状态和编码器在各个时间步的隐藏状态计算softmax运算的输入。softmax运算输出概率分布并对编码器各个时间步的隐藏状态做加权平均,从而得到背景变量。
具体来说,令编码器在时间步ttt的隐藏状态为ht\boldsymbol{h}_tht,且总时间步数为TTT。那么解码器在时间步t′t't′的背景变量为所有编码器隐藏状态的加权平均:
ct′=∑t=1Tαt′tht,\boldsymbol{c}_{t'} = \sum_{t=1}^T \alpha_{t' t} \boldsymbol{h}_t,ct′=t=1∑Tαt′tht,
其中给定t′t't′时,权重αt′t\alpha_{t' t}αt′t在t=1,…,Tt=1,\ldots,Tt=1,…,T的值是一个概率分布。为了得到概率分布,我们可以使用softmax运算:
αt′t=exp(et′t)∑k=1Texp(et′k),t=1,…,T.\alpha_{t' t} = \frac{\exp(e_{t' t})}{ \sum_{k=1}^T \exp(e_{t' k}) },\quad t=1,\ldots,T.αt′t=∑k=1Texp(et′k)exp(et′t),t=1,…,T.
现在,我们需要定义如何计算上式中softmax运算的输入et′te_{t' t}et′t。由于et′te_{t' t}et′t同时取决于解码器的时间步t′t't′和编码器的时间步ttt,我们不妨以解码器在时间步t′−1t'-1t′−1的隐藏状态st′−1\boldsymbol{s}_{t' - 1}st′−1与编码器在时间步ttt的隐藏状态ht\boldsymbol{h}_tht为输入,并通过函数aaa计算et′te_{t' t}et′t:
et′t=a(st′−1,ht).e_{t' t} = a(\boldsymbol{s}_{t' - 1}, \boldsymbol{h}_t).et′t=a(st′−1,ht).
这里函数aaa有多种选择,如果两个输入向量长度相同,一个简单的选择是计算它们的内积a(s,h)=s⊤ha(\boldsymbol{s}, \boldsymbol{h})=\boldsymbol{s}^\top \boldsymbol{h}a(s,h)=s⊤h。而最早提出注意力机制的论文则将输入连结后通过含单隐藏层的多层感知机变换 [1]:
a(s,h)=v⊤tanh(Wss+Whh),a(\boldsymbol{s}, \boldsymbol{h}) = \boldsymbol{v}^\top \tanh(\boldsymbol{W}_s \boldsymbol{s} + \boldsymbol{W}_h \boldsymbol{h}),a(s,h)=v⊤tanh(Wss+Whh),
其中v\boldsymbol{v}v、Ws\boldsymbol{W}_sWs、Wh\boldsymbol{W}_hWh都是可以学习的模型参数。
-
矢量化计算
因为矢量化计算更高效。
考虑一个常见的简单情形,即编码器和解码器的隐藏单元个数均为hhh,且函数a(s,h)=s⊤ha(\boldsymbol{s}, \boldsymbol{h})=\boldsymbol{s}^\top \boldsymbol{h}a(s,h)=s⊤h。假设我们希望根据解码器单个隐藏状态st′−1∈Rh\boldsymbol{s}_{t' - 1} \in \mathbb{R}^{h}st′−1∈Rh和编码器所有隐藏状态ht∈Rh,t=1,…,T\boldsymbol{h}_t \in \mathbb{R}^{h}, t = 1,\ldots,Tht∈Rh,t=1,…,T来计算背景向量ct′∈Rh\boldsymbol{c}_{t'}\in \mathbb{R}^{h}ct′∈Rh。
我们可以将查询项矩阵Q∈R1×h\boldsymbol{Q} \in \mathbb{R}^{1 \times h}Q∈R1×h设为st′−1⊤\boldsymbol{s}_{t' - 1}^\topst′−1⊤,并令键项矩阵K∈RT×h\boldsymbol{K} \in \mathbb{R}^{T \times h}K∈RT×h和值项矩阵V∈RT×h\boldsymbol{V} \in \mathbb{R}^{T \times h}V∈RT×h相同且第ttt行均为ht⊤\boldsymbol{h}_t^\topht⊤。此时,我们只需要通过矢量化计算
softmax(QK⊤)V\text{softmax}(\boldsymbol{Q}\boldsymbol{K}^\top)\boldsymbol{V}softmax(QK⊤)V
即可算出转置后的背景向量ct′⊤\boldsymbol{c}_{t'}^\topct′⊤。当查询项矩阵Q\boldsymbol{Q}Q的行数为nnn时,上式将得到nnn行的输出矩阵。输出矩阵与查询项矩阵在相同行上一一对应。 -
更新隐藏状态
以门控循环单元为例,在解码器中我们可以对门控循环单元的设计稍作修改,从而变换上一时间步t′−1t'-1t′−1的输出yt′−1\boldsymbol{y}_{t'-1}yt′−1、隐藏状态st′−1\boldsymbol{s}_{t' - 1}st′−1和当前时间步t′t't′的含注意力机制的背景变量ct′\boldsymbol{c}_{t'}ct′ [1]。解码器在时间步t′t't′的隐藏状态为
st′=zt′⊙st′−1+(1−zt′)⊙s~t′,\boldsymbol{s}_{t'} = \boldsymbol{z}_{t'} \odot \boldsymbol{s}_{t'-1} + (1 - \boldsymbol{z}_{t'}) \odot \tilde{\boldsymbol{s}}_{t'},st′=zt′⊙st′−1+(1−zt′)⊙s~t′,
其中的重置门、更新门和候选隐藏状态分别为
rt′=σ(Wyryt′−1+Wsrst′−1+Wcrct′+br),zt′=σ(Wyzyt′−1+Wszst′−1+Wczct′+bz),s~t′=tanh(Wysyt′−1+Wss(st′−1⊙rt′)+Wcsct′+bs), \begin{aligned} \boldsymbol{r}_{t'} &= \sigma(\boldsymbol{W}_{yr} \boldsymbol{y}_{t'-1} + \boldsymbol{W}_{sr} \boldsymbol{s}_{t' - 1} + \boldsymbol{W}_{cr} \boldsymbol{c}_{t'} + \boldsymbol{b}_r),\\ \boldsymbol{z}_{t'} &= \sigma(\boldsymbol{W}_{yz} \boldsymbol{y}_{t'-1} + \boldsymbol{W}_{sz} \boldsymbol{s}_{t' - 1} + \boldsymbol{W}_{cz} \boldsymbol{c}_{t'} + \boldsymbol{b}_z),\\ \tilde{\boldsymbol{s}}_{t'} &= \text{tanh}(\boldsymbol{W}_{ys} \boldsymbol{y}_{t'-1} + \boldsymbol{W}_{ss} (\boldsymbol{s}_{t' - 1} \odot \boldsymbol{r}_{t'}) + \boldsymbol{W}_{cs} \boldsymbol{c}_{t'} + \boldsymbol{b}_s), \end{aligned} rt′zt′s~t′=σ(Wyryt′−1+Wsrst′−1+Wcrct′+br),=σ(Wyzyt′−1+Wszst′−1+Wczct′+bz),=tanh(Wysyt′−1+Wss(st′−1⊙rt′)+Wcsct′+bs),
其中含下标的W\boldsymbol{W}W和b\boldsymbol{b}b分别为门控循环单元的权重参数和偏差参数。
Transform
Transformer模型的架构,与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:由于自注意力层并没有区分元素的顺序,所以一个位置编码层被用于向序列元素里添加位置信息。
- 点赞
- 收藏
- 分享
- 文章举报
- ElitesAI·动手学深度学习PyTorch版学习笔记-机器翻译及相关技术;注意力机制与Seq2seq模型;Transformer
- 动手学深度学习-机器翻译及相关技术;注意力机制与Seq2seq模型;Transformer
- 动手学深度学习PyTorch-机器翻译及相关技术、注意力机制与Seq2seq模型、Transformer
- 动手学深度学习 Task04 机器翻译及相关技术;注意力机制与Seq2seq模型;Transformer
- DL-Pytorch Task04:机器翻译及相关技术;注意力机制与Seq2seq模型;Transformer
- 《动手学深度学习——机器翻译及相关技术,注意力机制与seq2seq模型,Transformer》笔记
- 吴恩达《深度学习-序列模型》3 -- 序列模型和注意力机制
- 深度学习之注意力机制(Attention Mechanism)和Seq2Seq
- 动手学DL|Task4 机器翻译及其技术+注意力机制与Seq2seq模型+Transformer
- 《动手学深度学习》组队学习打卡Task4——注意力机制与Seq2seq模型
- B站动手学深度学习第十八课:seq2seq(编码器和解码器)和注意力机制
- 关于深度学习中的注意力机制
- 机器翻译中的深度学习技术:CNN,Seq2Seq,SGAN,Dual Learning
- 机器阅读理解 / 知识库 / 深度学习 / 对话系统 / 神经机器翻译 | 本周值得读
- 深度学习和自然语言处理的注意机制和记忆模型
- 王小草【深度学习】笔记第七弹--RNN与应用案例:注意力模型与机器翻译
- 深度学习中的注意力机制
- 学习笔记(05):深度学习之图像识别 核心技术与案例实战-图像分割模型
- 深度学习之seq2seq模型以及Attention机制
- 机器学习、深度学习的相关资料