keras(lstm)-使用返回序列时的必要形状=真

keras(lstm)-使用返回序列时的必要形状=真,keras,lstm,keras-layer,Keras,Lstm,Keras Layer,我正在尝试将LSTM网络与sin函数相匹配。目前,据我了解Keras,我的代码只预测下一个值。根据这个链接:它是一个多对一的模型。然而,我的目标是实现多对多模型。基本上,我希望能够预测给定时间内的10个值。当我尝试使用 return\u sequences=True(参见第行model.add(..)),这应该是解决方案,出现以下错误: ValueError: Error when checking target: expected lstm_8 to have 3 dimensions, bu

我正在尝试将LSTM网络与sin函数相匹配。目前,据我了解Keras,我的代码只预测下一个值。根据这个链接:它是一个多对一的模型。然而,我的目标是实现多对多模型。基本上,我希望能够预测给定时间内的10个值。当我尝试使用
return\u sequences=True
(参见第
行model.add(..)
),这应该是解决方案,出现以下错误:

ValueError: Error when checking target: expected lstm_8 to have 3 dimensions, but got array with shape (689, 1)
不幸的是,我完全不知道为什么会发生这种情况。使用
return\u sequences=True
时,是否有输入形状的一般规则?此外,我到底需要改变什么?谢谢你的帮助

import pandas
import numpy as np
import matplotlib.pylab as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import sklearn

from keras.models import Sequential
from keras.layers import Activation, LSTM
from keras import optimizers
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot

#generate sin function with noise
x = np.arange(0, 100, 0.1)
noise = np.random.uniform(-0.1, 0.1, size=(1000,))
Y = np.sin(x) + noise

# Perform feature scaling
scaler = MinMaxScaler()
Y = scaler.fit_transform(Y.reshape(-1, 1))

# split in train and test
train_size = int(len(Y) * 0.7)
test_size = len(Y) - train_size
train, test = Y[0:train_size,:], Y[train_size:len(Y),:]

def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
         a = dataset[i:(i+look_back), 0]
         dataX.append(a)
         dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)

# reshape into X=t and Y=t+1
look_back = 10
X_train, y_train = create_dataset(train, look_back)
X_test, y_test = create_dataset(test, look_back)

# LSTM network expects the input data in form of [samples, time steps, features]
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
np.set_printoptions(threshold=np.inf)

# compile model
model = Sequential()
model.add(LSTM(1, input_shape=(look_back, 1)))#, return_sequences=True))  <== uncomment this
model.compile(loss='mean_squared_error', optimizer='adam')
SVG(model_to_dot(model).create(prog='dot', format='svg'))

