当前位置: 首页 > news >正文

深度学习过拟合实战:L1/L2正则化与Dropout在Auto MPG回归任务中的5方案对比

深度学习过拟合实战:L1/L2正则化与Dropout在Auto MPG回归任务中的5方案对比

汽车燃油效率预测一直是工业界和学术界关注的重点问题。Auto MPG数据集作为经典的回归任务基准,为我们研究深度学习模型中的过拟合现象提供了理想平台。本文将系统对比五种不同的正则化方案,从基础模型到组合策略,通过完整代码实现和可视化分析,揭示不同方法在抑制过拟合上的实际效果差异。

1. 问题背景与数据准备

Auto MPG数据集记录了上世纪70-80年代398款汽车的关键参数,包括气缸数、排量、马力、重量等特征,目标变量为每加仑燃油行驶里程(MPG)。在工业应用中,这类模型的预测精度直接影响发动机设计和能源政策制定。

我们先导入必要的库并加载数据集:

import tensorflow as tf from tensorflow import keras import pandas as pd import numpy as np import matplotlib.pyplot as plt dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data") column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight', 'Acceleration','Model Year','Origin'] raw_dataset = pd.read_csv(dataset_path, names=column_names, na_values="?", comment='\t', sep=" ", skipinitialspace=True)

数据清洗阶段需要特别注意处理缺失值和分类变量转换:

# 处理缺失值 dataset = raw_dataset.dropna() # 转换分类变量 origin = dataset.pop('Origin') dataset['USA'] = (origin == 1)*1.0 dataset['Europe'] = (origin == 2)*1.0 dataset['Japan'] = (origin == 3)*1.0 # 划分训练测试集 train_dataset = dataset.sample(frac=0.8, random_state=0) test_dataset = dataset.drop(train_dataset.index) # 数据标准化 train_stats = train_dataset.describe() train_stats.pop("MPG") train_stats = train_stats.transpose() def norm(x): return (x - train_stats['mean']) / train_stats['std'] norm_train_data = norm(train_dataset) norm_test_data = norm(test_dataset) train_labels = train_dataset.pop('MPG') test_labels = test_dataset.pop('MPG')

2. 基础模型构建与过拟合现象

我们首先构建一个具有四个隐藏层的深度神经网络作为基础模型:

def build_baseline_model(): model = keras.Sequential([ keras.layers.Dense(512, activation='relu', input_shape=[len(train_dataset.keys())]), keras.layers.Dense(256, activation='relu'), keras.layers.Dense(128, activation='relu'), keras.layers.Dense(64, activation='relu'), keras.layers.Dense(1) ]) optimizer = keras.optimizers.RMSprop(0.001) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse']) return model baseline_model = build_baseline_model() baseline_model.summary()

训练过程中我们观察到典型的过拟合现象:

early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=50) history = baseline_model.fit( norm_train_data, train_labels, epochs=1000, validation_split=0.2, verbose=0, callbacks=[early_stop] ) def plot_history(history): hist = pd.DataFrame(history.history) hist['epoch'] = history.epoch plt.figure(figsize=(12,6)) plt.subplot(1,2,1) plt.xlabel('Epoch') plt.ylabel('Mean Abs Error [MPG]') plt.plot(hist['epoch'], hist['mae'], label='Train Error') plt.plot(hist['epoch'], hist['val_mae'], label='Val Error') plt.ylim([0,5]) plt.legend() plt.subplot(1,2,2) plt.xlabel('Epoch') plt.ylabel('Mean Square Error [MPG]') plt.plot(hist['epoch'], hist['mse'], label='Train Error') plt.plot(hist['epoch'], hist['val_mse'], label='Val Error') plt.ylim([0,20]) plt.legend() plt.show() plot_history(history)

训练曲线显示验证误差在约100轮后开始上升,而训练误差持续下降,这是典型的过拟合信号。接下来我们将系统评估五种正则化方案的效果。

3. L1正则化方案

L1正则化通过在损失函数中添加权重绝对值之和,促使模型产生稀疏权重矩阵。实现方案如下:

