You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为RNN/LSTM模型重塑数据集?二进制分类维度错误求助

解决LSTM输入维度不匹配的问题

这个错误的核心原因是LSTM层要求输入是3维数组,形状为 (样本数, 时间步长, 特征数),但你当前的x_train是2维数组(1415684, 6)——你把每个时间步的数据都当成了独立样本,而没有按患者分组形成完整的时间序列样本。

针对你的患者时序数据集,我们需要先按患者编号分组,把每个患者的所有时间步数据打包成一个序列样本,再调整成LSTM需要的3维格式。下面是具体的修改方案:

步骤1:用Pandas加载并分组数据(更方便处理时序分组)

Pandas的分组功能可以轻松按患者ID聚合时间序列,替代原来的np.loadtxt:

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, LSTM
from keras.preprocessing import sequence

# 固定随机种子
np.random.seed(7)

# 加载训练/测试数据,指定列名方便后续操作
train_df = pd.read_csv("featwithsignalsTRAIN.txt", header=None, 
                       names=["patient_id", "time", "X", "Y", "Z", "kurtosis", "skewness", "angle", "label"])
test_df = pd.read_csv("featwithsignalsTEST.txt", header=None, 
                      names=["patient_id", "time", "X", "Y", "Z", "kurtosis", "skewness", "angle", "label"])

步骤2:按患者ID生成时序样本

每个患者的所有时间步数据构成一个序列样本,标签取该患者的唯一标签(假设每个患者对应一个分类结果):

# 处理训练集
train_groups = train_df.groupby("patient_id")
x_train = []
y_train = []

for _, patient_data in train_groups:
    # 提取你需要的6个特征列
    features = patient_data[["X", "Y", "Z", "kurtosis", "skewness", "angle"]].values
    x_train.append(features)
    # 每个患者的标签唯一,取第一个即可
    y_train.append(patient_data["label"].iloc[0])

# 处理测试集(和训练集逻辑一致)
test_groups = test_df.groupby("patient_id")
x_test = []
y_test = []

for _, patient_data in test_groups:
    features = patient_data[["X", "Y", "Z", "kurtosis", "skewness", "angle"]].values
    x_test.append(features)
    y_test.append(patient_data["label"].iloc[0])

步骤3:统一序列长度(关键!)

不同患者的时间步数量可能不同,LSTM要求所有样本的时间步长度一致,我们用pad_sequences补零(或截断)到最大时间步长:

# 找出训练集中最长的序列长度
max_time_steps = max([seq.shape[0] for seq in x_train])

# 统一训练/测试集的序列长度
x_train = sequence.pad_sequences(x_train, maxlen=max_time_steps, dtype="float32")
x_test = sequence.pad_sequences(x_test, maxlen=max_time_steps, dtype="float32")

# 把标签转成numpy数组
y_train = np.array(y_train)
y_test = np.array(y_test)

步骤4:修改模型适配3维输入

调整LSTM层的输入参数,同时修正输出层(二进制分类只需要1个神经元+Sigmoid激活):

model = Sequential()
# 输入形状为(时间步长, 特征数),对应我们处理后的3维数据
model.add(LSTM(20, dropout=0.2, input_shape=(max_time_steps, 6)))
# 二进制分类输出层:1个神经元+Sigmoid激活
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# 查看模型结构确认输入输出
model.summary()

# 开始训练
model.fit(x_train, y_train, epochs=2, validation_data=(x_test, y_test))

关键说明

  • 为什么原来的代码报错?因为你把140多万个时间步当成了140多万个样本,但LSTM需要的是每个患者是一个样本,每个样本包含该患者的所有时间步数据,所以维度从2D变成了3D。
  • 如果你的数据集里每个患者的时间步数量完全一致,可以跳过pad_sequences步骤,直接把分组后的列表转成numpy数组即可。
  • 输出层用Dense(1, activation='sigmoid')是二进制分类的标准配置,原来的Dense(4)不符合任务需求。

内容的提问来源于stack exchange,提问作者Hadeer El-Zayat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:22:10