model.fit(X_train, y_train, validation_data=(X_test, y_test), 
batch_size=10, epochs=10, verbose=2)
prediction = model.predict(X_test, batch_size=1, verbose=0)
prediction.reshape(-1) 
#Transform back to original representation
Y = scaler.inverse_transform(Y)
prediction = scaler.inverse_transform(prediction)
plt.plot(np.arange(0,Y.shape[0]), Y)
plt.plot(np.arange(Y.shape[0] - X_test.shape[0] , Y.shape[0]), prediction, 'red')
plt.show()
error = mean_squared_error(y_test, prediction)
print(error)
导入熊猫
将numpy作为np导入
将matplotlib.pylab作为plt导入
从sklearn.preprocessing导入MinMaxScaler
从sklearn.model\u选择导入列车\u测试\u拆分
从sklearn.metrics导入均方误差
导入sklearn
从keras.models导入顺序
从keras.layers导入激活,LSTM
来自keras导入优化器
从IPython.display导入SVG
从keras.utils.vis_utils导入模型到dot
#用噪声生成正弦函数
x=np.arange(0,100,0.1)
噪声=np.随机.均匀(-0.1,0.1,大小=(1000,)
Y=np.sin(x)+噪声
#执行特征缩放
scaler=MinMaxScaler()
Y=缩放器。拟合_变换(Y。重塑(-1,1))
#列车和试验中的分离
列车尺寸=整数(长度(Y)*0.7)
测试尺寸=长度(Y)-列车尺寸
列车,测试=Y[0:列车尺寸,:],Y[列车尺寸:长度(Y),:]
def create_数据集(数据集,回望=1):
dataX,dataY=[],[]
对于范围内的i(len(数据集)-向后看-1):
a=数据集[i:(i+回顾),0]
dataX.append(a)
追加(数据集[i+回望,0])
返回np.array(dataX),np.array(dataY)
#重塑为X=t和Y=t+1
回头看=10
X\u train,y\u train=创建数据集(train,look\u back)
X_测试,y_测试=创建_数据集(测试,回顾)
#LSTM网络期望以[样本、时间步长、特征]的形式输入数据
X_-train=np.重塑(X_-train,(X_-train.shape[0],X_-train.shape[1],1))
X_检验=np.重塑(X_检验,(X_检验.形状[0],X_检验.形状[1],1))
np.set\u打印选项(阈值=np.inf)
#编译模型
模型=顺序()

model.add(LSTM(1,input_shape=(look_back,1)))#,return_sequences=True))问题不在于输入,而在于输出。 错误显示:“检查目标时出错,”,目标=y_训练和y_测试

因为您的lstm返回一个序列(return\u sequences=True),所以输出维度将是:(n\u batch,lookback,1)

您可以使用model.summary()进行验证

您需要更改create_dataset函数,以便形成每个基本事实(回望,1)

您可能想做的事情:
对于列车组中的每个序列x,其y将是下一个程序序列。
例如,假设我们想学习更简单的东西,序列将是前面的数字加上1-->1,2,3,4,5,6,7,8,9,10。 对于loockback=4:

X_train[0] = 1,2,3,4   
y_train[0] will be: 2,3,4,5  
X_train[1] = 2,3,4,5  
y_train[1] will be: 3,4,5,6  
and so on...

问题不在于输入,而在于输出。 错误显示:“检查目标时出错,”,目标=y_训练和y_测试

因为您的lstm返回一个序列(return\u sequences=True),所以输出维度将是:(n\u batch,lookback,1)

您可以使用model.summary()进行验证

您需要更改create_dataset函数,以便形成每个基本事实(回望,1)

您可能想做的事情:
对于列车组中的每个序列x,其y将是下一个程序序列。
例如,假设我们想学习更简单的东西,序列将是前面的数字加上1-->1,2,3,4,5,6,7,8,9,10。 对于loockback=4:

X_train[0] = 1,2,3,4   
y_train[0] will be: 2,3,4,5  
X_train[1] = 2,3,4,5  
y_train[1] will be: 3,4,5,6  
and so on...

我已经按照@DvirSamuel的建议模拟了数据,并为LSTM和FNN提供了代码。请注意,对于LSTM,如果前一层中包含
return\u sequences=True
,则需要添加
network\LSTM.add(layers.Dense(1,activation=None))

## Simulate data.

np.random.seed(20180826)

Z = np.random.randint(0, 10, size = (11000, 1))

for i in range(10):

     Z = np.concatenate((Z, (Z[:, -1].reshape(Z.shape[0], 1) + 1)), axis = 1)

X = Z[:, :-1]

Y = Z[:,  1:]

print(X.shape)

print(Y.shape)

## Training and validation data.

split = 10000

X_train = X[:split, :]
X_valid = X[split:, :]

Y_train = Y[:split, :]
Y_valid = Y[split:, :]

print(X_train.shape)
print(Y_train.shape)
print(X_valid.shape)
print(Y_valid.shape)
LSTM模型的代码:

## LSTM model.

X_lstm_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_lstm_valid = X_valid.reshape(X_valid.shape[0], X_valid.shape[1], 1)

Y_lstm_train = Y_train.reshape(Y_train.shape[0], Y_train.shape[1], 1)
Y_lstm_valid = Y_valid.reshape(Y_valid.shape[0], Y_valid.shape[1], 1)

# Define model.

network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(64, activation = 'relu', input_shape = (X_lstm_train.shape[1], 1),
    return_sequences = True))
network_lstm.add(layers.Dense(1, activation = None))

network_lstm.summary()

# Compile model.

