加入注意力
1.编码器对每次词的输出作为key和value
2.解码器RNN对上一个词的输出是query
3.注意力的输出和下一个词的词嵌入合并进入RNN
一个带有Bahdanau注意力的循环神经网络编码器-解码器模型
总结
1.seq2seq通过隐状态在编码器和解码器中传递信息
2.注意力机制可以根据解码器RNN的输出来匹配到合适的编码器RNN的输出来更有效的传递信息。
pip install d2l==0.17.6 ### 很重要,不要下载错了,对于colab
import torch
from torch import nn
from d2l import torch as d2l
注意力解码器
AttentionDecoder类定义了带有注意力机制解码器的基本接口
class AttentionDecoder(d2l.Decoder):
"""带有注意力机制解码器的基本接口"""
def __init__(self, **kwargs):
super(AttentionDecoder, self).__init__(**kwargs)
@property
def attention_weights(self):
raise NotImplementedError
Seq2SeqAttentionDecoder类中 实现带有Bahdanau注意力的循环神经网络解码器。
1.编码器在所有时间步的最终层隐状态,将作为注意力的键和值;
2.上一时间步的编码器全层隐状态,将作为初始化解码器的隐状态;
3.编码器有效长度(排除在注意力池中填充词元)。
class Seq2SeqAttentionDecoder(AttentionDecoder):
def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,
dropout=0, **kwargs):
super(Seq2SeqAttentionDecoder, self).__init__(**kwargs)
self.attention = d2l.AdditiveAttention(num_hiddens,num_hiddens,num_hiddens, dropout)
self.embedding = nn.Embedding(vocab_size, embed_size)
self.rnn = nn.GRU(
embed_size + num_hiddens, num_hiddens, num_layers,
dropout=dropout)
self.dense = nn.Linear(num_hiddens, vocab_size)