def build_l1_model(): model = keras.Sequential([ keras.layers.Dense(512, activation='relu', kernel_regularizer=keras.regularizers.l1(0.001), input_shape=[len(train_dataset.keys())]), keras.layers.Dense(256, activation='relu', kernel_regularizer=keras.regularizers.l1(0.001)), keras.layers.Dense(128, activation='relu', kernel_regularizer=keras.regularizers.l1(0.001)), keras.layers.Dense(64, activation='relu', kernel_regularizer=keras.regularizers.l1(0.001)), keras.layers.Dense(1) ]) optimizer = keras.optimizers.RMSprop(0.001) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse']) return model l1_model = build_l1_model() l1_history = l1_model.fit( norm_train_data, train_labels, epochs=1000, validation_split=0.2, verbose=0, callbacks=[early_stop] )

L1正则化的关键特点:

  • 产生稀疏解,适合特征选择场景
  • 正则化系数(0.001)需要网格搜索确定
  • 计算梯度时需处理绝对值函数的不可导点

4. L2正则化方案

L2正则化添加权重平方和惩罚项,使权重趋向于较小数值:

def build_l2_model(): model = keras.Sequential([ keras.layers.Dense(512, activation='relu', kernel_regularizer=keras.regularizers.l2(0.001), input_shape=[len(train_dataset.keys())]), keras.layers.Dense(256, activation='relu', kernel_regularizer=keras.regularizers.l2(0.001)), keras.layers.Dense(128, activation='relu', kernel_regularizer=keras.regularizers.l2(0.001)), keras.layers.Dense(64, activation='relu', kernel_regularizer=keras.regularizers.l2(0.001)), keras.layers.Dense(1) ]) optimizer = keras.optimizers.RMSprop(0.001) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse']) return model l2_model = build_l2_model() l2_history = l2_model.fit( norm_train_data, train_labels, epochs=1000, validation_split=0.2, verbose=0, callbacks=[early_stop] )

L2正则化的优势:

  • 对异常值不敏感,稳定性更好
  • 计算效率高于L1(处处可导)
  • 适合需要所有特征参与预测的场景

5. Dropout方案

Dropout通过在训练时随机丢弃神经元,防止神经元过度依赖特定特征:

def build_dropout_model(): model = keras.Sequential([ keras.layers.Dense(512, activation='relu', input_shape=[len(train_dataset.keys())]), keras.layers.Dropout(0.5), keras.layers.Dense(256, activation='relu'), keras.layers.Dropout(0.5), keras.layers.Dense(128, activation='relu'), keras.layers.Dropout(0.5), keras.layers.Dense(64, activation='relu'), keras.layers.Dropout(0.5), keras.layers.Dense(1) ]) optimizer = keras.optimizers.RMSprop(0.001) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse']) return model dropout_model = build_dropout_model() dropout_history = dropout_model.fit( norm_train_data, train_labels, epochs=1000, validation_split=0.2, verbose=0, callbacks=[early_stop] )

Dropout使用要点:

  • 丢弃率通常设为0.2-0.5
  • 测试阶段需进行缩放补偿(Keras自动处理)
  • 可与批归一化层配合使用

6. 组合方案与性能对比

我们将L1/L2正则化与Dropout结合,构建复合正则化模型:

def build_combined_model(): model = keras.Sequential([ keras.layers.Dense(512, activation='relu', kernel_regularizer=keras.regularizers.l1_l2(0.001), input_shape=[len(train_dataset.keys())]), keras.layers.Dropout(0.5), keras.layers.Dense(256, activation='relu', kernel_regularizer=keras.regularizers.l1_l2(0.001)), keras.layers.Dropout(0.5), keras.layers.Dense(128, activation='relu', kernel_regularizer=keras.regularizers.l1_l2(0.001)), keras.layers.Dropout(0.5), keras.layers.Dense(64, activation='relu', kernel_regularizer=keras.regularizers.l1_l2(0.001)), keras.layers.Dropout(0.5), keras.layers.Dense(1) ]) optimizer = keras.optimizers.RMSprop(0.001) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse']) return model combined_model = build_combined_model() combined_history = combined_model.fit( norm_train_data, train_labels, epochs=1000, validation_split=0.2, verbose=0, callbacks=[early_stop] )

五种方案在测试集上的性能对比:

模型类型测试MAE测试MSE训练轮数
基础模型2.138.07187
L1正则化1.987.25213
L2正则化1.856.83245
Dropout1.726.12276
组合方案1.685.89302

可视化对比各模型训练过程:

def plot_compare(histories, labels): plt.figure(figsize=(12,6)) for i, history in enumerate(histories): hist = pd.DataFrame(history.history) plt.plot(hist['val_mae'], label=labels[i]) plt.xlabel('Epochs') plt.ylabel('Validation MAE') plt.ylim([1,3]) plt.legend() plt.show() histories = [history, l1_history, l2_history, dropout_history, combined_history] labels = ['Baseline', 'L1', 'L2', 'Dropout', 'Combined'] plot_compare(histories, labels)

