Embedding层索引越界问题求助:索引159947超出[0,159943)范围
解决Embedding层索引超出范围的InvalidArgumentError问题
错误原因
你遇到的InvalidArgumentError核心问题是:测试数据用了全新训练的Tokenizer,而非训练模型时的那个。
训练时的Tokenizer已经建立了训练集词汇与索引的固定映射,测试时重新训练的Tokenizer会根据测试集词汇生成新索引——一旦测试集出现训练集没见过的词,就会被分配一个比训练集vocab_size更大的索引。而你的Embedding层input_dim是基于训练集vocab_size(159943)设置的,自然无法识别这些超出范围的索引,就触发了错误。
解决方法
1. 复用训练时的Tokenizer(最优方案)
训练模型时必须保存当时用的Tokenizer,测试时直接加载复用,保证词汇索引映射完全一致:
- 训练阶段保存Tokenizer:
import pickle # 训练你的Tokenizer(训练时执行) tok = Tokenizer() tok.fit_on_texts(train['comment_text_transformed']) # 保存Tokenizer到本地文件 with open('train_tokenizer.pkl', 'wb') as f: pickle.dump(tok, f) - 测试阶段加载Tokenizer并处理数据:
import pickle # 加载训练时保存的Tokenizer with open('train_tokenizer.pkl', 'rb') as f: tok = pickle.load(f) # 直接用这个Tokenizer处理测试数据,绝对不能重新fit encd_reviews_test = tok.texts_to_sequences(test['comment_text_transformed'])
2. 处理未登录词(OOV)
如果训练时没考虑未登录词,建议重新训练Tokenizer时加上oov_token参数,让所有训练集未见过的词统一映射到合法索引:
- 训练时初始化Tokenizer:
# 加入oov_token,让未见过的词映射到特定索引 tok = Tokenizer(oov_token='<OOV>') tok.fit_on_texts(train['comment_text_transformed']) # 调整vocab_size,因为多了一个<OOV>的索引(Tokenizer从1开始计数,+1包含0填充位) vocab_size = len(tok.word_index) + 1 - 生成词向量时,
<OOV>会自动用上你之前的随机初始化逻辑,无需额外修改词向量生成代码。
3. 临时应急修复(不推荐)
如果暂时没法重新处理训练数据,可以直接把测试数据中超出范围的索引替换为0(填充位):
import numpy as np # 假设pad_reviews_test是处理好的测试序列数组 pad_reviews_test = np.where(pad_reviews_test >= vocab_size, 0, pad_reviews_test)
这种方法会丢失未登录词的信息,仅作为临时救急方案。
内容的提问来源于stack exchange,提问作者YuvrajSingh
相关产品推荐
相关产品推荐

