LSTM的注意机制是一个直的softmax前馈网络,它接收编码器每个时间步的隐藏状态和解码器的当前状态。
这两个步骤似乎相互矛盾,无法绕过我的脑袋: 1)需要预先定义前馈网络的输入数量 2)编码器的隐藏状态数是可变的(取决于编码期间的时间步数)。
我误解了什么吗?培训是否与培训常规编码器/解码器网络相同,或者我是否必须单独培训注意机制?
先谢谢
答案 0 :(得分:12)
今天我问自己同样的事,发现了这个问题。我自己从未实施过注意机制,但从this paper来看,它似乎不仅仅是一个直接的softmax。对于解码器网络的每个输出y i ,上下文向量 c i 被计算为编码器隐藏状态的加权和 h 1 ,..., h T :
c i =α i1 h 1 + ... + α<子>问题子>的ħ强> <子>Ť子>
对于每个样本,时间步数T可以是不同的,因为系数α ij 不是固定大小的矢量。实际上,它们是由softmax(e i1 ,...,e iT )计算的,其中每个e ij 是a的输出。神经网络,其输入为编码器隐藏状态 h j ,解码器隐藏状态 s i-1 :< / p>
e ij = f( s i-1 , h j )
因此,在计算y i 之前,必须对该神经网络进行T次计算,产生T权重α i1 ,...,α iT < /子>。此外,this tensorflow impementation可能也很有用。
答案 1 :(得分:1)
def attention(inputs, size, scope):
with tf.variable_scope(scope or 'attention') as scope:
attention_context_vector = tf.get_variable(name='attention_context_vector',
shape=[size],
regularizer=layers.l2_regularizer(scale=L2_REG),
dtype=tf.float32)
input_projection = layers.fully_connected(inputs, size,
activation_fn=tf.tanh,
weights_regularizer=layers.l2_regularizer(scale=L2_REG))
vector_attn = tf.reduce_sum(tf.multiply(input_projection, attention_context_vector), axis=2, keep_dims=True)
attention_weights = tf.nn.softmax(vector_attn, dim=1)
weighted_projection = tf.multiply(inputs, attention_weights)
outputs = tf.reduce_sum(weighted_projection, axis=1)
return outputs
希望这段代码可以帮助您了解注意力是如何工作的。 我在我的文档分类工作中使用此功能,这是一个与您的编码器 - 解码器模型不同的lstm-attention模型。