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
细心的同学可能看出来,这里传递过来的上下文是整句的。但对于某一个词的翻译,所需要的信息是不一样的。这就有了注意力模型。
#带注意力模型的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: attention
批处理如何在 pytorch 的 seq2seq 模型中工作?
pytorch seq2seq模型中加入teacher_forcing机制