You need to enable JavaScript to run this app. 如何在堆叠LSTM模型中使用Bahdanau注意力?Keras实现咨询
优惠活动
大模型
产品
解决方案
定价
更多

如何在堆叠LSTM模型中使用Bahdanau注意力?Keras实现咨询

问题判断

你对x = AdditiveAttention(x, x)写法错误的判断是完全正确的,错误原因包含两点:

  • Keras的AdditiveAttention层入参要求是长度为2的列表输入,格式为[查询(query), 值(value)],直接传两个位置参数会触发语法报错,正确的调用格式是AdditiveAttention()([query, value])
  • 即使调整为符合语法的AdditiveAttention()([x, x]),也不符合你的需求:这种写法属于自注意力计算,而你的需求是解码器侧的状态作为查询、编码器输出的全部隐状态作为值做注意力匹配,二者逻辑完全不同。

符合需求的Keras高层实现代码

你给出的基础代码属于堆叠LSTM的分类结构,要加入编码器-解码器结构的Bahdanau注意力,调整后完整可运行代码如下:

import tensorflow as tf
from tensorflow.keras.layers import Input, LSTM, AdditiveAttention, Dense
from tensorflow.keras.models import Model

# 超参数定义
T = 100  # 输入序列长度
f = 12   # 单时间步输入特征维度
num_neurons1 = 64  # 编码器LSTM神经元数
num_neurons2 = 32  # 解码器LSTM神经元数

input_layer = Input(shape=(T, f))
# 编码器:返回全部时间步隐状态,作为注意力的value输入
encoder_out = LSTM(num_neurons1, return_sequences=True)(input_layer)
# 解码器:返回全部时间步隐状态,作为注意力的query输入,每个解码器时间步都会查询编码器全局隐状态
decoder_out = LSTM(num_neurons2, return_sequences=True)(encoder_out)
# 加性注意力(Bahdanau)计算
attention_out = AdditiveAttention()([decoder_out, encoder_out])
# 对注意力输出做全局平均池化后送入分类层
x = tf.keras.layers.GlobalAveragePooling1D()(attention_out)
output_layer = Dense(1, activation='sigmoid')(x)

model = Model(input_layer, output_layer)
model.summary()

简化场景适配

如果你的分类任务不需要保留解码器完整序列输出,想对齐你原来的代码结构(第二个LSTM只返回最后一个时间步状态),可以用以下简化写法:

# 编码器部分不变
encoder_out = LSTM(num_neurons1, return_sequences=True)(input_layer)
# 解码器只返回最后一个时间步的隐状态
decoder_final = LSTM(num_neurons2, return_sequences=False)(encoder_out)
# 为query增加长度为1的时间步维度,匹配注意力层输入维度要求
decoder_final = tf.expand_dims(decoder_final, axis=1)
# 注意力计算
attention_out = AdditiveAttention()([decoder_final, encoder_out])
# 去掉多余的时间步维度后送入分类层
x = tf.squeeze(attention_out, axis=1)
output_layer = Dense(1, activation='sigmoid')(x)

内容的提问来源于stack exchange,提问作者Mohammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 05:06:01