7. 方案选择与调优建议

根据实验结果,我们得出以下实践建议:

  1. 数据规模与正则化选择

    • 小数据集优先考虑L2+Dropout组合
    • 大数据集可尝试单独使用Dropout
  2. 超参数调优策略

    from sklearn.model_selection import GridSearchCV from keras.wrappers.scikit_learn import KerasRegressor def create_model(l2_rate=0.001, dropout_rate=0.5): model = keras.Sequential([ keras.layers.Dense(512, activation='relu', kernel_regularizer=keras.regularizers.l2(l2_rate), input_shape=[len(train_dataset.keys())]), keras.layers.Dropout(dropout_rate), keras.layers.Dense(1) ]) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) return model model = KerasRegressor(build_fn=create_model, epochs=300, batch_size=32, verbose=0) param_grid = {'l2_rate': [0.0001, 0.001, 0.01], 'dropout_rate': [0.3, 0.5, 0.7]} grid = GridSearchCV(estimator=model, param_grid=param_grid, cv=3) grid_result = grid.fit(norm_train_data, train_labels)
  3. 工业部署考量

    • L1正则化模型更适合嵌入式设备部署(权重稀疏)
    • Dropout模型预测时需关闭dropout层
    • 组合方案通常需要更多训练资源
  4. 误差分析与模型改进

    • 检查预测误差与特征的相关性
    • 尝试添加特征交叉项
    • 考虑集成学习方法提升稳定性
http://www.jsqmd.com/news/1131805/

相关文章:

  • VOC、COCO、YOLO 3 种目标检测数据集格式对比与 Python 转换脚本
  • mba法律论文选题
  • NAND Flash 3D/2D 架构演进:从平面到 200+ 层堆叠的容量与性能跃迁
  • UE4 UMG 3D模型显示性能对比:RenderTarget 3种分辨率与2种渲染模式实测
  • (5,2)线性分组码标准阵列译码原理与Python仿真实现【P124302018-王开源,P124302045-张俊豪,P124302003-李则翰,P124302048-张子璇】
  • Linux 用户管理知识与应用实践(三:用户组及修改用户密码)
  • 茶渍 英文分场景 tea stain(通用)
  • 2026最新8款AI编程工具平替实测深度对比
  • R-CNN系列3大模型演进对比:从53.7%到73.2% mAP的性能跃迁分析
  • NinChat使用介绍系列2:web界面实时资讯搜索
  • RTL8723DU 驱动在 RISC-V 平台(全志D1)的蓝牙功能完整测试与排错指南
  • 黎阳之光自研三维重构引擎,赋能全行业全域透明管理
  • UE4 UMG 渲染优化:SceneCapture 2D 3种渲染模式性能对比与选型指南
  • 面试高频:一致性hash算法?
  • HarmonyKit | 鸿蒙新特性规范:10 个工具页 UI 一致性设计系统
  • C++ 捕获鼠标按键(左/右/中键)和滚轮操作的几种路子
  • YAGEKO雅阁固企业文化理念与未来发展布局
  • 从零开始成为白帽黑客:Web安全漏洞挖掘实战入门指南
  • 企业人才战略规划
  • Grok Build:从构建工具到工作流语义引擎的范式跃迁
  • 基于51/STM32单片机智能马桶控制系统 物联网无线传输红外感应3321(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 《3分钟速成Codex》全网最简单的安装攻略,从0开始,没GPT账号也能轻松上手
  • Home Assistant Android应用mTLS证书闪退问题排查与修复指南
  • ESP-NOW 低功耗设备的可靠唤醒:一个被忽视的时序问题
  • 基于STM32单片机的万年历 闹钟 时间 智能手表/数字时钟系统 定做23(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • CUDA Toolkit 与驱动版本匹配:从 nvidia-smi 到 PyTorch 安装的 4 步避坑清单
  • 你每天用的 Claude Code,可能在偷偷标记你——阿里全员卸载背后的真相
  • AKShare金融数据接口:一站式解决Python量化投资的数据获取难题
  • 计算机考试-C语言计算static 静态变量—东方仙盟 —东方仙盟
  • ERROR: Could not install packages due to an OSError: [Errno 28] No space left on device