赞
踩
简单概括来讲该任务就是术语词典干预的机器翻译:选择以英文为源语言,中文为目标语言的机器翻译。本次大赛除英文到中文的双语数据,还提供英中对照的术语词典。
即利用提供的训练数据样本构建与训练机器翻译模型,并基于测试集以及术语词典,提供最终的翻译结果,数据包括:
训练集(Training):双语数据:中英14万余双语句对
开发集(也叫验证集,Validation):英中1000双语句对
测试集(Testing):英中1000双语句对
术语词典:英中2226条
Transformer来源于谷歌团队的“Attention Is All You Need”文章,就是这篇文章提出了大名鼎鼎的Transformer网络结构,如下图1所示。
Transformer架构中主要有以下几个核心:位置编码(Positional Encoding)、多头注意力(Multiple Attention)、残差连接(Residual Connections)等。下面将简单介绍一下:
位置编码(位置嵌入)的计算过程如下:
P E ( O d d ) = sin ( p o s / 1000 0 2 i / d i m ) P E ( O d d ) = \sin ( p o s / 1 0 0 0 0 ^ { 2 i / d i m } ) PE(Odd)=sin(pos/100002i/dim)
P E ( E v e n ) = cos ( p o s / 1000 0 2 i / d i m ) P E ( E v e n ) = \cos ( p o s / 1 0 0 0 0 ^ { 2 i / d i m } ) PE(Even)=cos(pos/100002i/dim)
其中 p o s pos pos为单词所在的位置( p o s = 0 , 1 , 2 , 3 , … pos=0,1,2,3,\dots pos=0,1,2,3,…), i i i为 E m b e d d i n g Embedding Embedding数组中的索引下标,同时 i i i的奇偶决定了 O d d Odd Odd还是 E v e n Even Even计算, d i m dim dim为嵌入向量的维度。
这里举一个简单的例子(详细过程可以参考知乎该博主):
以 When you play game of thrones中的When为例,如下图2(详细过程可以参考知乎该博主):
生成位置编码后,可与原始单词编码结合起来,如下图3(详细过程可以参考知乎该博主):
即如下图4所示(详细过程可以参考知乎该博主):
注意力机制的关键在于以下参数 K ( K e y ) K(Key) K(Key)、 Q ( Q u e r y ) Q(Query) Q(Query)、 V ( V a l u e ) V(Value) V(Value)。
继续以When you play game of thrones为例:
再通过Q与K矩阵乘法,缩放点积和归一化即可得到结果:
最后再把上述结果与V相乘。
经过该操作后,我们只得到了其中的一头注意力结果,对该操作重复,即可得到多头结果,最终将他们拼接:
随着网络层的深度的增加,网络更深层保留的原始信息减少,为了保持信息的不丢失,通过残差连接可以很好地保留该特点。
此外,残差连接还可以一定程度解决梯度消失问题。
借助于Pytorch模块,可以快速搭建模型架构。
class PositionalEncoding(nn.Module): # 位置编码,d_model为词嵌入维度,dropout为dropout概率,max_len为最大长度 def __init__(self, d_model, dropout=0.1, max_len=5000): super(PositionalEncoding, self).__init__() # dropout层 self.dropout = nn.Dropout(p=dropout) # 初始化一个位置编码矩阵 pe = torch.zeros(max_len, d_model) # 初始化位置 position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) # 计算位置编码 div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) # 计算位置编码矩阵 pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) pe = pe.unsqueeze(0).transpose(0, 1) # 初始化位置编码矩阵,然后增加一个维度,这样可以直接与输入张量相加 self.register_buffer('pe', pe) def forward(self, x): # 位置编码矩阵与输入张量相加 x = x + self.pe[:x.size(0), :] return self.dropout(x) class TransformerModel(nn.Module): # Transformer,src为源语言词汇表,tgt为目标语言词汇表,d_model为词嵌入维度,nhead为头数,num_encoder_layers为编码器层数,num_decoder_layers为解码器层数,dim_feedforward为前馈神经网络维度,dropout为dropout概率 def __init__(self, src_vocab, tgt_vocab, d_model, nhead, num_encoder_layers, num_decoder_layers, dim_feedforward, dropout): super(TransformerModel, self).__init__() # 初始化一个Transformer模型 self.transformer = nn.Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers, dim_feedforward, dropout) # 初始化位置编码 self.src_embedding = nn.Embedding(len(src_vocab), d_model) self.tgt_embedding = nn.Embedding(len(tgt_vocab), d_model) self.positional_encoding = PositionalEncoding(d_model, dropout) # 输出层 self.fc_out = nn.Linear(d_model, len(tgt_vocab)) # 初始化参数 self.src_vocab = src_vocab self.tgt_vocab = tgt_vocab self.d_model = d_model def forward(self, src, tgt): # 调整src和tgt的维度 src = src.transpose(0, 1) # (seq_len, batch_size) tgt = tgt.transpose(0, 1) # (seq_len, batch_size) # 生成mask src_mask = self.transformer.generate_square_subsequent_mask(src.size(0)).to(src.device) tgt_mask = self.transformer.generate_square_subsequent_mask(tgt.size(0)).to(tgt.device) # 生成padding mask src_padding_mask = (src == self.src_vocab['<pad>']).transpose(0, 1) tgt_padding_mask = (tgt == self.tgt_vocab['<pad>']).transpose(0, 1) src_embedded = self.positional_encoding(self.src_embedding(src) * math.sqrt(self.d_model)) tgt_embedded = self.positional_encoding(self.tgt_embedding(tgt) * math.sqrt(self.d_model)) output = self.transformer(src_embedded, tgt_embedded, src_mask, tgt_mask, None, src_padding_mask, tgt_padding_mask, src_padding_mask) return self.fc_out(output).transpose(0, 1)
[1].基于术语词典干预的机器翻译挑战赛
[2].从编解码和词嵌入开始,一步一步理解Transformer,注意力机制(Attention)的本质是卷积神经网络(CNN)
[3].三万字最全解析!从零实现Transformer(小白必会版
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。