pytorch基于seq2seq注意力模型实现英文法文翻译

Posted AI量化实验室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytorch基于seq2seq注意力模型实现英文法文翻译相关的知识,希望对你有一定的参考价值。

如果说深度学习在自然语言的有比较大的进步的话,机器翻译可能算一个。


传统机器学习或者专家系统,在机器翻译上折腾好几十年,好多语言学家,整理了各种语言学,形式逻辑规则,但作用有限。因为人类的语言实在是太复杂,而且本身还在不断的演化当中。


直到大家放弃语言规则,投入统计学方向,比如n-gram,cbow等,就是统计词语序列符合人类语言的最大概率。看似简单,但效果超好。


既然是统计问题,那深度学习就可以派上用场,尤其是序列预测问题。对于双语之间的翻译,其实就是寻找两个序列之间的对应关系。而这两种对应关系,还必须符合各自语种的表达习惯。这里的模型就是seq2seq。

输入一句法文,输出对应的英文翻译。

如上图所示,翻译过程就是将原文句子编码,信息在hidden的context里,然后经过解码器输出。

编码器就是一个很“传统”的1层的GRU。先把input做词嵌入,然后过gru输出output和hidden。

#编码器
class EncoderRNN(nn.Module):
#这是为何没有embedding_size,而直接=hidden_size是必须的吗?
   #另外gru的hidden就一个?
   def __init__(self, vocab_size, hidden_size, n_layers=1):
super(EncoderRNN, self).__init__()
self.n_layers = n_layers
self.hidden_size = hidden_size

self.embedding = nn.Embedding(vocab_size, hidden_size)
self.gru = nn.GRU(hidden_size, hidden_size)

def forward(self, input, hidden):
embedded = self.embedding(input).view(1, 1, -1)
output = embedded
for i in range(self.n_layers):
output, hidden = self.gru(output, hidden)
return output, hidden

def initHidden(self):
result = Variable(torch.zeros(1, 1, self.hidden_size))
return result

解码器的结构也类似,就是input是编码之后的output,所以输入维度是hidden_size。

class DecoderRNN(nn.Module):
def __init__(self, hidden_size, output_size, n_layers=1):
super(DecoderRNN, self).__init__()
self.n_layers = n_layers
self.hidden_size = hidden_size

self.embedding = nn.Embedding(output_size, hidden_size)
self.gru = nn.GRU(hidden_size, hidden_size)
self.out = nn.Linear(hidden_size, output_size)
self.softmax = nn.LogSoftmax()

def forward(self, input, hidden):
output = self.embedding(input).view(1, 1, -1)
for i in range(self.n_layers):
output = F.relu(output)
output, hidden = self.gru(output, hidden)
output = self.softmax(self.out(output[0]))
return output, hidden

def initHidden(self):
result = Variable(torch.zeros(1, 1, self.hidden_size))
return result

细心的同学可能看出来,这里传递过来的上下文是整句的。但对于某一个词的翻译,所需要的信息是不一样的。这就有了注意力模型。

pytorch基于seq2seq注意力模型实现英文法文翻译

#带注意力模型的GRU解码器
class AttnDecoderRNN(nn.Module):
def __init__(self, hidden_size, output_size, n_layers=1, dropout_p=0.1, max_length=MAX_LENGTH):
super(AttnDecoderRNN, self).__init__()
self.hidden_size = hidden_size
self.output_size = output_size
self.n_layers = n_layers
self.dropout_p = dropout_p
self.max_length = max_length

self.embedding = nn.Embedding(self.output_size, self.hidden_size)

self.attn = nn.Linear(self.hidden_size * 2, self.max_length)
self.attn_combine = nn.Linear(self.hidden_size * 2, self.hidden_size)

self.dropout = nn.Dropout(self.dropout_p)
self.gru = nn.GRU(self.hidden_size, self.hidden_size)
self.out = nn.Linear(self.hidden_size, self.output_size)

def forward(self, input, hidden, encoder_output, encoder_outputs):
embedded = self.embedding(input).view(1, 1, -1)
embedded = self.dropout(embedded)

#这里计算注意力权重
       attn_weights = F.softmax(
self.attn(torch.cat((embedded[0], hidden[0]), 1)))
attn_applied = torch.bmm(attn_weights.unsqueeze(0),
encoder_outputs.unsqueeze(0))

output = torch.cat((embedded[0], attn_applied[0]), 1)
output = self.attn_combine(output).unsqueeze(0)

#下面仍然到GRU/log_softmax
       for i in range(self.n_layers):
output = F.relu(output)
output, hidden = self.gru(output, hidden)

output = F.log_softmax(self.out(output[0]))
return output, hidden, attn_weights

def initHidden(self):
result = Variable(torch.zeros(1, 1, self.hidden_size))
return result

网络结构如上,具体注意力模型的原理,明天继续分析。

扫描下方二维码,关注:AI量化实验室(ailabx),了解AI量化最前沿技术、资讯。


以上是关于pytorch基于seq2seq注意力模型实现英文法文翻译的主要内容,如果未能解决你的问题,请参考以下文章

动手学pytorch-注意力机制和Seq2Seq模型

文本摘要Pytorch之Seq2seq: attention

批处理如何在 pytorch 的 seq2seq 模型中工作?

pytorch seq2seq模型中加入teacher_forcing机制

论文写作分析之一 《基于混合注意力Seq2seq模型的选项多标签分类》

pytorch seq2seq模型示例