Keras RNN 中的维度问题 - 重塑不起作用?
Posted
技术标签:
【中文标题】Keras RNN 中的维度问题 - 重塑不起作用?【英文标题】:Problem with dimensionality in Keras RNN - reshape isn't working? 【发布时间】:2021-12-16 03:38:10 【问题描述】:让我们考虑一下我要在其上执行 RNN 的随机数据集:
import random
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN
from keras.optimizers import SGD
import numpy as np
df_train = random.sample(range(1, 100), 50)
我想应用滞后等于 1 的 RNN。我将使用我自己的函数:
def create_dataset(dataset, lags):
dataX, dataY = [], []
for i in range(lags):
subdata = dataset[i:len(dataset) - lags + i]
dataX.append(subdata)
dataY.append(dataset[lags:len(dataset)])
return np.array(dataX), np.array(dataY)
根据滞后数缩小数据框。它输出两个 numpy 数组 - 第一个是自变量,第二个是因变量。
x_train, y_train = create_dataset(df_train, lags = 1)
但是现在当我尝试运行该函数时:
model = Sequential()
model.add(SimpleRNN(1, input_shape=(1, 1)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer=SGD(lr = 0.1))
history = model.fit(x_train, y_train, epochs=1000, batch_size=50, validation_split=0.2)
我得到错误:
ValueError: Error when checking input: expected simple_rnn_18_input to have 3 dimensions, but got array with shape (1, 49)
我已经阅读了它,解决方案就是应用重塑:
x_train = np.reshape(x_train, (x_train.shape[0], 1, x_train.shape[1]))
但是当我应用它时,我得到了错误:
ValueError: Error when checking input: expected simple_rnn_19_input to have shape (1, 1) but got array with shape (1, 49)
我不确定错误在哪里。你能告诉我我做错了什么吗?
【问题讨论】:
【参考方案1】:您所称的lags
在文献中被称为look back
。这种技术允许为 RNN 提供更多上下文数据并学习中/长期依赖关系。
错误是告诉您正在使用数据集(形状:1x49
)输入图层(形状:1x1
)
错误背后有两个原因:
第一个是由于您的 create_dataset
正在构建一堆 1x(50 - lags) = 1x49
向量,这与您想要的 1x(lags) = 1x1
相反。
特别是这条线是负责任的:
subdata = dataset[i:len(dataset) - lags + i]
# with lags = 1 you have just one
# iteration in range(1): i = 0
subdata = dataset[0:50 - 1 + 0]
subdata = dataset[0:49] # which is a 1x49 vector
# In order to create the right vector
# you need to change your function:
def create_dataset(dataset, lags = 1):
dataX, dataY = [], []
# iterate to a max of (50 - lags - 1) times
# because we need "lags" element in each vector
for i in range(len(dataset) - lags - 1):
# get "lags" elements from the dataset
subdata = dataset[i:i + lags]
dataX.append(subdata)
# get only the last label representing
# the current element iteration
dataY.append(dataset[i + lags])
return np.array(dataX), np.array(dataY)
如果您在 RNN 中使用 look back
,您还需要增加输入维度,因为您还要查看先例样本。
网络确实在寻找比 1 个样本更多的数据,因为它需要“回顾”更多样本以了解中/长期依赖关系。
这比实际更具概念性,在您的代码中很好,因为lags = 1
:
model.add(SimpleRNN(1, input_shape=(1, 1)))
# you should use lags in the input shape
model.add(SimpleRNN(1, input_shape=(1, LAGS)))
【讨论】:
以上是关于Keras RNN 中的维度问题 - 重塑不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
Recurrentshop 和 Keras:多维 RNN 导致维度不匹配错误
使用 Keras、Tensorflow 进行具有多个时间序列维度的 RNN 时间序列预测