Google Colab中Keras模型训练报错:数据基数不匹配求助
问题分析与解决
核心错误原因
你遇到的ValueError是因为训练数据的输入(X)和标签(Y)样本数量完全不匹配:
- 错误用了
match.xlsx里的3543条待匹配数据当作训练输入X - 同时用了
categ.xlsx里的37个分类当作标签Y
这两者没有对应关系,模型无法学习。正确逻辑应该是用ex.xlsx里的785条文本(fix)与分类(categ)的对应数据训练,之后再用match.xlsx的数据做预测。
修正后的完整代码
import pandas as pd import numpy as np import tensorflow as tf from tensorflow import keras from keras.utils import pad_sequences from keras.preprocessing.text import Tokenizer from keras.layers import Input, Embedding, LSTM, Dense from keras.models import Model from sklearn.preprocessing import LabelEncoder # 读取文件(优化重复上传逻辑) from google.colab import files # 依次上传三个文件 print("上传categ.xlsx") upload_categ = files.upload() print("上传ex.xlsx") upload_ex = files.upload() print("上传match.xlsx") upload_match = files.upload() # 读取Excel数据 df_categories = pd.read_excel('categ.xlsx', index_col=None) df_examples = pd.read_excel('ex.xlsx', index_col=None) df_to_distribute = pd.read_excel('match.xlsx', index_col=None) # 数据预处理 # 1. 提取训练数据:ex中的文本输入和对应分类标签 train_texts = df_examples['fix'].astype(str).tolist() train_labels = df_examples['categ'].astype(str).tolist() # 2. 提取待预测数据 predict_texts = df_to_distribute['match'].astype(str).tolist() # 3. 提取所有分类用于后续映射 all_categories = df_categories['categ'].astype(str).tolist() # 4. 文本Tokenizer:拟合所有相关文本(训练+分类+待预测) tokenizer = Tokenizer() tokenizer.fit_on_texts(train_texts + all_categories + predict_texts) # 5. 转换文本为序列并统一长度 max_length = max(len(tokenizer.texts_to_sequences([text])[0]) for text in train_texts + predict_texts) train_sequences = tokenizer.texts_to_sequences(train_texts) padded_train_sequences = pad_sequences(train_sequences, maxlen=max_length, padding='post') predict_sequences = tokenizer.texts_to_sequences(predict_texts) padded_predict_sequences = pad_sequences(predict_sequences, maxlen=max_length, padding='post') # 6. 标签编码:把分类文本转成模型可识别的整数ID label_encoder = LabelEncoder() label_encoder.fit(all_categories) encoded_train_labels = label_encoder.transform(train_labels) # 构建模型 input_layer = Input(shape=(max_length,)) embedding_layer = Embedding(input_dim=len(tokenizer.word_index) + 1, output_dim=64)(input_layer) lstm_layer = LSTM(64)(embedding_layer) # 输出层神经元数等于分类总数(37个) output_layer = Dense(len(all_categories), activation='softmax')(lstm_layer) model = Model(inputs=input_layer, outputs=output_layer) model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # 训练模型:使用ex中的对应数据训练 model.fit(padded_train_sequences, encoded_train_labels, epochs=10, batch_size=32, validation_split=0.2) # 预测待匹配数据 predictions = model.predict(padded_predict_sequences) # 将预测的整数ID转回分类文本 predicted_categories = label_encoder.inverse_transform(np.argmax(predictions, axis=1)) # 为待匹配数据添加分类列 df_to_distribute['predicted_categ'] = predicted_categories # 保存结果(可选) df_to_distribute.to_excel('matched_result.xlsx', index=False) print("匹配结果已保存为matched_result.xlsx")
关键修正点说明
- 训练数据对应关系:用
ex.xlsx里的fix文本作为模型输入,对应的categ作为标签,两者样本数均为785,彻底解决样本数量不匹配问题。 - 标签处理:用
LabelEncoder将分类文本转换为整数ID,符合sparse_categorical_crossentropy损失函数的输入要求,替代了错误的分类序列转换逻辑。 - 模型输出层调整:输出层神经元数设置为分类总数(37),对应37个分类的概率输出。
- 预测流程:训练完成后再对
match.xlsx的数据进行预测,将预测结果映射回分类文本并添加到原数据中。 - 代码优化:移除重复的文件上传和读取逻辑,简化代码结构。
内容的提问来源于stack exchange,提问作者Никитий
相关产品推荐
相关产品推荐

