简体   繁体   English

Tensorflow keras 时间序列预测,其中 X 和 y 具有不同的形状

[英]Tensorflow keras timeseries prediction with X and y having different shapes

I am trying to do time series prediction with tensorflow and keras with X and y having different dimensions:我正在尝试使用 tensorflow 和 keras 进行时间序列预测,其中Xy具有不同的维度:

X.shape = (5000, 12)
y.shape = (5000, 3, 12)

When I do the following当我执行以下操作时

n_input = 7
generator = TimeseriesGenerator(X, y, length=n_input, batch_size=1)

for i in range(5):
    x_, y_ = generator[i]
    print(x_.shape)
    print(y_.shape)

I get as desired the output我得到了 output

(1, 7, 12)
(1, 3, 12)
(1, 7, 12)
(1, 3, 12)
...

This is because my data is meteorological, I have 5000 days, for training in the array X I use a sliding window of 7 days, with each day containing 12 features (air pressure, temperature, humidity ao).这是因为我的数据是气象数据,我有 5000 天,对于数组X中的训练,我使用 7 天的滑动 window,每天包含 12 个特征(气压、温度、湿度 ao)。 And in the target array y I have sliding windows of 3 days, trying to predict the next 3 days to each window of 7 days.在目标数组y中,我将 windows 滑动 3 天,试图预测接下来的 3 天到每个 window 的 7 天。

But then when I try to fit the model I get an error due to the mismatch in the shape of the X and y arrays:但是当我尝试安装 model 时,由于Xy arrays 的形状不匹配而出现错误:

model = Sequential()
model.add(LSTM(4, input_shape=(None, 12)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
history = model.fit_generator(generator, epochs=3).history

ValueError: A target array with shape (1, 3, 12) was passed for an output of shape (None, 1) while using as loss `mean_squared_error`. This loss expects targets to have the same shape as the output.

So is there a way to adjust the architecture for the mismatch in the dimensions?那么有没有办法针对尺寸不匹配调整架构? Or is there a way to reshape X and y to make them work with this architecture?或者有没有办法重塑Xy以使它们与这种架构一起工作? I tried the late reshaping X into (5000, 7, 12) , but this gave also a dimensionality error.我尝试了后期将X重塑为(5000, 7, 12) ,但这也产生了维度错误。 Tnx Tnx

your generator is correct... it's your network that doesn't work.你的发电机是正确的......这是你的网络不起作用。

you don't handle the dimensionality correctly.你没有正确处理维度。 you are dealing with sequences so you need to impose return_sequences=True in your LSTM cells.你正在处理序列,所以你需要在你的 LSTM 单元中强加return_sequences=True your input has 7 timesteps while your output has 3 timesteps, you have to pass from 7 to 3 (you can do it with pooling and so on).您的输入有 7 个时间步,而您的 output 有 3 个时间步,您必须从 7 传递到 3(您可以通过池化等方式进行)。

below a dummy example.下面是一个虚拟示例。 I don't use a pooling operation but simply select a part of the sequence in order to get an output of 3 timesteps我不使用池操作,而只是使用 select 作为序列的一部分,以获得 3 个时间步长的 output

X = np.random.uniform(0,1, (5000, 12))
y = np.random.uniform(0,1, (5000, 3, 12))

n_input = 7
generator = tf.keras.preprocessing.sequence.TimeseriesGenerator(X, y, length=n_input, batch_size=32)

model = Sequential()
model.add(LSTM(4, return_sequences=True, input_shape=(n_input, 12)))
model.add(Lambda(lambda x: x[:,-3:,:]))
model.add(Dense(12))
model.compile(loss='mean_squared_error', optimizer='adam')

model.summary()

model.fit(generator, epochs=2)

here an example with pooling operation这里是一个池化操作的例子

model = Sequential()
model.add(LSTM(4, return_sequences=True, input_shape=(n_input, 12)))
model.add(MaxPool1D(2)) # also AvgPool1D is ok
model.add(Dense(12))
model.compile(loss='mean_squared_error', optimizer='adam')

model.summary()
model.fit(generator, epochs=2)

here an example with return_sequences=False and repeat vector这里有一个 return_sequences=False 和重复向量的例子

model = Sequential()
model.add(LSTM(4, return_sequences=False, input_shape=(n_input, 12)))
model.add(RepeatVector(3))
model.add(Dense(12))
model.compile(loss='mean_squared_error', optimizer='adam')

model.summary()
model.fit(generator, epochs=2)

Your final (fully connected) layer's shape is (None, 1) and your output's shape is (None, 3, 12).您的最终(完全连接)层的形状是 (None, 1),输出的形状是 (None, 3, 12)。 Output shapes of data and the network have to match. Output 形状的数据和网络必须匹配。

I would use the Functional API and create 3 separate Dense layers and concatenate them.我将使用功能 API并创建 3 个单独的密集层并将它们连接起来。 Like this:像这样:

inp = tf.keras.Input(shape=(7, 12))
x = tf.keras.layers.LSTM(4)(inp)

y1 = tf.keras.layers.Dense(12)(x)
y2 = tf.keras.layers.Dense(12)(x)
y3 = tf.keras.layers.Dense(12)(x)

y1 = tf.keras.backend.expand_dims(y1, axis=1)
y2 = tf.keras.backend.expand_dims(y2, axis=1)
y3 = tf.keras.backend.expand_dims(y3, axis=1)

output = tf.keras.layers.Concatenate(axis=1)([y1, y2, y3])

mdl = tf.keras.Model(inp, output)
mdl.summary()

Returned: Model Summary返回: Model 总结

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM