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

Python中如何用Keras Sequential构建多特征多类别输入输出的LSTM?

嘿,我来帮你搞定这个用Keras Sequential构建多特征多类别输入输出LSTM的问题!首先得明确:你的输入是三个分类特征(A/B/C)组成的时序数据,输出也是对应时序的这三个特征对吧?那咱们一步步来:

第一步:先把分类特征处理好(重中之重!)

你的三个特征都是分类类型,直接喂原始数字给LSTM绝对不行——模型会把它们当成连续数值,完全理解错你的类别含义。所以得先做编码:

  • FeatureA(100种取值):用独热编码,转成100维的向量;如果你的原始值是1-100,记得先减1把索引拉到0-99(独热编码默认从0开始)。
  • FeatureB(0/1开关):可以直接用独热编码转成2维向量,或者保留0/1也能行,但统一编码更规范。
  • FeatureC(5种取值):同样转成5维独热向量,注意索引对齐。

给你个代码示例,假设你的时序数据是(样本数, 时间步长, 3)的格式:

import numpy as np
from tensorflow.keras.utils import to_categorical

# 模拟你的时序数据,shape=(2个样本, 3个时间步, 3个特征)
raw_data = np.array([
    [[40,1,5], [58,1,2], [57,1,5]],
    [[40,0,1], [32,1,3], [67,0,2]]
])

# 分别编码每个特征
feature_a = to_categorical(raw_data[..., 0] - 1, num_classes=100)  # 处理100类
feature_b = to_categorical(raw_data[..., 1], num_classes=2)        # 处理2类
feature_c = to_categorical(raw_data[..., 2] - 1, num_classes=5)    # 处理5类

# 把编码后的特征拼起来,得到LSTM的输入数据
X = np.concatenate([feature_a, feature_b, feature_c], axis=-1)
# 现在X的形状是 (2, 3, 107) —— 107=100+2+5
第二步:处理输出目标

因为你要预测这三个特征,所以目标数据也要做和输入一样的编码。这里假设你要做序列预测(即每个时间步都输出下一个时间步的A/B/C),所以把原始数据移位作为目标:

# 目标是每个样本去掉第一个时间步的特征,对应输入的前n-1个时间步
y_a = to_categorical(raw_data[..., 0][:, 1:] - 1, num_classes=100)
y_b = to_categorical(raw_data[..., 1][:, 1:], num_classes=2)
y_c = to_categorical(raw_data[..., 2][:, 1:] - 1, num_classes=5)
第三步:用Sequential构建模型(两种方案)

这里要说明:Sequential是线性层堆叠,天生适合单输出场景,但咱们也能搞定多输出;如果想更灵活,函数式API会更顺手,我都给你列出来:

方案1:纯Sequential实现(拼接输出)

把三个输出的独热向量拼成一个107维的大向量,模型最后输出这个大向量,训练时用分类交叉熵损失:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, TimeDistributed

# 先把三个目标拼起来
y_combined = np.concatenate([y_a, y_b, y_c], axis=-1)

# 构建Sequential模型
model = Sequential()
# 输入层:指定输入形状为(时间步长, 特征数),return_sequences=True表示输出每个时间步的结果
model.add(LSTM(64, return_sequences=True, input_shape=(X.shape[1], X.shape[2])))
model.add(LSTM(32, return_sequences=True))  # 可以加多层LSTM提升能力
# 最后一层输出107维,用softmax激活(多分类必备)
model.add(TimeDistributed(Dense(107, activation='softmax')))

# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 开始训练:输入取前n-1个时间步,对应目标的n-1个时间步
model.fit(X[:, :-1, :], y_combined, epochs=20, batch_size=32)

方案2:函数式API(更推荐,多输出更清晰)

虽然你问的是Sequential,但实际多输出场景下,函数式API能让每个输出头独立设置损失和指标,逻辑更清楚,这里也给你参考:

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, LSTM, Dense, TimeDistributed

# 定义输入层
inputs = Input(shape=(X.shape[1], X.shape[2]))
# LSTM层共享参数
x = LSTM(64, return_sequences=True)(inputs)
x = LSTM(32, return_sequences=True)(x)
# 三个独立的输出头,分别对应三个特征的分类
output_a = TimeDistributed(Dense(100, activation='softmax'), name='output_a')(x)
output_b = TimeDistributed(Dense(2, activation='softmax'), name='output_b')(x)
output_c = TimeDistributed(Dense(5, activation='softmax'), name='output_c')(x)

# 构建模型
model = Model(inputs=inputs, outputs=[output_a, output_b, output_c])

# 编译时给每个输出单独指定损失和指标
model.compile(
    optimizer='adam',
    loss={
        'output_a': 'categorical_crossentropy',
        'output_b': 'categorical_crossentropy',
        'output_c': 'categorical_crossentropy'
    },
    metrics={
        'output_a': 'accuracy',
        'output_b': 'accuracy',
        'output_c': 'accuracy'
    }
)

# 训练时传入三个独立的目标
model.fit(X[:, :-1, :], [y_a, y_b, y_c], epochs=20, batch_size=32)
几个关键提醒
  • 时序形状别搞错:LSTM的输入必须是(样本数, 时间步长, 特征数),千万别喂二维数据!
  • return_sequences的设置:如果是序列预测(每个时间步都输出),一定要设为True;如果只预测最后一个时间步的结果,就设为False。
  • 编码要对齐:输入和目标的编码规则必须完全一致,比如FeatureA的原始值40,输入和目标都要转成索引39的独热向量,不然模型白学。

内容的提问来源于stack exchange,提问作者Dev Ermenegildo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:01:45