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

使用Keras LSTM进行768维特征向量多分类时遇形状匹配错误求助

解决Keras LSTM多分类中的形状不匹配错误

你的错误核心在于损失函数和标签格式不匹配,另外还有一个容易忽略的问题:你的输入是768维连续特征向量,用Embedding层并不合适,这也会影响模型的输入处理。下面一步步帮你修正:

1. 损失函数与标签的匹配问题

你当前使用的是sparse_categorical_crossentropy损失函数,这个函数要求标签是整数形式的单值(比如每个样本的标签是0-9中的一个数字,形状为(样本数, 1)),但从错误信息看,你的y_train是one-hot编码的10维向量(形状(61171, 10)),两者不匹配。

解决方法有两种,二选一即可:

  • 如果你的标签已经是one-hot编码,把损失函数改成categorical_crossentropy
  • 如果想保留sparse_categorical_crossentropy,需要把one-hot编码的标签转换为整数形式(可以用np.argmax(y_train, axis=1)实现)

推荐第一种,因为你的数据已经是one-hot格式,直接改损失函数更方便。

2. 替换Embedding层以适配连续特征

Embedding层是用来处理离散的索引序列(比如自然语言中的词索引),而你的输入是768维的连续特征向量,应该调整输入形状后直接接入LSTM——因为LSTM要求输入是3D张量:(batch_size, timesteps, features)。

你的768维特征可以看作是768个时间步,每个时间步1个特征,所以需要把输入从(样本数,768)转换成(样本数,768,1),再接入LSTM层。

修改后的完整代码

def do_experiment(train_file, validation_file, test_file, experiment_number, optimizer_name):
    def scheduler(epoch):
        if epoch % 4 == 0 and epoch:
            K.set_value(model.optimizer.lr, K.get_value(model.optimizer.lr)*0.9)
            print(K.get_value(model.optimizer.lr))
        return K.get_value(model.optimizer.lr)
    
    change_lr = LearningRateScheduler(scheduler)
    early_stopper = EarlyStopping(min_delta=0.001, patience=15)
    csv_logger = CSVLogger('lstm.csv')
    weights_file="trained_model/" + str(experiment_number) + "-weights.h5"
    model_checkpoint= ModelCheckpoint(weights_file, monitor="val_loss", save_best_only=True, save_weights_only=True, mode='auto')

    x_train, y_train, groundtruth_train= du.loaddata(train_file, experiment_number)
    x_validation, y_validation, groundtruth_validation= du.loaddata(validation_file, experiment_number)
    
    # 调整输入形状,适配LSTM的3D输入要求
    x_train = x_train.reshape(x_train.shape[0], 768, 1)
    x_validation = x_validation.reshape(x_validation.shape[0], 768, 1)
    
    batch_size = 32
    nb_classes = 10
    nb_epoch = 100

    model = Sequential()
    # 去掉Embedding层,直接接入LSTM并指定输入形状
    model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2, input_shape=(768, 1)))
    model.add(Dense(10, activation='softmax'))
    # 替换损失函数,适配one-hot标签格式
    model.compile(loss='categorical_crossentropy', optimizer=optimizer_name, metrics=['accuracy'])
    
    model.fit(x_train, y_train, batch_size=batch_size, epochs=nb_epoch, 
              validation_data=(x_validation, y_validation), shuffle=True, 
              callbacks=[change_lr, early_stopper, csv_logger, model_checkpoint])

关键修改点说明

  • 输入形状调整:通过reshape把2D的特征向量转换成3D张量,满足LSTM对输入维度的要求
  • 移除Embedding层:换成直接指定input_shape=(768,1)的LSTM层,适配连续特征输入
  • 损失函数替换:用categorical_crossentropy替代sparse_categorical_crossentropy,匹配one-hot编码的标签格式

这样修改后,应该就能解决你遇到的形状不匹配错误,顺利完成768维特征向量的多分类任务了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:20:17