i got this error:

  File "C:\Users\User\Desktop\new datasets3\gridsearchtryupdate.py", line 76, in create_model
    model.add(Bidirectional(LSTM(lstm_units2, activation='elu', kernel_initializer=initializer, recurrent_initializer=initializer2, dropout=dropout_rate, recurrent_dropout=dropout_rate)))
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\tensorflow\python\trackable\base.py", line 205, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\engine\input_spec.py", line 235, in assert_input_compatibility
    raise ValueError(
ValueError: Input 0 of layer "bidirectional_1" is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: (None, 10)


from this code:

import os
import numpy as np
import pandas as pd
import tensorflow as tf
import random as rn
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
from keras.models import Sequential
from keras.layers import Dense, Conv1D, Bidirectional, LSTM, TimeDistributed, Dropout, Flatten, ELU, MaxPool1D
from keras.activations import elu as ELU
from keras import backend as K
import itertools

# Set the random seed for reproducibility
seed_value = 42
os.environ['PYTHONHASHSEED'] = str(seed_value)
np.random.seed(seed_value)
rn.seed(seed_value)
tf.random.set_seed(seed_value)
K.clear_session()

def parse_date(date_string):
    return pd.to_datetime(date_string, format='%d/%m/%Y')

# Load the dataset
df = pd.read_csv('daily2023.csv', parse_dates=['Date'], date_parser=parse_date, index_col='Date')
passenger_count = df['passenger count'].values

def split_sequence(sequence, n_steps):
    X, y = list(), list()
    for i in range(len(sequence)):
        end_ix = i + n_steps
        if end_ix > len(sequence) - 1:
            break
        seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
        X.append(seq_x)
        y.append(seq_y)
    return np.array(X), np.array(y)

# Assuming passenger_count is a NumPy array containing the feature to be scaled
train_size = int(len(passenger_count) * 0.6)  # 60% of the data
val_size = int(len(passenger_count) * 0.2)  # 20% of the data
test_size = len(passenger_count) - train_size - val_size  # Remaining data

# Split the data into train, validation, and test sets
train_data = passenger_count[0:train_size]
val_data = passenger_count[train_size:train_size+val_size]
test_data = passenger_count[train_size+val_size:]

# Create an instance of MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))

# Fit the scaler on the training data only
scaler.fit(train_data.reshape(-1, 1))

# Transform the training data
scaled_train_data = scaler.transform(train_data.reshape(-1, 1))

# Transform the validation and test data using the same scaler
scaled_val_data = scaler.transform(val_data.reshape(-1, 1))
scaled_test_data = scaler.transform(test_data.reshape(-1, 1))

# Now scaled_train_data, scaled_val_data, and scaled_test_data are properly scaled

initializer = tf.keras.initializers.GlorotNormal(seed=seed_value)
initializer2 = tf.keras.initializers.Orthogonal(seed=seed_value)

def create_model(filters, kernel_size, lstm_units,lstm_units2, dropout_rate, n_steps, n_features):
    model = Sequential()
    model.add(TimeDistributed(Conv1D(filters=filters, kernel_size=kernel_size, activation='relu', kernel_initializer=initializer), input_shape=(None, n_steps, n_features)))
    model.add(TimeDistributed(Dropout(dropout_rate)))
    model.add(TimeDistributed(Flatten()))
    # LSTM Layer with Dropout
    model.add(Bidirectional(LSTM(lstm_units, activation='elu', kernel_initializer=initializer, recurrent_initializer=initializer2, dropout=dropout_rate, recurrent_dropout=dropout_rate), input_shape=(n_seq, n_steps, n_features)))
    # Optionally adding another LSTM layer
    model.add(Bidirectional(LSTM(lstm_units2, activation='elu', kernel_initializer=initializer, recurrent_initializer=initializer2, dropout=dropout_rate, recurrent_dropout=dropout_rate)))
    model.add(Dense(1, kernel_initializer=initializer))
    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='mse')
    return model

