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 中的维度问题 - 重塑不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Keras RNN输入维度问题

Recurrentshop 和 Keras:多维 RNN 导致维度不匹配错误

使用 Keras、Tensorflow 进行具有多个时间序列维度的 RNN 时间序列预测

在 Keras 中使用 GRU 的 RNN

将 gridsearchCV 与 Keras RNN-LSTM 一起使用时出现尺寸错误

使用Keras与LSTM和RNN进行斗争