LSTM多输入建模报错及输入输出、批次大小问题咨询
关于Keras多输入LSTM模型的问题解答
嘿,我来帮你一步步捋清楚这些问题,都是新手用LSTM时容易踩的坑,别担心~
1. 如何修复输入形状不匹配的报错
这个报错的核心原因很直白:你的price输入层定义的形状是(22234,1),意思是每个输入样本是长度为22234的单特征序列,但你传入的trainX是(1,22234,51)——这里不仅特征数是51(和定义的1不匹配),连样本数和时间步长的逻辑都搞反了!
结合你的场景(用过去的价格、情绪预测下一小时价格),正确的调整方式如下:
- 首先明确你的时间步长:比如你想用「过去51个时刻的价格/情绪」来预测下一小时价格,那时间步长就是51,而不是22234。
- 修改模型的输入层定义:把
shape=(dataLength,1)里的dataLength改成你的时间步长(比如51),也就是:price = Input(shape=(51,1),name='price') sentiment = Input(shape=(51,1),name='sentiment') - 同时调整输入数据的形状:把
trainX和trainS整理成**(样本数, 时间步长, 特征数)**的格式。比如原始trainX是(22234,1)(22234个时刻的价格),你可以生成22234-51=22183个样本,每个样本是连续51个时刻的价格,最终trainX形状为(22183,51,1),trainS同理调整成相同的样本数和形状。 - 最后调用模型时,传入正确的时间步长:
lstm = buildModel(51,1)
2. 输入数据重塑步骤是否正确?batch_size应如何确定?
重塑步骤完全错误!
LSTM要求的输入形状是**(样本数, 时间步长, 特征数)**,你之前把样本数设为1、时间步长设成总数据量,相当于把所有数据当成了一个样本,这完全不符合时序预测的逻辑——我们需要的是多个“过去N步→未来1步”的样本对。
正确的重塑逻辑(以时间步长51为例):
- 假设原始price数据是
(总时刻数, 1),比如(22234,1); - 从第1个时刻开始,每次取连续51个时刻作为一个输入样本,对应的标签是第52个时刻的价格;
- 重复这个过程,直到最后一个可取的样本(第22234-51=22183个样本);
- 最终得到的
trainX形状是(22183,51,1),trainS做同样的处理,确保样本数和时间步长一致。
batch_size的确定方法
batch_size是模型每次训练时一次性处理的样本数量,不需要包含在输入数据的形状里,只需要在fit函数里通过参数设置:
- 优先选2的幂数,比如32、64、128,这类数值在GPU上计算效率更高;
- 参考你的硬件内存:如果GPU内存小,就设小一点(比如32),避免内存溢出;如果内存足够,可以设大一点(比如128);
- 结合样本数:比如你有2万多个样本,设batch_size=64的话,一轮训练大概会有340次左右的迭代,训练效率和稳定性都比较合适。
比如在fit里设置:
lstm.fit([trainX,trainS],[trainY], validation_data=([testX,testS],[testY]), epochs=10, batch_size=64)
3. lstm.fit中输出参数[trainX]设置是否正确?
完全不正确!你要做的是预测下一小时的价格,所以标签(输出参数)应该是每个输入样本对应的「下一个时刻的价格」,而不是输入的trainX本身。
举个具体的例子:
- 输入样本1:第1-51小时的价格+情绪
- 对应标签:第52小时的价格
- 输入样本2:第2-52小时的价格+情绪
- 对应标签:第53小时的价格
所以你需要单独整理出trainY数组,形状是(样本数,1),里面是每个样本对应的下一小时价格,然后在fit里传入[trainY],而不是[trainX]。你现在用trainX当标签,相当于让模型去“复制”输入,完全偏离了预测下一小时价格的目标。
内容的提问来源于stack exchange,提问作者Shin Yu Wu
相关产品推荐
相关产品推荐

