我试图建立一个非常简单的LSTM结构,使用填充和屏蔽来学习如何训练时间序列数据。假设我每个月有两个人的血值信息。对于第一个人,我只有七个月的数据,而对于下一个人,我只有四个月的数据。最后,我选择-100作为填充值来完成序列。
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import LSTM
from tensorflow.keras.utils import Sequence
from keras.layers import LSTM, Dense, Masking
#each column represent a different blood value.
xPad = np.array([[
[ 0.4654949, 0.06225133],
[ -0.48630088, 0.97063685],
[ -0.23714237, 1.07598604],
[ -0.94519772, 0.76515959],
[ -0.81456729, 1.05963647],
[ 0.60236851, 1.26799774],
[ 1.89095161, 1.02534057]],
[[ -1.76505643, 0.61171791],
[ 2.00335928, -0.02941931],
[ -1.58293956, -0.02671103],
[ 1.57166957, -0.39450184],
[-100, -100 ],
[-100, -100 ],
[-100, -100 ]]])
假设我想估计这个人是低体重、中等体重还是高体重。这就是为什么我也有每个月每个人的信息,如下所示。对于第二个人,我用零向量填充缺失的月份。例如,[0,0,1]
表示该特定月份的人是高体重的。
y = np.array([
[[0,0,1],[0,0,1],[0,0,1],[0,0,1],[0,1,0],[0,1,0],[0,1,0]],
[[1,0,0],[1,0,0],[1,0,0],[0,1,0],[0,0,0],[0,0,0],[0,0,0]]
])
然后,我使用tensorflow创建我的网络。
special_value= -100
seq_len = 7
dim = 2
model = Sequential()
model.add(Masking(mask_value=special_value, input_shape=(seq_len, dim)))
model.add(LSTM(5))
model.add(Dense(3))
model.compile(loss='binary_crossentropy', optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001))
model.fit(xPad, y, epochs=10, batch_size=2)
我想知道我在这里做错了什么。我很感激你的帮助。
Dimensions must be equal, but are 7 and 2 for '{{node binary_crossentropy/mul}} = Mul[T=DT_FLOAT](binary_crossentropy/Cast, binary_crossentropy/Log)' with input shapes: [2,7,3], [2,3]
简单来说,你可以通过修改
来解决这个问题。model.add(LSTM(5))
model.add(LSTM(5, return_sequences=True))
下面是答案的扩展。
得到形状为[2, 7, 2]
的xPad
和形状为[2, 7, 3]
的y
。所以你似乎试图预测y
的每一个时间步xPad
。然后错误提示是
它有一个LSTM,只输出最后一个但是您的y
用于所有的时间步长(这是不兼容的)。return_sequences=True
输出所有时间步长的状态,这使得您的y
与模型的输出兼容。
这个答案显示了return_sequences=True
的作用。