目录
赛题情况
简单概括来讲该任务就是术语词典干预的机器翻译:选择以英文为源语言,中文为目标语言的机器翻译。本次大赛除英文到中文的双语数据,还提供英中对照的术语词典。
即利用提供的训练数据样本构建与训练机器翻译模型,并基于测试集以及术语词典,提供最终的翻译结果,数据包括:
训练集(Training):双语数据:中英14万余双语句对
开发集(也叫验证集,Validation):英中1000双语句对
测试集(Testing):英中1000双语句对
术语词典:英中2226条
关于Transformer
Transformer来源于谷歌团队的“Attention Is All You Need”文章,就是这篇文章提出了大名鼎鼎的Transformer网络结构,如下图1所示。
Transformer架构中主要有以下几个核心:位置编码(Positional Encoding)、多头注意力(Multiple Attention)、残差连接(Residual Connections)等。下面将简单介绍一下:
位置编码(Positional Encoding)
位置编码(位置嵌入)的计算过程如下:
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所示(详细过程可以参考知乎该博主):
多头注意力(Multiple Attention)
注意力机制的关键在于以下参数 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为例:
其中,初始的Linear weights矩阵随机生成,并一般通过反向传播等算法调整权重。
再通过Q与K矩阵乘法,缩放点积和归一化即可得到结果:
最后再把上述结果与V相乘。
经过该操作后,我们只得到了其中的一头注意力结果,对该操作重复,即可得到多头结果,最终将他们拼接:
残差连接(Residual Connections)
随着网络层的深度的增加,网络更深层保留的原始信息减少,为了保持信息的不丢失,通过残差连接可以很好地保留该特点。
此外,残差连接还可以一定程度解决梯度消失问题。
赛题代码模块
借助于Pytorch模块,可以快速搭建模型架构。
核心Transformer模块
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(小白必会版😃)