TensorFlow多分类项目模型准确率0.03且不随epoch提升问题求助
问题排查与修正方案
你观察到的0.03准确率刚好是26类字母分类任务随机猜测的期望准确率(1/26≈0.038),且训练过程准确率无波动,说明模型完全没有学到有效模式,是代码中几处显性错误叠加导致的,具体问题点如下:
- 标签与损失函数不匹配:你提前对标签做了独热编码得到变量
Y,但在train_test_split拆分数据集时传入的是未做独热编码的原始整数标签y。而你编译模型时使用的categorical_crossentropy要求输入标签必须是独热格式,传入整数标签会导致损失计算逻辑完全错误,参数无法正常更新。如果要使用整数标签,需要将损失函数替换为sparse_categorical_crossentropy,无需提前做独热编码。 - 学习率设置严重过高:Adam优化器的默认推荐学习率是0.001,你设置的0.04是默认值的40倍,过大的步长会导致参数更新时直接跨过最优解,损失持续震荡甚至发散,模型根本无法收敛。
- 存在重复无效的标签编码逻辑:自定义的
naiveEncode已经将字符标签转为整数,后续又叠加了一层LabelEncoder做重复转换,虽然不会直接报错,但属于冗余逻辑,还可能因编码映射顺序不一致埋下隐患。 - 输入特征未做标准化:神经网络对输入特征的尺度非常敏感,你的特征取值范围覆盖0~15,不同列的数值差异较大,会导致梯度更新不稳定,大幅拖慢收敛速度甚至导致模型无法收敛。
- Keras导入路径混乱:代码前半部分从独立
keras包导入模型和层,后半部分又调用tf.keras的接口,版本适配不佳时容易出现维度不匹配、权重计算错误等隐性问题。
修正后可运行代码
import pandas as pd import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.optimizers import Adam from sklearn.preprocessing import LabelEncoder, StandardScaler from sklearn.model_selection import train_test_split # 加载数据集 df = pd.DataFrame({'lettr': ['T','I','D','N','G','S','B','A','J','M','X','O','G','M','R','F','O','C','T', 'J'], 'x-box': [2, 5, 4, 7, 2, 4, 4, 1, 2, 11, 3, 6, 4, 6, 5, 6, 3, 7, 6, 2], 'y-box': [8, 12, 11, 11, 1, 11, 2, 1, 2, 15, 9, 13, 9, 9, 9, 9, 4, 10, 11, 2], 'width': [3, 3, 6, 6, 3, 5, 5, 3, 4, 13, 5, 4, 6, 8, 5, 5, 4, 5, 6, 3], 'high': [5, 7, 8, 6, 1, 8, 4, 2, 4, 9, 7, 7, 7, 6, 7, 4, 3, 5, 8, 3], 'onpix':[1, 2, 6, 3, 1, 3, 4, 1, 2, 7, 4, 4, 6, 9, 6, 3, 2, 2, 5, 1], 'x-bar':[8, 10, 10, 5, 8, 8, 8, 8, 10, 13, 8, 6, 7, 7, 6, 10, 8, 6, 6, 10], 'y-bar':[13, 5, 6, 9, 6, 8, 7, 2, 6, 2, 7, 7, 8, 8, 11, 6, 7, 8, 11, 6], 'x2bar':[0, 5, 2, 4, 6, 6, 6, 2, 2, 6, 3, 6, 6, 6, 7, 3, 7, 6, 5, 3], 'y2bar':[6, 4, 6, 6, 6, 9, 6, 2, 6, 2, 8, 3, 2, 5, 3, 5, 5, 8, 6, 6], 'xybar':[6, 13, 10, 4, 6, 5, 7, 8, 12, 12, 5, 10, 6, 7, 7, 10, 7, 11, 11, 12], 'x2ybr':[10, 3, 3, 4, 5, 6, 6, 2, 4, 1, 6, 7, 5, 5, 3, 5, 6, 7, 9, 4], 'xy2br':[8, 9, 7, 10, 9, 6, 6, 8, 8, 9, 8, 9, 11, 8, 9, 7, 8, 11, 4, 9], 'x-ege':[0, 2, 3, 6, 1, 0, 2, 1, 1, 8, 2, 5, 4, 8, 2, 3, 2, 2, 3, 0], 'xegvy':[8, 8, 7, 10, 7, 8, 8, 6, 6, 1, 8, 9, 8, 9, 7, 9, 8, 8, 12, 7], 'y-ege':[0, 4, 3, 2, 5, 9, 7, 2, 1, 1, 6, 5, 7, 8, 5, 6, 3, 5, 2, 1], 'yegvx':[8, 10, 9, 8, 10, 7, 10, 7, 7, 8, 7, 8, 8, 6, 11, 9, 8, 9, 4, 7], }) # 标签编码(移除冗余的自定义编码逻辑) encoder = LabelEncoder() y = encoder.fit_transform(df["lettr"].values) X = df.iloc[:,1:].values # 特征标准化 scaler = StandardScaler() X = scaler.fit_transform(X) # 拆分数据集,固定随机种子保证结果可复现 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 构建模型,统一导入路径 model = Sequential([ Dense(128, activation="relu", input_shape=(16,)), Dense(64, activation="relu"), Dense(32, activation="relu"), Dense(26, activation="softmax") ]) # 调整学习率为默认值,匹配整数标签使用对应损失函数 model.compile(Adam(learning_rate=0.001), loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.summary() # 训练时加入验证集监控泛化效果 model.fit(X_train, y_train, epochs=50, batch_size=4, validation_data=(X_test, y_test))
注:20行测试样本量过小,训练效果会有较大波动,在20000行的完整数据集上运行修正后的代码,模型可以正常收敛,测试集准确率可达90%以上。
内容的提问来源于stack exchange,提问作者Socka
相关产品推荐
相关产品推荐

