如何解决“Failed to convert a NumPy array to a Tensor (Unsupported object type int)”错误
修复
ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type int)错误 问题根源
你的输入特征feat包含未处理的文本列(text,object类型)和数值列(attachment,float类型),但模型第一层是Embedding层——该层仅能接收文本经分词编码后的整数序列,直接传入原始DataFrame会因类型不兼容无法转为Tensor,触发报错。
具体修复方案
1. 文本预处理:将text转为整数序列
用Tokenizer对文本分词、编码,转成固定长度的整数序列,适配Embedding层输入要求:
from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences def preprocess_text(texts, max_feature, max_len): tokenizer = Tokenizer(num_words=max_feature) tokenizer.fit_on_texts(texts) sequences = tokenizer.texts_to_sequences(texts) padded_sequences = pad_sequences(sequences, maxlen=max_len) return padded_sequences, tokenizer
2. 分离并处理数值特征
提取attachment列,转成二维numpy数组,方便后续和文本特征拼接:
def process_numeric_features(df): numeric_feat = df['attachment'].values.reshape(-1, 1) return numeric_feat
3. 修改模型结构:支持多输入(文本+数值)
改用函数式API构建模型,分别处理文本和数值特征后拼接输出:
from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Concatenate def model(max_feature, embed_size, max_len): # 文本分支 text_input = Input(shape=(max_len,), name='text_input') x = Embedding(max_feature, embed_size, input_length=max_len)(text_input) x = Conv1D(filters=64, kernel_size=7, padding='same', activation='relu')(x) x = MaxPooling1D(pool_size=2, padding='same')(x) x = Dropout(0.1)(x) x = Bidirectional(LSTM(64, recurrent_dropout=0.02, return_sequences=True))(x) x = GlobalMaxPool1D()(x) x = Dropout(0.1)(x) text_output = Dense(16, activation='relu')(x) # 数值分支 numeric_input = Input(shape=(1,), name='numeric_input') numeric_output = Dense(8, activation='relu')(numeric_input) # 拼接分支输出 combined = Concatenate()([text_output, numeric_output]) final_output = Dense(train_args["total_classes"], activation='softmax')(combined) model = Model(inputs=[text_input, numeric_input], outputs=final_output) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) logger.info(model.summary()) return model
4. 调整数据拆分与训练流程
在数据拆分和训练时,分别传入处理后的文本与数值特征:
def split_data(text_feat, numeric_feat, label): x_text_train, x_text_val, x_num_train, x_num_val, y_train, y_val = train_test_split( text_feat, numeric_feat, encode_labels(label), test_size=0.20, random_state=42, shuffle=True) data = { "train": {"text": x_text_train, "numeric": x_num_train, "y": y_train}, "test": {"text": x_text_val, "numeric": x_num_val, "y": y_val} } return data def train_model(data, train_args): logger.info("Starting training Neural Network") nn_model = model(train_args["max_feature"], train_args["embed_size"], train_args["max_len"]) history = nn_model.fit( [data["train"]["text"], data["train"]["numeric"]], data["train"]["y"], batch_size=64, epochs=10, validation_data=([data["test"]["text"], data["test"]["numeric"]], data["test"]["y"]) ) logger.info("Finished training Neural Network") return nn_model def main(): data_dir = "data" data_file = os.path.join(data_dir, 'data.csv') train_df = pd.read_csv(data_file) label = train_df["category"] # 预处理文本和数值特征 text_feat, tokenizer = preprocess_text(train_df['text'], train_args["max_feature"], train_args["max_len"]) numeric_feat = process_numeric_features(train_df) data = split_data(text_feat, numeric_feat, label) model = train_model(data, train_args) metrics = get_model_metrics(model, data) for (k, v) in metrics.items(): print(f"{k}: {v}")
5. 适配评估函数
评估时同样传入多输入:
def get_model_metrics(model, data): preds = model.predict([data["test"]["text"], data["test"]["numeric"]]) accuracy = accuracy_score(np.argmax(preds, axis=1), np.argmax(data["test"]["y"],axis=1)) metrics = {"accuracy_score": accuracy} return metrics
内容的提问来源于stack exchange,提问作者Deepak Soni
相关产品推荐
相关产品推荐

