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

如何修改代码让训练后的模型为每个类别生成不同预测值?

问题:所有类别预测值相同的模型修复方案

针对你遇到的模型对所有类别输出相同预测值的问题,以下是具体的问题分析和代码修改方案:

核心问题分析

  1. 类别预处理逻辑冗余:你用Tokenizer处理离散类别属于误用,Tokenizer适用于文本序列,而你的category是独立离散值,直接用标签编码更高效。
  2. 训练参数不合理:过大的batch_size(1000)会导致梯度更新不充分,模型无法学到类别间的差异;固定100轮epochs可能出现欠拟合或过拟合。
  3. 未处理数据集不平衡:如果某个value的样本占比过高,模型会倾向于预测该类别,导致所有输出一致。

具体修改方案

1. 修正类别预处理逻辑

替换原有的Tokenizer流程,用LabelEncoder对离散类别进行编码:

from sklearn.preprocessing import LabelEncoder

# 对category进行标签编码
le_category = LabelEncoder()
categories_encoded = le_category.fit_transform(categories)
categories_encoded = categories_encoded.reshape(-1, 1)  # 调整为模型可接受的形状

2. 调整模型结构

针对离散类别输入,简化模型并适配标签编码的输入格式:

model = tf.keras.Sequential([
    tf.keras.layers.Embedding(input_dim=len(le_category.classes_), output_dim=32, input_length=1),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(len(value_labels), activation='softmax')
])

3. 优化训练参数

  • 减小batch_size让梯度更新更频繁
  • 添加早停回调防止过拟合,同时保留最优权重
  • 计算类别权重处理数据集不平衡:
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.utils.class_weight import compute_class_weight

# 计算类别权重
class_weights = compute_class_weight('balanced', classes=np.unique(y_train), y=y_train)
class_weight_dict = {i: class_weights[i] for i in range(len(class_weights))}

# 早停回调
early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# 训练模型
model.fit(X_train, y_train, epochs=50, batch_size=32, 
          validation_data=(X_test, y_test), callbacks=[early_stop],
          class_weight=class_weight_dict)

4. 修正预测函数

适配标签编码的输入流程,避免重复计算映射关系:

# 提前创建value的反向映射(只执行一次)
value_inv_mapping = {i: value for i, value in enumerate(value_labels)}

def generate_prediction(input_category, le_category, model, value_inv_mapping):
    # 对输入类别编码
    category_encoded = le_category.transform([input_category]).reshape(-1, 1)
    # 生成预测(关闭日志输出)
    prediction = model.predict(category_encoded, verbose=0)
    predicted_label = np.argmax(prediction)
    # 映射回原始value
    predicted_value = value_inv_mapping[predicted_label]
    return predicted_value

完整修改后的代码

import numpy as np
import pandas as pd
import tensorflow as tf
import random
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.utils.class_weight import compute_class_weight

# 读取数据集
data = pd.read_csv('dataset.csv')

# 数据预处理
categories = data['category'].tolist()
values = data['value'].tolist()

# 对category进行标签编码
le_category = LabelEncoder()
categories_encoded = le_category.fit_transform(categories)
categories_encoded = categories_encoded.reshape(-1, 1)

# 编码目标变量
value_labels = np.unique(values)
value_mapping = {value: i for i, value in enumerate(value_labels)}
encoded_values = np.array([value_mapping[value] for value in values])
value_inv_mapping = {i: value for i, value in enumerate(value_labels)}

# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(
    categories_encoded, encoded_values, test_size=0.2, random_state=42
)

# 计算类别权重
class_weights = compute_class_weight('balanced', classes=np.unique(y_train), y=y_train)
class_weight_dict = {i: class_weights[i] for i in range(len(class_weights))}

# 构建模型
model = tf.keras.Sequential([
    tf.keras.layers.Embedding(input_dim=len(le_category.classes_), output_dim=32, input_length=1),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(len(value_labels), activation='softmax')
])

# 编译模型
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 早停回调
early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# 训练模型
model.fit(X_train, y_train, epochs=50, batch_size=32, 
          validation_data=(X_test, y_test), callbacks=[early_stop],
          class_weight=class_weight_dict)

# 保存模型
model.save('model/category_predictor')
model.save('model/category_predictor.h5')

# 预测函数
def generate_prediction(input_category, le_category, model, value_inv_mapping):
    category_encoded = le_category.transform([input_category]).reshape(-1, 1)
    prediction = model.predict(category_encoded, verbose=0)
    predicted_label = np.argmax(prediction)
    predicted_value = value_inv_mapping[predicted_label]
    return predicted_value

# 测试预测
categories_test = list(set(data['category'].tolist()))
keywords = []
prompts = []

for _ in range(10):
    input_category = random.choice(categories_test)
    predicted_value = generate_prediction(input_category, le_category, model, value_inv_mapping)
    keywords.append(input_category)
    prompts.append(predicted_value)

# 打印结果
for keyword, prompt in zip(keywords, prompts):
    print(f'Input category: {keyword} | Predicted value: {prompt}')

内容的提问来源于stack exchange,提问作者Teodor G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:55:06