tf.contrib.seq2seq.BahdanauAttention()
__init__(
num_units,
memory,
memory_sequence_length=None,
normalize=False,
probability_fn=None,
score_mask_value=None,
dtype=None,
name='BahdanauAttention'
)
有两种attention模式:
1.Bahdanau attention
现在,对上面的解码器稍作修改。我们假设时刻t′t′的背景向量为ct′ct′。那么解码器在t′t′时刻的隐含层变量
令编码器在tt时刻的隐含变量为htht,解码器在t′t′时刻的背景向量为
也就是说,给定解码器的当前时刻t′t′,我们需要对编码器中不同时刻tt的隐含层变量求加权平均。而权值也称注意力权重。它的计算公式是
而et′t∈Ret′t∈R的计算为:
其中函数a有多种设计方法。在Bahanau的论文中,
其中的v、Ws、Wh和编码器与解码器两个循环神经网络中的各个权重和偏移项以及嵌入层参数等都是需要同时学习的模型参数。
2. 当normalize=True,上面所提到的a模型发生的变化.变化如下:
v = g * v / ||v||
et′t=v⊤tanh(Wsst′−1+Whht)
这中方法是受到了weight normalization的方法启发而来的。
具体的你可以查看源码了解:
v = variable_scope.get_variable("attention_v", [num_units], dtype=dtype) | |
if normalize: |
# Scalar used in weight normalization | |
g = variable_scope.get_variable( | |
"attention_g", dtype=dtype, | |
initializer=math.sqrt((1. / num_units))) | |
# Bias added prior to the nonlinearity | |
b = variable_scope.get_variable( | |
"attention_b", [num_units], dtype=dtype, | |
initializer=init_ops.zeros_initializer()) | |
# normed_v = g * v / ||v|| | |
normed_v = g * v * math_ops.rsqrt( | |
math_ops.reduce_sum(math_ops.square(v))) | |
return math_ops.reduce_sum( | |
normed_v * math_ops.tanh(keys + processed_query + b), [2]) | |
else: | |
return math_ops.reduce_sum(v * math_ops.tanh(keys + processed_query), [2]) | |
__init__(
num_units,
memory,
memory_sequence_length=None,
scale=False,
probability_fn=None,
score_mask_value=None,
dtype=None,
name='LuongAttention'
)
luongAttention 方法的详细描述在论文:https://arxiv.org/pdf/1508.04025.pdf
计算过程:
这是输出层输出的结果。下面是target 隐藏层状态怎么计算的。