LSTM神经网络输入/输出维度错误

4

我对TensorFlow和LSTM架构还比较新。我在解决如何为我的数据集确定输入和输出(x_train、x_test、y_train、y_test)方面遇到了问题。

我的原始输入形状如下:

  • x_train:(366,4)
  • x_test:(104,4)
  • y_train:(366,)
  • y_test:(104,)

y_train和y_test是一系列股票价格。x_train和x_test是我要用来预测股票价格的四个特征。

# Splitting the training and testing data

train_start_date = '2010-01-08'
train_end_date = '2017-01-06'
test_start_date = '2017-01-13'
test_end_date = '2019-01-04'

train = df.ix[train_start_date : train_end_date]
test = df.ix[test_start_date:test_end_date]


X_test = sentimentScorer(test)
X_train = sentimentScorer(train)

Y_test = test['prices'] 
Y_train = train['prices']

#Conversion in 3D array for LSTM INPUT

X_test = X_test.reshape(1, 104, 4)
X_train = X_train.reshape(1, 366, 4)





model = Sequential()

model.add(LSTM(128, input_shape=(366,4), activation='relu', 
return_sequences=True))
model.add(Dropout(0.2))

model.add(LSTM(128, activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))

model.add(Dense(10, activation='softmax'))

opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)

# Compile model
model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=opt,
    metrics=['accuracy'],
)

model.fit(X_train,
          Y_train,
          epochs=3,
          validation_data=(X_test, Y_test))

这是生成的错误:

> --------------------------------------------------------------------------- ValueError                                Traceback (most recent call
> last) <ipython-input-101-fd4099583529> in <module>
>      65           Y_train,
>      66           epochs=3,
> ---> 67           validation_data=(X_test, Y_test))
> 
> c:\users\talal\appdata\local\programs\python\python36\lib\site-packages\tensorflow\python\keras\engine\training.py
> in fit(self, x, y, batch_size, epochs, verbose, callbacks,
> validation_split, validation_data, shuffle, class_weight,
> sample_weight, initial_epoch, steps_per_epoch, validation_steps,
> **kwargs)    1507         steps_name='steps_per_epoch',    1508         steps=steps_per_epoch,
> -> 1509         validation_split=validation_split)    1510     1511     # Prepare validation data.
> 
> c:\users\talal\appdata\local\programs\python\python36\lib\site-packages\tensorflow\python\keras\engine\training.py
> in _standardize_user_data(self, x, y, sample_weight, class_weight,
> batch_size, check_steps, steps_name, steps, validation_split)
>     991       x, y = next_element
>     992     x, y, sample_weights = self._standardize_weights(x, y, sample_weight,
> --> 993                                                      class_weight, batch_size)
>     994     return x, y, sample_weights
>     995 
> 
> c:\users\talal\appdata\local\programs\python\python36\lib\site-packages\tensorflow\python\keras\engine\training.py
> in _standardize_weights(self, x, y, sample_weight, class_weight,
> batch_size)    1110         feed_input_shapes,    1111        
> check_batch_axis=False,  # Don't enforce the batch size.
> -> 1112         exception_prefix='input')    1113     1114     if y is not None:
> 
> c:\users\talal\appdata\local\programs\python\python36\lib\site-packages\tensorflow\python\keras\engine\training_utils.py
> in standardize_input_data(data, names, shapes, check_batch_axis,
> exception_prefix)
>     314                            ': expected ' + names[i] + ' to have ' +
>     315                            str(len(shape)) + ' dimensions, but got array '
> --> 316                            'with shape ' + str(data_shape))
>     317         if not check_batch_axis:
>     318           data_shape = data_shape[1:]
> 
> ValueError: Error when checking input: expected lstm_18_input to have
> 3 dimensions, but got array with shape (366, 4)

366是一个样本中时间戳的数量吗? - Dulmina
3个回答

5

你的代码基本上是正确的。

你的y_testy_train应该是一个元素的数组或形状为(1,1)的数组,这并不重要。

但你的输入形状是错误的,第一个LSTM应该是:

model.add(LSTM(128, input_shape=(None,4), activation='relu', return_sequences=True))

注意,由于您的测试和训练序列长度不同,因此无法指定 None(Keras接受未指定的第一维)。错误是由长度分别为366和104导致的。如果要在RNN中使用批处理,则应使用 keras.preprocessing.sequence.pad_sequences 进行零填充。

不需要在批处理中指定 input_shape,其余网络应该没问题。

如果您正在执行回归而不是分类(可能是这种情况),则应执行 @Ankish Bansal 撰写的两个最后步骤,例如将损失更改为 mean squared error 并使最后一层输出1个值而不是10个。


嘿,谢谢你的回复。我必须解释一下,我的数据有366个观测值和4个特征(366,4)。这是在我将其重塑为(1, 366, 4)之前。无论如何,我修改了输入形状为(1, 366, 4),结果出现了错误:
ValueError: Shapes must be equal rank, but are 3 and 2
- Talal Zahid
1
请检查我的更新,这应该解决你所有的问题。 - Szymon Maszke
是的,它可以工作,但我仍然困惑于如何将y_test和y_train减少为(1,1)数组。这没有意义,这些是与每个观察值(x_train中的366个和x_test中的104个)对应的股票价格。这是产生的错误:ValueError:输入数组应具有与目标数组相同数量的样本。找到1个输入样本和366个目标样本。 - Talal Zahid
你需要不同的架构来完成这个任务,并且需要了解LSTMs/RNNs以及它们的工作原理。顺便说一下,为了避免混淆,请标记正确的答案作为你的问题的解答。 - Szymon Maszke

3
  1. LSTM期望输入维度为(num_examples, seq_length, input_dims),因此输入存在一个错误。

  2. 您正在预测1个维度的输出,而您的模型输出是10。请尝试:

    model.add(Dense(1, activation='linear'))

  3. 此外,您正在预测价格,这是回归问题。但是,您正在使用分类设置。请尝试:

    model.compile(loss='mse', optimizer='adam', metrics=['mean_squared_error'])


感谢您的回复。就您提到的第一个更改而言,我只有一个样本,一个(366, 4)的数组。4个特征和366个观测值。所以您建议我的input_shape应该是=(1, 366, 4)?但这导致了错误:ValueError: Shapes must be equal rank, but are 3 and 2。 - Talal Zahid

1

您的X_train维度不正确。LSTM仅接受三维输入。您正在说您有4个特征。假设366是一个样本的时间戳数量,您的输入应该是(num_samples, 366, 4)形状。 祝好:-)


我只有一个样本,一个(366, 4)的数组。4个特征和366个观测值。所以你建议我的input_shape应该是=(1, 366, 4)?但是这导致了错误:ValueError: Shapes must be equal rank, but are 3 and 2 - Talal Zahid
1
是的,那应该没问题了 :-)。之前错误在第一个LSTM层,现在已经修复了。现在错误在最后一个密集层,该密集层的输出是3D,但您提供的是1D。请使用Keras flatten层来减少维度。 - Dulmina
1
使用model.summary()命令可以查看每个层的输出形状,然后您就会了解。此外,用户案例中最后一个Dense层的输出形状应该为1,因此可以使用model.add(Dense(1, activation='relu'))来添加最后一层。 - Dulmina
错误似乎发生在第一个LSTM层:“model.add(LSTM(128,input_shape =(1,366,4),activation ='relu', return_sequences = True))” - Talal Zahid
1
@TalalZahid 请查看我的更新答案,昨天指错方向了,抱歉。 - Szymon Maszke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接