为什么我的LSTM对不同句子中的相似词汇输出相同预测结果
核心问题分析
- 你当前的模型架构完全没有实现「将单句所有词的表征输入第二个LSTM处理」的设计逻辑,第二个LSTM的输入只有单个词的表征,自然无法捕捉上下文信息,相同字符构成的词汇不管出现在什么语境下预测结果都不会变:
- 你目前的模型是单输入单输出的线性堆叠结构,实际运行逻辑是每次输入单个词的字符序列,输出单个词的分类结果。代码里的
Reshape((1, 50))操作把单个词的表征转成了长度为1的序列,输入到第二个LSTM时只有单个时间步,根本没有同一句子其他词的信息参与计算。 - 你使用的
Sequential模型本身不支持“先批量处理所有单字得到词表征、再按句子维度重组词序列输入第二层LSTM”的流程,需要改用函数式API实现分阶段的处理逻辑。
- 你目前的模型是单输入单输出的线性堆叠结构,实际运行逻辑是每次输入单个词的字符序列,输出单个词的分类结果。代码里的
- 其他次要问题:
- 第一层处理字符的BiLSTM后直接用
Flatten会丢失字符序列的时序信息,更合理的做法是用GlobalMaxPooling1D或者GlobalAveragePooling1D来聚合字符级的时序特征得到词表征。 - 第二层LSTM需要设置
return_sequences=True才能输出每个词对应的上下文表征,最终对每个位置做分类。
- 第一层处理字符的BiLSTM后直接用
修复思路
- 调整数据输入格式:输入维度改为
(batch_size, 句子长度=10, 单词字符长度),即每个批次的数据包含若干句子,每个句子有10个词,每个词对应固定长度的字符索引序列。 - 改用Keras函数式API搭建模型:
- 先用
TimeDistributed包装第一层的字符Embedding、字符级BiLSTM、池化层,实现对每个词的独立字符特征提取,得到形状为(batch_size, 10, 词表征维度)的句子级词序列。 - 将上述词序列直接输入第二层的句子级BiLSTM,输出每个词对应的上下文融合表征,再接全连接层做二分类。
- 先用
示例参考代码(仅核心结构):
from tensorflow.keras.layers import Input, TimeDistributed, Embedding, Bidirectional, LSTM, Dense, GlobalMaxPooling1D from tensorflow.keras.models import Model from tensorflow.keras.optimizers import Adam # 单词字符长度、词表大小、字符embedding维度等参数根据你的实际情况填写 input = Input(shape=(10, char_per_word)) # 对每个词单独做字符级特征提取 x = TimeDistributed(Embedding(input_dim=vocab_size, output_dim=char_embedding_size))(input) x = TimeDistributed(Bidirectional(LSTM(24, return_sequences=True)))(x) x = TimeDistributed(GlobalMaxPooling1D())(x) # 聚合字符特征得到词表征,形状 (batch, 10, 48) # 句子级上下文建模 x = Bidirectional(LSTM(32, return_sequences=True))(x) output = Dense(1, activation='sigmoid')(x) model = Model(inputs=input, outputs=output) optimizer = Adam(learning_rate=learning_rate) model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])
内容的提问来源于stack exchange,提问作者noam frank
相关产品推荐
相关产品推荐

