TensorFlow训练情感分析模型的张量转换适配报错排查
问题根因
你碰到的所有报错本质来自两个预处理疏漏,和模型结构本身无关:
- 特征数据类型不合法:输入给Keras模型的特征X中同时存在字符串类型的原始词、整数类型的填充值0,属于混合类型输入,Keras没有适配这种混合类型输入的数据读取组件,这是最后一个
Failed to find data adapter报错的直接原因。
报错信息里已经明确标注输入列表同时包含<class 'str'>和<class 'int'>类型值,而你搭建的模型第一层是Embedding层,该层仅接收整数类型的词ID输入,无法直接处理原始字符串。 - 前期维度不匹配类报错的两个诱因:
- 你最初排查到的标签Y冗余问题:X和Y样本量不对齐时,批次生成器按batch_size=32拉取数据,会出现特征长度和标签长度差3个值的情况,即报错中提到的35维度来源,和你文本本身的词长没有关联。
- 最初手动将不等长嵌套列表转numpy数组时,会生成dtype为
object的外层数组,每个元素是独立的子numpy数组,TensorFlow无法将这种嵌套object结构解析为合法张量,才会触发Unsupported object type numpy.ndarray报错。
你之前尝试用不规则张量ragged.constant失败,本质也是因为输入里混了字符串类型值,加上X/Y样本量不对齐,和不规则张量本身的能力无关。
修复步骤
按以下顺序调整预处理代码即可解决所有报错:
- 第一步:完成词到整数ID的映射,彻底清除输入中的字符串值
你使用gensim训练的word2vec模型自带词到ID的映射表,直接调用即可,不要把原始文本字符串传入模型:processed_data = [] # 未知词统一映射为ID1,填充值固定用ID0,和词表ID不冲突 UNK_ID = 1 PAD_ID = 0 for seq in data: id_seq = [] for word in seq: # 过滤手动填充时误加的0值,后续统一做填充 if word == PAD_ID: continue if word in word2vec_model.wv.key_to_index: id_seq.append(word2vec_model.wv.key_to_index[word]) else: id_seq.append(UNK_ID) processed_data.append(id_seq) - 第二步:用Keras官方接口做序列填充,不要手动写循环补0
手动填充容易出现长度计算错误、类型不一致问题,直接调用内置工具生成格式合法的定长数组:from tensorflow.keras.preprocessing.sequence import pad_sequences # 按你之前统计的最长序列长度做后填充 X = pad_sequences(processed_data, maxlen=maxLen, padding='post', value=PAD_ID) # 将标签Y也转为numpy数组,保证类型统一 Y = numpy.asarray(Y) - 第三步:训练前做合法性校验
执行fit前先确认两个条件:X.dtype和Y.dtype均为数值类型(int/float),无字符串残留X.shape[0] == Y.shape[0],特征和标签的样本量完全一致
校验通过后再执行model.fit(X, Y, batch_size=32, epochs=50)即可正常启动训练。
补充:你当前的模型结构没有问题,Embedding层输出的动态长度序列可以正常对接两层LSTM结构,不需要调整模型层配置。
内容的提问来源于stack exchange,提问作者XEX
相关产品推荐
相关产品推荐

