在R中使用Keras 2.0构建股票预测LSTM模型时遇维度错误
Let's break down why you're getting that ValueError: Input 0 is incompatible with layer lstm_5: expected ndim=3, found ndim=2 error, and fix your code step by step.
Root Cause
LSTM layers in Keras expect a 3D input tensor with the shape (number_of_samples, timesteps, number_of_features). Your current code has two key issues:
- The dimensions of your
x_trainandx_testarrays are incorrect (you used 51 timesteps instead of 50). - The
input_shapeparameter in your LSTM layer was misconfigured.
Step 1: Fix Input Data Dimensions
Looking at your code:
- You set
seq_length = 50, so each training sample uses 50 days of data to predict the 51st day. That means eachx_trainentry should have 50 timesteps, not 51. - Your original array conversion was hardcoding dimensions and not properly handling the list-to-array conversion. Instead, use
unlist()to flatten the list first, then reshape it correctly.
Replace your array conversion code with this:
# Convert x_train list to 3D array: (samples, timesteps, features) x_train <- array(unlist(x_train), dim = c(length(x_train), seq_length, 1)) # Convert y_train list to 2D array: (samples, 1) y_train <- array(unlist(y_train), dim = c(length(y_train), 1)) # Do the same for test data x_test <- array(unlist(x_test), dim = c(length(x_test), seq_length, 1)) y_test <- array(unlist(y_test), dim = c(length(y_test), 1))
Step 2: Correct the LSTM Layer Setup
The input_shape parameter for an LSTM layer refers to the shape of a single sample (omitting the number of samples, which Keras handles automatically). Since each of your samples has 50 timesteps and 1 feature (closing price), set input_shape = c(seq_length, 1).
Here's the fixed model code:
library(keras) model <- keras_model_sequential() # First LSTM layer: 50 units, return sequences for stacking another LSTM (if needed) model %>% layer_lstm(units = 50, return_sequences = TRUE, input_shape = c(seq_length, 1)) %>% # Second LSTM layer (optional but common for time series) layer_lstm(units = 50) %>% # Output layer: predicts a single value (next day's normalized price) layer_dense(units = 1) # Compile the model with appropriate loss and optimizer model %>% compile( loss = 'mean_squared_error', optimizer = optimizer_adam(learning_rate = 0.001) )
Key Notes
- If you want the model to accept variable-length timesteps (not just 50), you can use
input_shape = c(NULL, 1)instead. Just make sure all samples in a batch have the same timestep length during training. - The
unitsparameter replaces the oldoutput_dimfrom Keras 1.x—this sets the number of hidden units in the LSTM layer (50 is a reasonable starting point for this dataset).
Why Your Previous Input Shapes Failed
input_shape = c(1L): This tells Keras to expect 2D input (samples, 1), which doesn't match the 3D input LSTMs require.input_shape = c(NULL, 1L): While this is valid for variable timesteps, your input data had the wrong timestep count (51 instead of 50), so Keras still threw a dimension mismatch error.
内容的提问来源于stack exchange,提问作者Mislav

