如何搭建多输出Sequential模型 解决LSTM训练形状不匹配问题
问题原因
报错的核心是模型输出张量形状和标签形状不匹配:
- 你给两层LSTM都设置了
return_sequences=True,该参数会让LSTM输出每个时间步的隐藏状态,最终传给Dense层的张量形状是(None, 7803, 100),经过Dense层后输出形状为(None, 7803, 3) - 你的标签
ytrain形状是(None, 3),仅对应每个样本的一个全局标签,不是每个时间步的标签,二者维度无法对齐。
LSTM方案修复方法
修改第二层LSTM的return_sequences参数为False,仅输出最后一个时间步的隐藏状态,输出形状就会变为(None, 100),经过Dense层后输出(None, 3),和标签形状匹配。
修改后代码如下:
model=Sequential() # 第一层LSTM保留return_sequences=True,给下一层LSTM输入三维张量 model.add(LSTM(1500,input_shape=(7803,1), return_sequences=True,activation='relu')) # 第二层LSTM关闭return_sequences,输出二维张量 model.add(LSTM(100)) model.add(Dense(3, activation='softmax')) model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) hist=model.fit(xtrain,ytrain,epochs=10,batch_size=64)
注意:你当前的序列长度7803非常高,LSTM处理这么长的序列计算量会极大,建议先做特征降维或者序列采样,避免显存不足、训练速度过慢的问题。另外如果你的标签是整数形式的分类标签,没有做one-hot编码,需要把损失函数换成sparse_categorical_crossentropy。
非LSTM实现多输出方案
不需要LSTM也可以实现3输出的多分类需求,如果你的数据本身没有时序依赖,直接用全连接网络或者一维CNN效率更高,示例如下:
全连接网络方案
把输入的最后一个维度压平,直接接全连接层即可:
model=Sequential() model.add(Flatten(input_shape=(7803,1))) model.add(Dense(2048, activation='relu')) model.add(Dense(256, activation='relu')) model.add(Dense(3, activation='softmax')) model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
一维CNN方案
如果数据有局部相关性,用一维CNN提取特征更高效:
model=Sequential() model.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(7803,1))) model.add(MaxPooling1D(pool_size=2)) model.add(Conv1D(filters=32, kernel_size=3, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dense(3, activation='softmax'))
两种非LSTM方案的输出形状都是(None, 3),可以直接匹配你的标签形状。
内容的提问来源于stack exchange,提问作者10sha25
相关产品推荐
相关产品推荐

