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

Bi-LSTM+CRF模型训练报错:NumPy数组转Tensor失败(不支持list类型)

问题修复方案

核心报错原因

报错ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type list)的根源:

  • 处理后的Name列是变长序列列表,而CompanyId、TableTypeCode是one-hot编码后的数值型列,两者无法直接合并成模型可接收的张量
  • 原模型结构错误,未考虑多输入(文本序列+数值特征)的适配逻辑,也未按需求集成CRF层

完整修复代码

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
from keras.layers import Input, Embedding, LSTM, Dense, Bidirectional, Concatenate
from keras.models import Model
import tensorflow_addons as tfa

# 加载数据
df = pd.read_excel("data.xlsx")
X = df[['CompanyId', 'Name', 'TableTypeCode']]
y = df['BlockName']

# 1. 预处理文本特征(Name)
X['Name'] = X['Name'].astype(str)
tokenizer = Tokenizer()
tokenizer.fit_on_texts(X['Name'])  # 先拟合所有文本,再生成序列
name_sequences = tokenizer.texts_to_sequences(X['Name'])
# 对序列做padding,统一长度(取最长序列或自定义固定长度)
max_seq_len = max([len(seq) for seq in name_sequences])
name_padded = pad_sequences(name_sequences, maxlen=max_seq_len, padding='post', truncating='post')

# 2. 预处理数值/类别特征(CompanyId、TableTypeCode)
# One-hot编码
cat_features = pd.get_dummies(X[['CompanyId', 'TableTypeCode']])
# 转换为numpy数组
cat_np = cat_features.values

# 3. 处理标签
encoder = LabelEncoder()
y_encoded = encoder.fit_transform(y)
y_categorical = to_categorical(y_encoded)
n_classes = len(encoder.classes_)

# 4. 划分训练测试集
X_name_train, X_name_test, X_cat_train, X_cat_test, y_train, y_test = train_test_split(
    name_padded, cat_np, y_categorical, test_size=0.2, random_state=42
)

# 5. 构建多输入Bi-LSTM+CRF模型
# 文本输入分支
text_input = Input(shape=(max_seq_len,), name='text_input')
embedding = Embedding(input_dim=len(tokenizer.word_index)+1, output_dim=128)(text_input)
bilstm = Bidirectional(LSTM(units=128, return_sequences=False))(embedding)

# 数值特征输入分支
cat_input = Input(shape=(cat_features.shape[1],), name='cat_input')
cat_dense = Dense(64, activation='relu')(cat_input)

# 拼接两个分支的输出
concat = Concatenate()([bilstm, cat_dense])
dense = Dense(64, activation='relu')(concat)

# 加入CRF层
crf = tfa.layers.CRF(n_classes, activation='softmax')
output = crf(dense)

model = Model(inputs=[text_input, cat_input], outputs=output)
# CRF层使用专属损失函数
model.compile(optimizer='adam', loss=crf.loss, metrics=[crf.accuracy])

# 训练模型
model.fit(
    [X_name_train, X_cat_train], y_train,
    validation_data=([X_name_test, X_cat_test], y_test),
    epochs=10, batch_size=32
)

关键修复点说明

  • 文本特征标准化:通过pad_sequences将变长的Name序列统一为固定长度,彻底解决列表类型无法转换为张量的核心问题
  • 多输入模型设计:将文本序列和数值类别特征拆分为两个独立输入分支,分别处理后再拼接输出,适配多模态数据的输入需求
  • CRF层正确集成:使用tfa.layers.CRF替代原有的Dense+softmax,同时配套使用CRF自带的损失函数与评估指标,符合序列标注任务的特性
  • 预处理流程修正:先调用tokenizer.fit_on_texts拟合全部文本数据,再转换为序列,确保编码规则的一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:10:24