路面类型识别 — CNN-LSTM 完整流程:基于车辆振动数据的端到端深度学习

项目概述

本项目基于六分力传感器采集的车辆振动数据(x/y/z 三轴加速度),使用 CNN-LSTM 深度学习框架实现路面类型识别,能够准确区分沥青路面湿滑路面

核心特点

  • CNN-LSTM 端到端学习:直接从原始振动信号中自动提取特征,无需手工设计特征
  • 严格跨实验验证:用第1次实验数据训练 → 在第2次实验数据上测试(及反向),杜绝数据泄露
  • 阈值自动调优:自动扫描最佳分类阈值,最大化 F1 分数
  • 全面可视化:训练曲线、混淆矩阵、ROC 曲线、逐场景准确率热图

数据来源

实验 文件 说明
第1次试验 合并_所有传感器_第一次实验.xlsx 包含 沥青路面(加速/匀速) + 湿滑路面
第2次试验 合并_所有传感器_第二次实验.xlsx 同上,独立采集
  • 4个传感器位置:左前、右前、左后、右后
  • 采样频率:1600 Hz
  • 三轴加速度:x, y, z

模型架构

Input (T, 3)  →  Conv1D×3  →  LSTM(64)  →  Dense → 二分类
  T=256 时间步   提取局部特征   时序建模      分类头

目录结构

路面识别_CNN_LSTM_完整流程/
├── config.py              # 配置文件(所有参数集中管理)
├── data_loader.py         # 数据加载、预处理、增强
├── models.py              # CNN-LSTM 模型定义
├── trainer.py             # 训练器(含 Focal Loss)
├── evaluation.py          # 评估指标与可视化
├── run_pipeline.py        # ★ 主流程入口
├── requirements.txt       # Python 依赖
├── README.md              # 本文件
└── 实验结果/               # 自动生成
    ├── models/            # 训练好的模型文件 (.pth)
    ├── plots/             # 可视化图表
    └── cross_experiment_metrics.csv  # 评估指标 CSV

运行方法

1. 安装依赖

pip install torch numpy pandas matplotlib seaborn scikit-learn openpyxl joblib

2. 准备数据

确保父目录 合并后的数据/ 中有以下两个文件:

  • 合并_所有传感器_第一次实验.xlsx
  • 合并_所有传感器_第二次实验.xlsx

3. 运行主程序

cd 路面识别_CNN_LSTM_完整流程
python run_pipeline.py

4. 查看结果

运行完成后,在 实验结果/ 目录下查看:

  • plots/ — 训练曲线、混淆矩阵、ROC 曲线、场景热图、对比图
  • models/ — 保存的模型权重文件
  • cross_experiment_metrics.csv — 指标汇总

配置参数说明

编辑 config.py 可调整以下参数:

参数 默认值 说明
WINDOW_SIZE 256 滑动窗口大小(时间步数)
STRIDE 128 滑动步长(50%重叠)
BATCH_SIZE 128 训练批次大小
EPOCHS 100 最大训练轮数
PATIENCE 15 EarlyStopping 容忍轮数
LEARNING_RATE 1e-3 初始学习率
TUNE_THRESHOLD True 是否自动调优阈值
USE_FOCAL_LOSS False 是否使用 Focal Loss
USE_AUGMENTATION False 是否使用数据增强
POSITION_SPECIFIC False 是否按位置分别建模

实验结果摘要

方向 准确率 F1分数 最佳阈值
Exp1→Exp2 ~94% ~89% 0.8~0.9
Exp2→Exp1 ~97% ~85% 0.8~0.95

关键发现:CNN-LSTM 在严重不平衡场景(Exp2→Exp1,沥青:湿滑 ≈ 10.6:1)下显著优于传统 MLP,证明了其从原始时序信号中自动学习有效特征的能力。

技术亮点

1. 数据预处理流程

# 滑动窗口切分
def sliding_window(data, window_size=256, stride=128):
    """将长序列切分为固定长度的窗口"""
    windows = []
    for i in range(0, len(data) - window_size + 1, stride):
        windows.append(data[i:i+window_size])
    return np.array(windows)

2. CNN-LSTM 模型架构

