You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Keras Sequential模型中使用Doc2Vec句向量做情感分析的报错解决

问题分析与解决方案

错误根源

你遇到的InvalidArgumentError本质是输入层和输入数据完全不匹配:

  • Keras的Embedding层是用来把非负整数索引(比如词在字典中的ID)转换成向量的,它要求输入必须是≥0的整数。但你喂给它的是Doc2Vec生成的浮点数向量(甚至包含负数,比如错误里的-19),这完全不符合Embedding层的输入规则,所以才会抛出“索引不在有效范围”的错误。
  • 另外,你的Doc2Vec训练代码也有逻辑问题:把token直接拼接成字符串保存,TaggedLineDocument会把每行当成一个单“词”的文档,这样训练出来的Doc2Vec向量根本没有语义价值,等于白训了。

分步骤修复方案

1. 先修复Doc2Vec的训练逻辑

Doc2Vec需要的是每个文档的token列表,而不是拼接后的字符串,正确的训练代码应该是这样:

from gensim.models.doc2vec import Doc2Vec, TaggedDocument

# 假设x是已经分词后的句子列表,比如x = [["i", "love", "this", "film"], ["it", "sucks", "badly"], ...]
tagged_docs = [TaggedDocument(words=tokens, tags=[str(idx)]) for idx, tokens in enumerate(x)]

# 调整Doc2Vec参数:alpha和min_alpha的合理范围是0.025到0.0001,vector_size用128维比5维更能捕捉语义
d2v_model = Doc2Vec(
    tagged_docs,
    dm=0,  # DBOW模式
    window=5,
    vector_size=128,
    epochs=100,
    workers=32,
    dbow_words=1,
    alpha=0.025,
    min_alpha=0.0001
)

2. 生成有效的句向量

用修复后的模型生成每个句子的向量,确保输入是token列表:

import numpy as np

# 生成(样本数, 向量维度)的2D数组
doc_vectors = np.array([d2v_model.infer_vector(tokens) for tokens in x])

3. 修改Keras模型,移除错误的Embedding层

既然我们已经有了预训练好的句向量,就不需要再用Embedding层做索引映射。根据你的需求,分两种情况调整模型:

情况A:继续使用LSTM层

LSTM要求输入是3D张量(样本数, 时间步长, 特征数),所以需要把2D的句向量reshape成3D:

from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout

model = Sequential()
# input_shape=(时间步长, 特征数),这里把每个向量维度当作一个时间步,特征数为1
model.add(LSTM(200, dropout=0.2, recurrent_dropout=0.2, input_shape=(doc_vectors.shape[1], 1)))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

# 把2D向量reshape成3D
doc_vectors_3d = doc_vectors.reshape(doc_vectors.shape[0], doc_vectors.shape[1], 1)

# 开始训练
model.fit(doc_vectors_3d, y, batch_size=32, epochs=8, verbose=1)
情况B:用全连接层替代LSTM(更高效)

句向量本身已经是语义压缩后的表示,直接用全连接层就能完成分类,不需要LSTM:

model = Sequential()
model.add(Dense(256, activation='relu', input_shape=(doc_vectors.shape[1],)))
model.add(Dropout(0.2))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

# 直接用2D的句向量输入即可
model.fit(doc_vectors, y, batch_size=32, epochs=8, verbose=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:40:58