使用Keras结合FastText词嵌入构建句尾词预测语言模型准确率过低问题
问题修复方案
核心错误原因
- 你当前的任务是词分类预测任务,输出目标应该是词在词汇表中的整数类别索引,而非FastText生成的300维嵌入向量,现有实现的损失和输出层逻辑完全不匹配任务目标。你之前替换为Embedding层能得到60%准确率,就是因为当时的标签用的是正确的词整数索引,输出层维度与词汇表大小匹配,损失逻辑和任务对应,所以效果正常。
- 最后一层的softmax激活+categorical_crossentropy损失要求输出是每个类别的概率分布,对应维度必须是词汇表大小(48000),你之前输出300维加softmax是对嵌入向量的每个维度做概率归一化,完全不符合业务逻辑。
- 你之前调用
to_categorical(y, num_classes=vocab_size)报错维度异常,是因为你传入的y是300维的嵌入向量,不是单个的整数词索引,to_categorical会把每个维度的值都当成独立的类别索引处理,自然会生成远大于预期的样本数。
具体修复步骤
步骤1:调整标签数据结构
预处理阶段必须保留每个句尾词对应的词汇表整数索引,假设这个索引数组命名为y_idx,shape为(44317,),每个元素是0~48000之间的整数,对应句尾词在词汇表中的位置。
# 正确的标签独热编码转换方式 from tensorflow.keras.utils import to_categorical vocab_size = 48000 # 替换为你的实际词汇表大小 y = to_categorical(y_idx, num_classes=vocab_size) # 此时y的shape为(44317, 48000),符合预期
如果不想做独热编码,也可以直接用y_idx作为标签,后续调整损失函数即可。
步骤2:调整模型输出层配置
把最后一个Dense层的维度改为词汇表大小,对应调整损失函数:
#importing all the needed tensorflow.keras components from tensorflow.keras.models import Sequential from tensorflow.keras.layers import InputLayer, LSTM, Dense vocab_size = 48000 # 替换为你的实际词汇表大小 model = Sequential() model.add(InputLayer((39, 300))) # 固定输入长度为39,也可以保留None支持变长输入 model.add(LSTM(100, return_sequences=True)) model.add(LSTM(100)) model.add(Dense(100, activation='relu')) model.add(Dense(vocab_size, activation='softmax')) # 输出维度改为词汇表大小 # 如果用了to_categorical就用这个配置 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(X, y, batch_size=128, epochs=20) # 如果没做to_categorical,直接用y_idx作为标签就用这个配置 # model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # model.fit(X, y_idx, batch_size=128, epochs=20) model.save('model.h5')
可选方案:基于嵌入向量相似度预测
如果你不想做分类,想直接输出嵌入向量和FastText向量做相似度匹配,就调整输出层和损失函数:
model.add(Dense(300)) # 不需要softmax激活 model.compile(loss='mse', optimizer='adam') # 也可以替换为余弦相似度损失
这种方式训练完预测时,需要把输出的300维向量和词汇表所有词的FastText向量做相似度计算,取TopK相似的词作为预测结果,该方案不会输出分类准确率指标,也不会直接得到词的类别。
内容的提问来源于stack exchange,提问作者tristan19954
相关产品推荐
相关产品推荐

