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

LSTM分类器对所有观测样本输出相同标签的问题求助

问题分析与解决方案

你的模型出现全样本预测类别1的情况,核心原因是模型未学到有效特征,结合你的数据和模型设置,以下是具体排查和解决步骤:

1. 优先解决训练不足问题

你的模型只训练了5个epochs,对于LSTM这类序列模型来说完全不够,根本达不到收敛状态。

  • 增加epochs到50-100,同时加入早停机制防止过拟合:
    from keras.callbacks import EarlyStopping
    
    early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
    classifier.fit(x_train, y_train, epochs=100, batch_size=100, 
                   validation_split=0.1, callbacks=[early_stop])
    
  • 加入验证集(validation_split或validation_data),实时监控模型在非训练数据上的表现,避免盲目训练。

2. 简化模型结构,降低复杂度

你堆叠了4层LSTM,参数过多,对于1987个训练样本来说,容易出现过拟合或收敛困难:

  • 先尝试简化为1-2层LSTM,比如:
    classifier = Sequential()
    # 第一层LSTM,根据数据复杂度调整units
    classifier.add(LSTM(units=128, input_shape=(30, 14)))
    classifier.add(Dropout(0.3))  # 适当提高Dropout比例,增强泛化
    classifier.add(Dense(3, activation='softmax'))
    
  • 不需要所有LSTM层都返回序列(return_sequences=True),只有当前面还有LSTM层需要接收序列输入时才需要设置,否则会增加不必要的计算。

3. 必须做时间序列数据标准化

LSTM对输入数据的尺度极其敏感,未标准化的数据会导致模型难以收敛:

  • 使用StandardScaler或MinMaxScaler对特征做标准化,注意训练集和测试集必须用训练集的拟合参数:
    from sklearn.preprocessing import StandardScaler
    
    # 假设x_train形状是(1987,30,14),先展平为(1987*30,14)做拟合
    scaler = StandardScaler()
    x_train_scaled = scaler.fit_transform(x_train.reshape(-1, 14)).reshape(1987,30,14)
    x_test_scaled = scaler.transform(x_test.reshape(-1,14)).reshape(500,30,14)
    
  • 用标准化后的数据重新训练模型。

4. 处理类别不平衡问题

测试集中类别1的样本占比最高(37.6%),模型容易偏向预测多数类,可通过类别权重调整:

  • 计算类别权重并传入训练:
    from sklearn.utils.class_weight import compute_class_weight
    import numpy as np
    
    class_weights = compute_class_weight('balanced', classes=np.unique(y_train), y=y_train)
    class_weight_dict = dict(zip(np.unique(y_train), class_weights))
    
    classifier.fit(x_train_scaled, y_train, epochs=100, batch_size=100,
                   validation_split=0.1, callbacks=[early_stop], class_weight=class_weight_dict)
    

5. 调整优化器与学习率

当前学习率0.0001可能过小,导致模型收敛速度太慢:

  • 尝试将学习率调整为0.001,这是Adam优化器的默认值,更适合初始训练:
    classifier.compile(optimizer=Adam(0.001),
                        loss='sparse_categorical_crossentropy',              
                        metrics=['accuracy'])
    
  • 可加入学习率调度器,自动调整学习率:
    from keras.callbacks import ReduceLROnPlateau
    
    lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-6)
    # fit时加入callbacks=[early_stop, lr_scheduler]
    

关于损失函数与激活函数的说明

你的损失函数sparse_categorical_crossentropy和输出层的softmax激活是完全正确的,因为你的标签是整数形式的多分类标签,不需要做one-hot编码,这部分没有问题。

内容的提问来源于stack exchange,提问作者Alex Rogers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:53:11