基于4折交叉验证的车辆分类神经网络构建及精度提升问询
车辆分类任务:4折交叉验证神经网络精度优化方案
问题概述
我是深度学习新手,正在用4折交叉验证搭建神经网络完成车辆分类任务,当前模型精度仅0.7。已生成训练精度曲线和Epoch输出示例,不确定代码是否存在问题,急需能有效提升精度的方法。
现有代码
!pip install category_encoders import tensorflow as tf from sklearn.model_selection import KFold import pandas as pd import numpy as np from tensorflow import keras import category_encoders as ce from category_encoders import OrdinalEncoder car_data = pd.read_csv('car_data.csv') car_data.columns = ['Purchasing', 'Maintenance', 'No_Doors','Capacity','BootSize','Safety','Evaluation'] # 提取特征和标签 X = car_data.drop(['Evaluation'], axis=1) Y = car_data['Evaluation'] # 编码特征 encoder = ce.OrdinalEncoder(cols=['Purchasing', 'Maintenance', 'No_Doors','Capacity','BootSize','Safety']) X = encoder.fit_transform(X) X = X.to_numpy() # 编码标签 Y_df = pd.DataFrame(Y, columns=['Evaluation']) encoder = OrdinalEncoder(cols=['Evaluation']) Y_encoded = encoder.fit_transform(Y_df) Y = Y_encoded.to_numpy() # 搭建模型 input_layer = tf.keras.layers.Input(shape=(X.shape[1])) hidden_layer_1 = tf.keras.layers.Dense(units=64, activation='relu', kernel_initializer='glorot_uniform')(input_layer) hidden_layer_2 = tf.keras.layers.Dense(units=32, activation='relu', kernel_initializer='glorot_uniform')(hidden_layer_1) output_layer = tf.keras.layers.Dense(units=1, activation='sigmoid', kernel_initializer='glorot_uniform')(hidden_layer_2) model = tf.keras.Model(inputs=input_layer, outputs=output_layer) # 4折交叉验证初始化 kfold = KFold(n_splits=4, shuffle=True, random_state=42) scores = [] quality_weights= [] # 编译模型 model.compile(optimizer='adam', loss=''sparse_categorical_crossentropy'', metrics=['accuracy'], sample_weight_mode='temporal') for train_index, test_index in kfold.split(X,Y): X_train, X_test = X[train_index], X[test_index] Y_train, Y_test = Y[train_index], Y[test_index] # 训练模型 model.fit(X_train, Y_train, epochs=300, batch_size=64, sample_weight=quality_weights) # 评估模型 score = model.evaluate(X_test, Y_test) scores.append(score[1]) # 绘制精度曲线 plt.plot(history.history['accuracy']) plt.title('Model Training Accuracy') plt.ylabel('Accuracy') plt.xlabel('Epoch') plt.legend(['Train'], loc='upper left') plt.show() # 输出平均精度 print(f'Mean accuracy: {np.mean(scores):.3f} +/- {np.std(scores):.3f}')
代码错误修正
- 损失函数语法错误:
loss=''sparse_categorical_crossentropy''嵌套了双引号,改成loss='sparse_categorical_crossentropy'即可 - 输出层与任务不匹配:车辆分类是多分类任务(标签为unacc/acc/good/vgood四类),但当前用了
units=1+sigmoid的二分类配置,必须改成units=4+softmax - 缺失依赖导入:代码中用了
plt但没导入matplotlib,要加import matplotlib.pyplot as plt - history变量未定义:
model.fit()的返回值没赋值给history,改成history = model.fit(...)才能绘制曲线 - 空样本权重报错:
quality_weights是空列表,直接传入会报错,要么删掉这个参数,要么根据类别分布设置合理权重 - 交叉验证模型复用问题:当前循环里复用同一个模型,每轮训练会在上一轮权重基础上继续,不符合交叉验证“每折独立训练”的要求,必须在每轮折叠里重新初始化模型
精度提升具体方法
1. 模型结构优化
- 修正输出层:把输出层改为
tf.keras.layers.Dense(units=4, activation='softmax'),匹配多分类任务 - 增加正则化:在隐藏层加入Dropout层(比如
tf.keras.layers.Dropout(0.2))或者L2正则(kernel_regularizer=tf.keras.regularizers.l2(0.01)),防止过拟合 - 调整网络规模:尝试增加隐藏层数量(比如加一层64神经元的隐藏层),或者调整神经元数量(比如128→64→32)
2. 数据预处理优化
- 替换编码方式:Ordinal编码会给类别强加顺序(比如把Purchasing的low/med/high编码成1/2/3),但这些类别实际没有顺序意义,换成**独热编码(OneHotEncoder)**效果会更好
- 特征归一化:用
sklearn.preprocessing.StandardScaler对特征做标准化,神经网络对输入尺度敏感,归一化后能加快收敛,提升精度
3. 训练策略调整
- 加入早停机制:添加
tf.keras.callbacks.EarlyStopping(monitor='val_accuracy', patience=10, restore_best_weights=True),训练到验证精度不再提升就停止,避免过拟合,还能节省时间 - 启用验证集:在
model.fit()里加validation_split=0.1,实时监控验证精度,判断模型是否过拟合 - 调整超参数:试试不同的batch_size(比如32、128),或者降低Adam的学习率(比如
optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001))
4. 类别不平衡处理
检查数据集的类别分布,如果某类样本占比极低,要么对该类做过采样,要么对大类做欠采样,或者在model.fit()里传入class_weight参数平衡类别权重
5. 规范交叉验证流程
每一轮折叠都要重新创建模型,保证每折的模型都是从零开始训练,示例代码片段如下:
for train_index, test_index in kfold.split(X,Y): # 每折都重新初始化模型 input_layer = tf.keras.layers.Input(shape=(X.shape[1])) hidden_layer_1 = tf.keras.layers.Dense(units=64, activation='relu')(input_layer) dropout_1 = tf.keras.layers.Dropout(0.2)(hidden_layer_1) hidden_layer_2 = tf.keras.layers.Dense(units=32, activation='relu')(dropout_1) dropout_2 = tf.keras.layers.Dropout(0.2)(hidden_layer_2) output_layer = tf.keras.layers.Dense(units=4, activation='softmax')(dropout_2) model = tf.keras.Model(inputs=input_layer, outputs=output_layer) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) X_train, X_test = X[train_index], X[test_index] Y_train, Y_test = Y[train_index], Y[test_index] history = model.fit(X_train, Y_train, epochs=300, batch_size=64, validation_split=0.1, callbacks=[early_stop]) score = model.evaluate(X_test, Y_test) scores.append(score[1])
内容的提问来源于stack exchange,提问作者zed
相关产品推荐
相关产品推荐

