python - 尝试从 Keras 运行顺序模型时出现 ValueError
问题描述
我正在尝试用 Keras 构建一个 NARX NN。我仍然不能 100% 确定在 LSTM 神经元中使用参数return_sequence=True但是,在我检查之前,我需要让代码工作。当我尝试运行它时,我收到以下消息:
ValueError: Error when checking input: expected lstm_84_input to have 3 dimensions, but got array with shape (6686, 3)
请参阅下面的代码。运行model.fit命令时出现错误。我的数据数据的形状为 40101 时间步 x 6 个特征(3 个外生输入,3 个系统响应)。
import numpy as np
import pandas as pd
from sklearn.model_selection import TimeSeriesSplit
import tensorflow as tf
from tensorflow.keras import initializers
# --- main
data = pd.read_excel('example.xlsx',usecols=['wave','wind','current','X','Y','RZ'])
data.plot(subplots=True, figsize=[15,10])
x_data = np.array(data.loc[:,['wave','wind','current']])
y_data = np.array(data.loc[:,['X','Y','RZ']])
timeSeriesCrossValidation = TimeSeriesSplit(n_splits=5)
for train, validation in timeSeriesCrossValidation.split(x_data, y_data):
# create model
model = tf.keras.models.Sequential()
# input layer
model.add(tf.keras.layers.LSTM(units=50,
input_shape=(40101,3),
dropout=0.01,
recurrent_dropout=0.2,
kernel_initializer=initializers.RandomNormal(mean=0,stddev=.5),
bias_initializer=initializers.Zeros(),
return_sequences = True))
# 1st hidden layer
model.add(tf.keras.layers.LSTM(units=50,
dropout=0.01,
recurrent_dropout=0.2,
kernel_initializer=initializers.RandomNormal(mean=0,stddev=.5),
bias_initializer=initializers.Zeros(),
return_sequences = True))
# 2nd hidder layer
model.add(tf.keras.layers.LSTM(units=50,
dropout=0.01,
recurrent_dropout=0.2,
kernel_initializer=initializers.RandomNormal(mean=0,stddev=.5),
bias_initializer=initializers.Zeros(),
return_sequences = False))
# output layer
model.add(tf.keras.layers.Dense(3))
model.compile(loss='mse',optimizer='nadam',metrics=['accuracy'])
model.fit(x_data[train], y_data[train],
verbose=2,
batch_size=None,
epochs=10,
validation_data=(x_data[validation], y_data[validation])
#callbacks=early_stop
)
prediction = model.predict(x_data[validation])
y_validation = y_data[validation]
解决方案
LSTM 层需要 3 个维度的输入:
(n_samples, time_steps, features)
您使用以下格式传递数据:
(n_samples, features)
由于您没有创建时间步长的功能,因此最简单的解决方案是将输入更改为 shape:
(40101, 1, 3)
虚假数据:
x_data = np.random.rand(40101, 1, 3)
y_data = np.random.rand(40101, 3)
此外,您不应在input_shape
Keras 层的参数中传递样本数。只需使用这个:
input_shape=(1, 3)
所以这里是更正的代码(带有虚假数据):
import numpy as np
from sklearn.model_selection import TimeSeriesSplit
import tensorflow as tf
from tensorflow.keras import initializers
from tensorflow.keras.layers import *
x_data = np.random.rand(40101, 1, 3)
y_data = np.random.rand(40101, 3)
timeSeriesCrossValidation = TimeSeriesSplit(n_splits=5)
for train, validation in timeSeriesCrossValidation.split(x_data, y_data):
# create model
model = tf.keras.models.Sequential()
# input layer
model.add(LSTM(units=5,
input_shape=(1, 3),
dropout=0.01,
recurrent_dropout=0.2,
kernel_initializer=initializers.RandomNormal(mean=0, stddev=.5),
bias_initializer=initializers.Zeros(),
return_sequences=True))
# 1st hidden layer
model.add(LSTM(units=5,
dropout=0.01,
recurrent_dropout=0.2,
kernel_initializer=initializers.RandomNormal(mean=0, stddev=.5),
bias_initializer=initializers.Zeros(),
return_sequences=True))
# 2nd hidder layer
model.add(LSTM(units=50,
dropout=0.01,
recurrent_dropout=0.2,
kernel_initializer=initializers.RandomNormal(mean=0, stddev=.5),
bias_initializer=initializers.Zeros(),
return_sequences=False))
# output layer
model.add(tf.keras.layers.Dense(3))
model.compile(loss='mse', optimizer='nadam', metrics=['accuracy'])
model.fit(x_data[train], y_data[train],
verbose=2,
batch_size=None,
epochs=1,
validation_data=(x_data[validation], y_data[validation])
# callbacks=early_stop
)
prediction = model.predict(x_data[validation])
y_validation = y_data[validation]
如果你想要一个函数来创建时间步,使用这个:
def multivariate_data(dataset, target, start_index, end_index, history_size,
target_size, step, single_step=False):
data = []
labels = []
start_index = start_index + history_size
if end_index is None:
end_index = len(dataset) - target_size
for i in range(start_index, end_index):
indices = range(i-history_size, i, step)
data.append(dataset[indices])
if single_step:
labels.append(target[i+target_size])
else:
labels.append(target[i:i+target_size])
return np.array(data), np.array(labels)
它会给你正确的形状,例如:
multivariate_data(dataset=np.random.rand(40101, 3),
target=np.random.rand(40101, 3),
0, len(x_data), 5, 0, 1, True)[0].shape
(40096, 5, 3)
您丢失了 5 个数据点,因为一开始您无法回顾过去 5 步。
推荐阅读
- arrays - 将字符串 json 转换为数组 swift
- servlets - 何时使用 servlet 以及何时使用 aem 中的服务来实现任何特定逻辑
- javascript - 如何防止弹出确认对话框暂停计时器脚本
- linux - 如何使用collectd在Linux中将系统指标从一台机器推送到另一台机器?
- java - 在一帧中将对象添加到 Arraylist 但在第二个已打开的帧中无法访问它
- react-native - 如何使函数呈现列表项
- r - 如何在ggplot中编辑图例标签并将图例拆分为多列
- javascript - 使用与 HtmlWebpackPlugin 和 EJS 相同的模板文件?
- python - 如何分隔'di'单词中的前缀?
- excel - Excel在Vlookup上返回空白