使用Keras基于图表预测Roc值时准确率为0的问题排查
问题描述
我是神经网络领域新手,尝试用TensorFlow/Keras编写预测算法,基于提取的图表数据,通过Alt(高度)和Temp(温度)预测Roc值。此前模型准确率曾达到0.2至0.5,虽不理想但可优化,然而之后准确率骤降为0,无论调整参数都无法恢复。
附相关代码
# import tensorflow as tf from tensorflow import keras import numpy as np import pandas as pd import sklearn.model_selection # Data collection factor = 10 data = pd.read_csv("roc_6800_ibf.csv", sep=",") data = data.apply(pd.to_numeric, errors='coerce') data = (data / factor) + 5 predict = "Roc" x = np.array(data.drop([predict], axis=1)) y = np.array(data[predict]) x_train, x_test, y_train, y_test = sklearn.model_selection.train_test_split(x, y, test_size=0.2) x_shape = int(x.ndim) y_shape = int(y.ndim) # Model model = keras.Sequential([ keras.layers.Dense(units=(2), input_shape=(2,), activation="relu"), keras.layers.Dense(4, activation="relu"), keras.layers.Dense(1, activation="relu") ]) model.compile(optimizer="adam", loss="MeanSquaredError", metrics=["accuracy"]) model.fit(x_train, y_train, epochs=20, batch_size=10, verbose=1) results = model.evaluate(x_test, y_test) print("- - - - - - - - - - - - - - - - - - - - - - - -") print(results) # Prediction def dataPredict(inputvalues, outputvalues): print("- - - - - - - - - - - - - - - - - - - - - - - -") test_q = np.array([inputvalues]) test_a = outputvalues prediction = model.predict((test_q / factor) + 5) print("Prediction " + str((prediction[0] - 5) * factor)) print("Actual " + str(test_a[0])) print("Input " + str(test_q)) dataPredict([5.5,20.0],[3.6]) dataPredict([6.8,30.0],[0.4])
数据集(72条记录)
Alt,Temp,Roc -1.0,-40.0,9.6 0.0,-40.0,9.6 1.0,-40.0,9.6 2.0,-40.0,9.6 3.0,-40.0,9.6 4.0,-40.0,9.6 5.0,-40.0,9.6 6.0,-40.0,9.6 7.0,-40.0,8.1 8.0,-40.0,7.9 7.5,-40.0,9.1 -1.0,0.0,9.6 0.0,0.0,9.6 1.0,0.0,9.6 2.0,0.0,9.6 2.1,0.0,9.6 3.0,0.0,9.0 4.0,0.0,8.0 5.0,0.0,6.6 6.0,0.0,5.5 7.0,0.0,4.2 8.0,0.0,3.2 -1.0,20.0,9.6 0.0,20.0,9.6 0.5,20.0,9.0 1.0,20.0,8.6 2.0,20.0,7.8 3.0,20.0,6.2 4.0,20.0,5.2 5.0,20.0,4.0 6.0,20.0,2.9 7.0,20.0,1.8 8.0,20.0,0.5 -1.0,40.0,7.5 0.0,40.0,6.8 1.0,40.0,5.6 2.0,40.0,4.2 3.0,40.0,3.2 4.0,40.0,2.2 5.0,40.0,1.0 -1.0,50.0,5.4 0.0,50.0,4.2 -0.5,-40.0,9.5 0.5,-40.0,9.5 1.5,-40.0,9.5 2.5,-40.0,9.5 3.5,-40.0,9.5 4.5,-40.0,9.5 5.5,-40.0,9.5 6.5,-40.0,9.1 7.5,-40.0,8.1 -0.5,-10.0,9.5 0.5,-10.0,9.5 1.5,-10.0,9.5 2.5,-10.0,9.5 3.5,-10.0,9.5 4.5,-10.0,8.3 5.5,-10.0,7.1 6.5,-10.0,6.0 7.5,-10.0,5.0 -0.5,30.0,8.4 0.5,30.0,7.6 1.5,30.0,6.4 2.5,30.0,5.5 3.5,30.0,4.2 4.5,30.0,3.1 5.5,30.0,1.9 6.5,30.0,0.8 7.5,30.0,-0.5 5.2,10.0,5.3 6.8,10.0,4.0
异常训练日志
Epoch 20/20 6/6 [==============================] - 0s 2ms/step - loss: 32.5049 - accuracy: 0.0000e+00
核心原因与解决办法
1. 回归任务误用分类指标accuracy
你做的是回归任务(预测连续型Roc值),但用了分类任务专属的accuracy指标。accuracy统计的是预测类别与真实类别完全匹配的比例,回归任务中预测值和真实值几乎不可能完全相等,因此准确率直接变为0。之前那0.2-0.5的数值也是无意义的巧合。
2. 输出层激活函数错误
输出层使用relu激活函数,但你的Roc值存在负数(如7.5,30.0,-0.5),relu会将所有负数截断为0,导致模型无法学习负向Roc的规律,最终训练崩溃。
3. 数据预处理逻辑冗余
自定义的(data / factor) + 5转换没必要,反而打乱了数据原始分布,增加模型学习难度。用标准化/归一化这类通用预处理方法更稳妥。
修正后的代码示例
from tensorflow import keras import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 数据读取与预处理 data = pd.read_csv("roc_6800_ibf.csv", sep=",") data = data.apply(pd.to_numeric, errors='coerce').dropna() # 清理无效数据 predict = "Roc" x = data.drop([predict], axis=1).values y = data[predict].values # 数据标准化(适配神经网络输入) scaler_x = StandardScaler() scaler_y = StandardScaler() x_scaled = scaler_x.fit_transform(x) y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)) # 划分训练测试集 x_train, x_test, y_train, y_test = train_test_split(x_scaled, y_scaled, test_size=0.2, random_state=42) # 构建回归模型 model = keras.Sequential([ keras.layers.Dense(8, input_shape=(2,), activation="relu"), keras.layers.Dense(4, activation="relu"), keras.layers.Dense(1) # 回归任务输出层无需激活函数 ]) # 回归任务用MSE损失,监控MAE(平均绝对误差)指标 model.compile(optimizer="adam", loss="MeanSquaredError", metrics=["MeanAbsoluteError"]) # 训练模型(加入验证集监控过拟合) history = model.fit(x_train, y_train, epochs=50, batch_size=8, verbose=1, validation_split=0.1) # 评估模型 results = model.evaluate(x_test, y_test) print("-"*50) print(f"测试集损失: {results[0]:.4f}, 平均绝对误差: {results[1]:.4f}") # 预测函数(适配标准化转换) def dataPredict(inputvalues, outputvalues): print("-"*50) test_q_scaled = scaler_x.transform(np.array([inputvalues])) prediction_scaled = model.predict(test_q_scaled, verbose=0) prediction = scaler_y.inverse_transform(prediction_scaled)[0][0] print(f"预测值: {prediction:.2f}") print(f"真实值: {outputvalues[0]}") print(f"输入值: {inputvalues}") dataPredict([5.5,20.0],[3.6]) dataPredict([6.8,30.0],[0.4])
额外建议
- 数据集仅72条,数据量极小,易过拟合,可添加
keras.layers.Dropout(0.2)层抑制过拟合,或使用更简单的模型结构。 - 训练时通过
validation_split监控验证集损失,避免模型在训练集上过度拟合。 - 回归任务不要关注
accuracy,重点看MeanSquaredError(均方误差)或MeanAbsoluteError(平均绝对误差),数值越小说明预测越准确。
内容的提问来源于stack exchange,提问作者Bengt B
相关产品推荐
相关产品推荐