import torch
import torch.nn as nn

class CNNLSTM(nn.Module):
    def __init__(self, input_dim=3, hidden_dim=64, num_classes=2):
        super(CNNLSTM, self).__init__()
        # CNN 特征提取
        self.conv1 = nn.Conv1d(input_dim, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv1d(32, 64, kernel_size=3, padding=1)
        self.conv3 = nn.Conv1d(64, 128, kernel_size=3, padding=1)
        self.pool = nn.MaxPool1d(2)
        
        # LSTM 时序建模
        self.lstm = nn.LSTM(128, hidden_dim, batch_first=True, bidirectional=True)
        
        # 分类头
        self.fc = nn.Sequential(
            nn.Linear(hidden_dim*2, 64),
            nn.ReLU(),
            nn.Dropout(0.3),
            nn.Linear(64, num_classes)
        )
    
    def forward(self, x):
        # x: (batch, seq_len, input_dim)
        x = x.transpose(1, 2)  # -> (batch, input_dim, seq_len)
        
        # CNN 处理
        x = self.pool(torch.relu(self.conv1(x)))
        x = self.pool(torch.relu(self.conv2(x)))
        x = self.pool(torch.relu(self.conv3(x)))
        
        # 转回时序格式
        x = x.transpose(1, 2)  # -> (batch, new_seq_len, 128)
        
        # LSTM 处理
        lstm_out, _ = self.lstm(x)
        
        # 取最后一个时间步
        out = lstm_out[:, -1, :]
        
        # 分类
        return self.fc(out)

3. 跨实验验证策略

# 严格的数据划分策略
def cross_experiment_split(data_exp1, labels_exp1, data_exp2, labels_exp2):
    """训练集和测试集来自不同实验,确保无数据泄露"""
    # 方案1:Exp1训练,Exp2测试
    X_train, y_train = data_exp1, labels_exp1
    X_test, y_test = data_exp2, labels_exp2
    
    # 方案2:Exp2训练,Exp1测试(反向验证)
    # X_train, y_train = data_exp2, labels_exp2
    # X_test, y_test = data_exp1, labels_exp1
    
    return X_train, y_train, X_test, y_test

可视化结果

训练过程监控

项目自动生成以下可视化图表:

  1. 训练曲线:损失和准确率随 epoch 变化
  2. 混淆矩阵:模型在测试集上的分类表现
  3. ROC 曲线:不同阈值下的性能表现
  4. 场景热图:不同驾驶场景下的准确率分布
  5. 模型对比图:CNN-LSTM vs 传统方法

性能对比

原始振动数据

特征提取

方法选择

传统手工特征

CNN-LSTM 自动特征

MLP 分类器

端到端分类

准确率: ~85%

准确率: ~94-97%

应用场景

  1. 智能驾驶系统:实时路面状态感知
  2. 车辆健康监测:路面异常检测
  3. 道路养护管理:路面状况评估
  4. 自动驾驶决策:根据路面类型调整控制策略

总结与展望

本项目展示了 CNN-LSTM 在车辆振动数据分析中的强大能力,主要优势包括:

  • 端到端学习:无需复杂的手工特征工程
  • 时序建模:LSTM 有效捕捉振动信号的时序依赖
  • 强泛化性:跨实验验证证明了模型的鲁棒性
  • 实用性强:完整的工程化实现,开箱即用

未来改进方向

  1. 增加更多路面类型(水泥路、砂石路等)
  2. 融合多传感器数据(陀螺仪、GPS等)
  3. 在线学习与自适应更新
  4. 部署到嵌入式设备实时推理

资源下载

完整代码已开源,欢迎 Star 和 Fork:

  • GitHub 仓库路面识别-CNN-LSTM
  • 数据集:包含两次实验的完整振动数据
  • 预训练模型:可直接用于推理的模型权重

参考文献

  1. Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press.
  2. Hochreiter, S., & Schmidhuber, J. (1997). Long short-term memory. Neural computation.
  3. LeCun, Y., Bengio, Y., & Hinton, G. (2015). Deep learning. Nature.

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

联系方式:如有问题或建议,欢迎在评论区留言或通过 GitHub Issues 反馈。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