欢迎光临
我们一直在努力

基于CNN-LSTM的路面类型识别:从数据泄露到跨实验泛化的改进之路

一、引言

在路面类型识别任务中,我们使用车辆上安装的四个加速度传感器(左前、右前、左后、右后)采集三轴(x, y, z)振动信号,目标是区分沥青路面和湿滑路面。我们已有两次独立实验数据,保存在两个Excel文件中,每个文件包含多个Sheet(对应不同工况和传感器位置)。初始代码采用了CNN-LSTM模型,但存在严重的数据处理缺陷,可能导致虚假的高准确率。本文将剖析问题,并提出一套科学、可靠的训练与验证策略。


二、原始代码的“致命伤”

2.1 数据泄露根源

原始代码使用train_test_split直接打乱所有滑动窗口进行划分。
问题:同一个Sheet(例如六分力_沥青路面_60kph_第1次_左前)切出的窗口有50%重叠,这些窗口高度相似。若这些窗口一部分在训练集、一部分在测试集,模型相当于“提前看过答案”。
后果:测试准确率虚高(可能>95%),但无法泛化到全新实验。

2.2 忽视传感器空间相关性

四个传感器安装在车辆不同位置,同一时刻的数据具有物理关联(振动传播时间差)。原始代码将每个传感器数据视为独立样本,丢失了“前后左右”的空间相位差信息——而这恰恰是区分刚性与柔性路面的关键特征。

2.3 车速干扰未解耦

两次实验的车速范围可能不同(如第一次40-60kph,第二次20-80kph)。若模型仅依赖振动幅值,可能沦为“车速分类器”,而非路面分类器。


三、三大改进策略

策略一:跨实验泛化验证(最推荐)

  • 做法:用第一次实验的所有数据训练,用第二次实验的所有数据测试(或反过来)。

  • 优势:完全杜绝数据泄露,真实模拟“未来新实验”场景。

  • 适用性:你的两次实验是天然的独立分割。

  • 关注点:若测试准确率骤降(如<70%),说明模型过拟合车速/环境因素,需考虑频域特征或数据增强。

策略二:留一工况法

  • 做法:按Sheet名称分组,例如将*_60kph_*的工况作为测试集,其余工况(40kph、S线等)训练。

  • 目的:检验模型对车速、操纵方式的鲁棒性。

  • 结果解读:若在未见车速上表现差,则模型依赖于幅值,应改用功率谱密度(PSD)或小波包能量等与车速无关的特征。

策略三:全量数据 + 分组K折

  • 做法:合并两次实验,但使用GroupKFold,将文件路径+Sheet名作为组别。确保同一Sheet的所有窗口同属一个折。

  • 适用:数据量较少时,可最大化利用数据,同时保持严格划分。

进阶:多传感器融合(强烈建议)

将四个传感器的12个通道(4×3)作为模型的输入特征,即窗口形状为(128, 12)。修改模型input_channels=12。这样CNN能自动提取跨传感器的时空模式,物理意义更明确。


四、代码修改实战(基于策略一)

4.1 定义带分组信息的窗口切分函数

def create_windows_with_groups(data_list, window_size, stride):
X_list, y_list, group_list = [], [], []
for values, label, name in data_list:
n = len(values)
if n < window_size:
continue
starts = range(0, n – window_size + 1, stride)
for start in starts:
X_list.append(values[start:start+window_size])
y_list.append(label)
group_list.append(name) # 使用Sheet名作为组ID
return np.array(X_list), np.array(y_list), np.array(group_list)

4.2 修改主流程的划分逻辑

from sklearn.model_selection import GroupShuffleSplit

# 分别加载两个文件
file1_data = load_and_label_data(Config.FILE1)
file2_data = load_and_label_data(Config.FILE2)

# 分别切分窗口(不混合)
X_train, y_train, groups_train = create_windows_with_groups(file1_data, Config.WINDOW_SIZE, Config.STRIDE)
X_test, y_test, _ = create_windows_with_groups(file2_data, Config.WINDOW_SIZE, Config.STRIDE)

# 从训练集中划分验证集(按组划分,防止同一个Sheet的窗口出现在训练和验证)
gss = GroupShuffleSplit(n_splits=1, test_size=Config.VAL_SIZE/(1-Config.TEST_SIZE), random_state=42)
train_idx, val_idx = next(gss.split(X_train, y_train, groups=groups_train))
X_train_final, y_train_final = X_train[train_idx], y_train[train_idx]
X_val, y_val = X_train[val_idx], y_train[val_idx]

# 注意:此处不再使用原始X_temp等变量

4.3 标准化与训练(其余代码不变)

标准化依然用训练集拟合,变换验证集和测试集,保持一致性。

4.4 多传感器融合(额外可选)

若想融合12通道,只需在加载数据时,将同一时刻四个传感器的x,y,z拼接成12维向量,然后切分窗口。这需要修改load_and_label_data或额外写一个merge_sensors_data函数,将四个传感器的相同Sheet合并对齐(根据时间戳匹配)。

五、训练与评估的关键观察指标

  • 混淆矩阵:重点关注湿滑路面(正例)的召回率。若召回率低,说明模型对湿滑信号敏感度不足。

  • 按Sheet统计预测概率:将测试集中每个Sheet的所有窗口预测概率取平均,观察其一致性。若某个Sheet的窗口预测概率在0.4~0.6之间波动,说明模型对该工况置信度低,可能需增加该类样本。

  • AUC值:优于准确率,尤其类别不均衡时。

六、结论

  • 切勿混洗窗口划分数据集——必须按独立实验或工况分组。

  • 优先采用跨实验验证,这是最接近真实部署的评估方式。

  • 传感器融合是提升泛化能力的捷径,利用多通道时空信息。

  • 若车速影响显著,引入频域特征(FFT、小波包)或速度归一化。

  • 通过以上改进,你将获得真正可信的路面识别模型。代码框架本身质量很高,只需调整数据处理和划分策略,即可发挥CNN-LSTM的强大能力。

    赞(0)
    未经允许不得转载:171主机测评 » 基于CNN-LSTM的路面类型识别:从数据泄露到跨实验泛化的改进之路
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址