network_lstm.compile(optimizer = 'rmsprop', loss = 'mean_squared_error')

# Fit model.

history_lstm = network_lstm.fit(X_lstm_train, Y_lstm_train, epochs = 5, batch_size = 32, verbose = True,
    validation_data = (X_lstm_valid, Y_lstm_valid))

## Extract loss over epochs and predict.

# Extract loss.

loss_lstm = history_lstm.history['loss']
val_loss_lstm = history_lstm.history['val_loss']
epochs_lstm = range(1, len(loss_lstm) + 1)

plt.plot(epochs_lstm, loss_lstm, 'black', label = 'Training Loss')
plt.plot(epochs_lstm, val_loss_lstm, 'red', label = 'Validation Loss')
plt.title('LSTM: Training and Validation Loss')
plt.legend()

plt.title('First in Sequence')

plt.scatter(Y_train[:, 0], network_lstm.predict(X_lstm_train)[:, 0], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, 0], network_lstm.predict(X_lstm_valid)[:, 0], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.title('Last in Sequence')

plt.scatter(Y_train[:, -1], network_lstm.predict(X_lstm_train)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, -1], network_lstm.predict(X_lstm_valid)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
FNN型号的代码:

## FNN model.

# Define model.

network_fnn = models.Sequential()
network_fnn.add(layers.Dense(64, activation = 'relu', input_shape = (X_train.shape[1],)))
network_fnn.add(Dense(10, activation = None))

network_fnn.summary()

# Compile model.

network_fnn.compile(optimizer = 'rmsprop', loss = 'mean_squared_error')

# Fit model.

history_fnn = network_fnn.fit(X_train, Y_train, epochs = 5, batch_size = 32, verbose = True,
    validation_data = (X_valid, Y_valid))

## Extract loss over epochs.

# Extract loss.

loss_fnn = history_fnn.history['loss']
val_loss_fnn = history_fnn.history['val_loss']
epochs_fnn = range(1, len(loss_fnn) + 1)

plt.plot(epochs_fnn, loss_fnn, 'black', label = 'Training Loss')
plt.plot(epochs_fnn, val_loss_fnn, 'red', label = 'Validation Loss')
plt.title('FNN: Training and Validation Loss')
plt.legend()

plt.title('First in Sequence')

