tensorflow - 如何在 Keras 的两个 LSTM 层之间添加注意力层
问题描述
我正在尝试在编码器 LSTM(多对多)和解码器 LSTM(多对一)之间添加一个注意层。
但是我的代码似乎只为一个解码器 LSTM 输入创建了注意力层。
如何将注意力层应用于解码器 LSTM 的所有输入?(注意力层的输出 = (None,1440,984) )
这是我模型的注意力层的总结。
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) (None, 1440, 5) 0
__________________________________________________________________________________________________
bidirectional_1 (Bidirectional) (None, 1440, 984) 1960128 input_1[0][0]
__________________________________________________________________________________________________
dense_1 (Dense) (None, 1440, 1) 985 bidirectional_1[0][0]
__________________________________________________________________________________________________
flatten_1 (Flatten) (None, 1440) 0 dense_1[0][0]
__________________________________________________________________________________________________
activation_1 (Activation) (None, 1440) 0 flatten_1[0][0]
__________________________________________________________________________________________________
repeat_vector_1 (RepeatVector) (None, 984, 1440) 0 activation_1[0][0]
__________________________________________________________________________________________________
permute_1 (Permute) (None, 1440, 984) 0 repeat_vector_1[0][0]
__________________________________________________________________________________________________
multiply_1 (Multiply) (None, 1440, 984) 0 bidirectional_1[0][0]
permute_1[0][0]
__________________________________________________________________________________________________
lambda_1 (Lambda) (None, 984) 0 multiply_1[0][0]
==================================================================================================
Total params: 1,961,113
Trainable params: 1,961,113
Non-trainable params: 0
__________________________________________________________________________________________________
这是我的代码
_input = Input(shape=(self.x_seq_len, self.input_x_shape), dtype='float32')
activations = Bidirectional(LSTM(self.hyper_param['decoder_units'], return_sequences=True), input_shape=(self.x_seq_len, self.input_x_shape,))(_input)
# compute importance for each step
attention = Dense(1, activation='tanh')(activations)
attention = Flatten()(attention)
attention = Activation('softmax')(attention)
attention = RepeatVector(self.hyper_param['decoder_units']*2)(attention)
attention = Permute([2, 1])(attention)
sent_representation = Multiply()([activations, attention])
sent_representation = Lambda(lambda xin: K.sum(xin, axis=-2), output_shape=(self.hyper_param['decoder_units']*2,))(sent_representation)
attn = Model(input=_input, output=sent_representation)
model.add(attn)
#decoder
model.add(LSTM(self.hyper_param['encoder_units'], return_sequences=False, input_shape=(None, self.hyper_param['decoder_units'] * 2 )))
解决方案
注意力意味着迭代地获取一个解码器输出值(最后一个隐藏状态),然后使用这个“查询”,“关注”所有“值”,这只是编码器输出的整个列表。
所以 input1 = 上一个时间步的解码器隐藏状态:'key'
input2 = 所有编码器隐藏状态:“值”
输出 = 上下文:所有编码器隐藏状态的加权和
使用上下文,解码器的上一个隐藏状态和上一个翻译的输出来生成下一个单词和一个新的隐藏输出状态,然后再次重复上述过程,直到遇到'EOS'。
您的注意力逻辑本身是完美的(不包括涉及解码器的最后一行)。但是您的其余代码丢失了。如果您可以分享完整的代码,我可以帮助您解决错误。我认为您定义的注意力逻辑没有错误。
推荐阅读
- php - 在 Linkedin API 上创建图像共享
- angular - 使用 defaultIfEmpty() 仍然没有在 Angular canActivate 防护中发出
- ios - 调用出列单元时出列可重用单元崩溃
- reactjs - 如何在 Typescript 模块声明中使用多个通配符?
- java - OpenJPA & Spring Boot 2 & Gradle
- scala - 将数据框转换为列名和值的结构数组
- google-bigquery - BigQuery:验证所有日期的格式为 yyyy-mm-dd
- javascript - 更改 _.groupBy() 结果数据的顺序
- mysql - 如何选择在给定日期尚未更新的 MySQL 表值?
- visual-studio - Visual Studio 任务列表 - 树视图