def evaluate_model(model, X_train, y_train, X_val, y_val, X_test, y_test, scaler):
    y_train_pred = scaler.inverse_transform(model.predict(X_train))
    y_val_pred = scaler.inverse_transform(model.predict(X_val))
    y_test_pred = scaler.inverse_transform(model.predict(X_test))
    y_train_true = scaler.inverse_transform(y_train.reshape(-1, 1))
    y_val_true = scaler.inverse_transform(y_val.reshape(-1, 1))
    y_test_true = scaler.inverse_transform(y_test.reshape(-1, 1))

    # Calculate metrics for the training set
    mse_train = mean_squared_error(y_train_true, y_train_pred)
    mae_train = mean_absolute_error(y_train_true, y_train_pred)
    rmse_train = np.sqrt(mse_train)
    mape_train = np.mean(np.abs((y_train_true - y_train_pred) / y_train_true)) * 100

    # Calculate metrics for the validation set
    mse_val = mean_squared_error(y_val_true, y_val_pred)
    mae_val = mean_absolute_error(y_val_true, y_val_pred)
    rmse_val = np.sqrt(mse_val)
    mape_val = np.mean(np.abs((y_val_true - y_val_pred) / y_val_true)) * 100

    # Calculate metrics for the test set
    mse_test = mean_squared_error(y_test_true, y_test_pred)
    mae_test = mean_absolute_error(y_test_true, y_test_pred)
    rmse_test = np.sqrt(mse_test)
    mape_test = np.mean(np.abs((y_test_true - y_test_pred) / y_test_true)) * 100

    return mse_train, mae_train, rmse_train, mape_train, mse_val, mae_val, rmse_val, mape_val, mse_test, mae_test, rmse_test, mape_test

filters_options = [2, 4, 8, 16, 20]
kernel_size_options = [3, 5, 7, 9]
lstm_units_options = [5, 10, 20, 25, 30, 40, 50, 60]
lstm_units2_options = [5, 10, 20, 25, 30, 40, 50, 60]
dropout_rate_options = [0.1, 0.2, 0.3]
n_steps_options = [20, 25, 30, 35, 40, 45, 50, 55, 60]
epochs = 100

results = []

for n_steps in n_steps_options:
    X_train, y_train = split_sequence(scaled_train_data, n_steps)
    X_val, y_val = split_sequence(scaled_val_data, n_steps)
    X_test, y_test = split_sequence(scaled_test_data, n_steps)

    n_features = 1
    n_seq = 1
    X_train = X_train.reshape(X_train.shape[0], n_seq, n_steps, n_features)
    X_val = X_val.reshape(X_val.shape[0], n_seq, n_steps, n_features)
    X_test = X_test.reshape(X_test.shape[0], n_seq, n_steps, n_features)

    for filters, kernel_size, lstm_units,lstm_units2, dropout_rate in itertools.product(filters_options, kernel_size_options, lstm_units_options,lstm_units2_options, dropout_rate_options):
        model = create_model(filters=filters, kernel_size=kernel_size, lstm_units=lstm_units, lstm_units2=lstm_units2, dropout_rate=dropout_rate, n_steps=n_steps, n_features=n_features)
        model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=epochs, verbose=1)
        mse_train, mae_train, rmse_train, mape_train, mse_val, mae_val, rmse_val, mape_val, mse_test, mae_test, rmse_test, mape_test = evaluate_model(model, X_train, y_train, X_val, y_val, X_test, y_test, scaler)
        results.append({
            'n_steps': n_steps,
            'filters': filters,
            'kernel_size': kernel_size,
            'lstm_units': lstm_units,
            'lstm_units2': lstm_units2,
            'dropout_rate': dropout_rate,
            'mse_train': mse_train,
            'mae_train': mae_train,
            'rmse_train': rmse_train,
            'mape_train': mape_train,
            'mse_val': mse_val,
            'mae_val': mae_val,
            'rmse_val': rmse_val,
            'mape_val': mape_val,
            'mse_test': mse_test,
            'mae_test': mae_test,
            'rmse_test': rmse_test,
            'mape_test': mape_test,
        })

results_df = pd.DataFrame(results)
results_df.to_csv('20-60steps_BDLSTM_100_ELU_ADDLSTM.csv', index=False)

best_results = results_df.loc[results_df.groupby('n_steps')['mape_test'].idxmin()]

print("Best parameters for each n_steps:")
print(best_results)