plt.scatter(Y_train[:, 1], network_fnn.predict(X_train)[:, 1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, 1], network_fnn.predict(X_valid)[:, 1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.title('Last in Sequence')

plt.scatter(Y_train[:, -1], network_fnn.predict(X_train)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, -1], network_fnn.predict(X_valid)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

我已经按照@DvirSamuel的建议模拟了数据,并为LSTM和FNN提供了代码。请注意,对于LSTM,如果前一层中包含
return\u sequences=True
,则需要添加
network\LSTM.add(layers.Dense(1,activation=None))

## Simulate data.

np.random.seed(20180826)

Z = np.random.randint(0, 10, size = (11000, 1))

for i in range(10):

     Z = np.concatenate((Z, (Z[:, -1].reshape(Z.shape[0], 1) + 1)), axis = 1)

X = Z[:, :-1]

Y = Z[:,  1:]

print(X.shape)

print(Y.shape)

## Training and validation data.

split = 10000

X_train = X[:split, :]
X_valid = X[split:, :]

Y_train = Y[:split, :]
Y_valid = Y[split:, :]

print(X_train.shape)
print(Y_train.shape)
print(X_valid.shape)
print(Y_valid.shape)
LSTM模型的代码:

## LSTM model.

X_lstm_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_lstm_valid = X_valid.reshape(X_valid.shape[0], X_valid.shape[1], 1)

Y_lstm_train = Y_train.reshape(Y_train.shape[0], Y_train.shape[1], 1)
Y_lstm_valid = Y_valid.reshape(Y_valid.shape[0], Y_valid.shape[1], 1)

# Define model.

network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(64, activation = 'relu', input_shape = (X_lstm_train.shape[1], 1),
    return_sequences = True))
network_lstm.add(layers.Dense(1, activation = None))

network_lstm.summary()

# Compile model.

network_lstm.compile(optimizer = 'rmsprop', loss = 'mean_squared_error')

# Fit model.

history_lstm = network_lstm.fit(X_lstm_train, Y_lstm_train, epochs = 5, batch_size = 32, verbose = True,
    validation_data = (X_lstm_valid, Y_lstm_valid))

## Extract loss over epochs and predict.

# Extract loss.

loss_lstm = history_lstm.history['loss']
val_loss_lstm = history_lstm.history['val_loss']
epochs_lstm = range(1, len(loss_lstm) + 1)

plt.plot(epochs_lstm, loss_lstm, 'black', label = 'Training Loss')
plt.plot(epochs_lstm, val_loss_lstm, 'red', label = 'Validation Loss')
plt.title('LSTM: Training and Validation Loss')
plt.legend()

plt.title('First in Sequence')

plt.scatter(Y_train[:, 0], network_lstm.predict(X_lstm_train)[:, 0], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, 0], network_lstm.predict(X_lstm_valid)[:, 0], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.title('Last in Sequence')

plt.scatter(Y_train[:, -1], network_lstm.predict(X_lstm_train)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, -1], network_lstm.predict(X_lstm_valid)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
FNN型号的代码:

## FNN model.

# Define model.

network_fnn = models.Sequential()
network_fnn.add(layers.Dense(64, activation = 'relu', input_shape = (X_train.shape[1],)))
network_fnn.add(Dense(10, activation = None))

network_fnn.summary()

# Compile model.

network_fnn.compile(optimizer = 'rmsprop', loss = 'mean_squared_error')

# Fit model.

history_fnn = network_fnn.fit(X_train, Y_train, epochs = 5, batch_size = 32, verbose = True,
    validation_data = (X_valid, Y_valid))

## Extract loss over epochs.

# Extract loss.

loss_fnn = history_fnn.history['loss']
val_loss_fnn = history_fnn.history['val_loss']
epochs_fnn = range(1, len(loss_fnn) + 1)

plt.plot(epochs_fnn, loss_fnn, 'black', label = 'Training Loss')
plt.plot(epochs_fnn, val_loss_fnn, 'red', label = 'Validation Loss')
plt.title('FNN: Training and Validation Loss')
plt.legend()

plt.title('First in Sequence')

plt.scatter(Y_train[:, 1], network_fnn.predict(X_train)[:, 1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, 1], network_fnn.predict(X_valid)[:, 1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.title('Last in Sequence')

plt.scatter(Y_train[:, -1], network_fnn.predict(X_train)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()

plt.scatter(Y_valid[:, -1], network_fnn.predict(X_valid)[:, -1], alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
这不应该:

X_-train=np.重塑(X_-train,(X_-train.shape[0],X_-train.shape[1],1))

X_检验=np.重塑(X_检验,(X_检验.形状[0],X_检验.形状[1],1))

像这样:

X_列=np.整形((X_列形状[0],X_列形状[1],1))

X_检验=np.重塑((X_检验形状[0],X_检验形状[1],1))

这会是你的问题吗?(xD后1年)

这不应该:

X_-train=np.重塑(X_-train,(X_-train.shape[0],X_-train.shape[1],1))

X_检验=np.重塑(X_检验,(X_检验.形状[0],X_检验.形状[1],1))

像这样:

X_列=np.整形((X_列形状[0],X_列形状[1],1))

X_检验=np.重塑((X_检验形状[0],X_检验形状[1],1))


这会是你的问题吗?(xD后1年)

谢谢你的回复,但我真的不明白。将行更改为
dataY.append(数据集[i+1:[i+1+look\u back),0])
将生成您提到的输出?这取决于所需的输出。。但是是的。。append(dataset[i+1:(i+1+look_back),0])应该使每个标签都是(loockback,1)向量。这是我的想法,但似乎没有什么区别。至少我也得到了一个值错误<代码>检查目标时出错:预期lstm_1有3个维度,但得到了形状为(164,10)的数组。
您做得很好。。最后一件事是目标形状应该是(无,164,10),指令dataY.append(dataset[i+1:(i+1+look_back),0])将创建带有形状(164,10)的向量,但您希望通知模型