Я пытаюсь предсказать временные ряды с помощью модели Трансформера, но результаты представляют собой прямую линию. ⇐ Python
-
Anonymous
Я пытаюсь предсказать временные ряды с помощью модели Трансформера, но результаты представляют собой прямую линию.
Below is the prediction code in my Google Colab environment.
import numpy as np import pandas as pd import matplotlib.pyplot as plt from datetime import timedelta from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Dense, Dropout, LayerNormalization, MultiHeadAttention from tensorflow.keras.optimizers import Adam from tensorflow.keras.losses import MeanSquaredError, MeanAbsoluteError # Load the data data = pd.read_csv('/content/data.csv') data['Timestamp (KST)'] = pd.to_datetime(data['Timestamp (KST)']) data.set_index('Timestamp (KST)', inplace=True) # Load the actual data actual_data = pd.read_csv('/content/actual_data.csv') actual_data['Timestamp (KST)'] = pd.to_datetime(actual_data['Timestamp (KST)']) actual_data.set_index('Timestamp (KST)', inplace=True) # Select specific day for actual values specific_day = '2024-11-02' actual_values = actual_data.loc[specific_day, 'Motion Detected'].values.reshape(-1, 1) # Extract the 'Motion Detected' column for training training_data = data['Motion Detected'].values.reshape(-1, 1) # Normalize the data scaler = MinMaxScaler(feature_range=(0, 1)) training_data_normalized = scaler.fit_transform(training_data) # Function to create sequences for training def create_sequences(data, seq_length): sequences = [] targets = [] for i in range(len(data)-seq_length): seq = data[i:i+seq_length] target = data[i+seq_length:i+seq_length+1] sequences.append(seq) targets.append(target) return np.array(sequences), np.array(targets) # Define Transformer model def build_transformer_model(input_shape): inputs = Input(shape=input_shape) # Multi-head self-attention attention_output = MultiHeadAttention(num_heads=4, key_dim=input_shape[1])(inputs, inputs) # Skip connection and layer normalization attention_output = LayerNormalization(epsilon=1e-6)(inputs + attention_output) # Feed-forward neural network outputs = Dense(64, activation='relu')(attention_output) outputs = Dropout(0.65)(outputs) outputs = Dense(1, activation='linear')(outputs) # Output shape is set to 1 and linear activation function is used # Model model = Model(inputs=inputs, outputs=outputs) return model # Build and compile the Transformer model sequence_length = 24 # Sequence length used during training transformer_model = build_transformer_model(input_shape=(sequence_length, 1)) transformer_model.compile(optimizer=Adam(learning_rate=0.001), loss=MeanSquaredError(), metrics=[MeanAbsoluteError()]) # Generate sequences for training X_transformer, y_transformer = create_sequences(training_data_normalized, sequence_length) X_transformer = X_transformer.reshape((X_transformer.shape[0], sequence_length, 1)) # Train the Transformer model transformer_model.fit(X_transformer, y_transformer, epochs=10, batch_size=72, verbose=1, validation_split=0.2) # Generate predictions for the next 24 hours future_steps = 24 future_predictions_normalized = [] # Use the last sequence from the actual data as the initial input for predictions current_sequence = training_data_normalized[-sequence_length:].reshape(-1) # Flatten the sequence for i in range(future_steps): # Reshape the sequence to match the input shape of the model current_sequence_reshaped = current_sequence[-sequence_length:].reshape((1, sequence_length, 1)) # Make a prediction prediction = transformer_model.predict(current_sequence_reshaped)[0, 0] # Append the prediction to the list of future predictions future_predictions_normalized.append(prediction) # Update the current sequence by adding the prediction current_sequence = np.append(current_sequence, prediction) # Inverse transform the normalized predictions to get the actual values future_predictions = scaler.inverse_transform(np.array(future_predictions_normalized).reshape(-1, 1)) # Generate timestamps for the future predictions (hourly time points for the next day) last_timestamp = data.index[-1] future_timestamps = [last_timestamp + timedelta(hours=i) for i in range(1, future_steps + 1)] # Format x-axis to display time as '00:00:00' formatted_timestamps = [time.strftime('%H:%M:%S') for time in future_timestamps] # Set the figure size plt.figure(figsize=(15, 8)) # Plot the actual values as a line plt.plot(formatted_timestamps, actual_values, label=f'Actual Values ({specific_day})', linestyle='dashed', color='green') # Plot the predicted values as a line plt.plot(formatted_timestamps, future_predictions, label='Predicted Values', linestyle='solid', color='blue') # Scatter plot for actual values for i, txt in enumerate(actual_values): plt.scatter(formatted_timestamps, txt, color='green', marker='o') plt.annotate(f'{int(txt[0])}', (formatted_timestamps, txt[0]), textcoords="offset points", xytext=(0, 10), ha='center') # Scatter plot for predicted values for i, txt in enumerate(future_predictions): plt.scatter(formatted_timestamps, txt, color='blue', marker='o') plt.annotate(f'{int(txt[0])}', (formatted_timestamps, txt[0]), textcoords="offset points", xytext=(0, 10), ha='center') plt.xlabel('Time (KST)') plt.xticks(rotation=45, ha='right') plt.ylabel('Motion Detected') plt.title(f'Hourly Motion Detected Prediction for the Next 24 Hours ({specific_day})') plt.legend() plt.show() Below are the prediction results. Even if I keep modifying it, the prediction result comes out with the same value. What's the problem?
enter image description here
And below is my training data structure. Motion Detected is the number of motion detections and has a value between 0 and 100. enter image description here
Источник: https://stackoverflow.com/questions/780 ... sults-come
Below is the prediction code in my Google Colab environment.
import numpy as np import pandas as pd import matplotlib.pyplot as plt from datetime import timedelta from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Dense, Dropout, LayerNormalization, MultiHeadAttention from tensorflow.keras.optimizers import Adam from tensorflow.keras.losses import MeanSquaredError, MeanAbsoluteError # Load the data data = pd.read_csv('/content/data.csv') data['Timestamp (KST)'] = pd.to_datetime(data['Timestamp (KST)']) data.set_index('Timestamp (KST)', inplace=True) # Load the actual data actual_data = pd.read_csv('/content/actual_data.csv') actual_data['Timestamp (KST)'] = pd.to_datetime(actual_data['Timestamp (KST)']) actual_data.set_index('Timestamp (KST)', inplace=True) # Select specific day for actual values specific_day = '2024-11-02' actual_values = actual_data.loc[specific_day, 'Motion Detected'].values.reshape(-1, 1) # Extract the 'Motion Detected' column for training training_data = data['Motion Detected'].values.reshape(-1, 1) # Normalize the data scaler = MinMaxScaler(feature_range=(0, 1)) training_data_normalized = scaler.fit_transform(training_data) # Function to create sequences for training def create_sequences(data, seq_length): sequences = [] targets = [] for i in range(len(data)-seq_length): seq = data[i:i+seq_length] target = data[i+seq_length:i+seq_length+1] sequences.append(seq) targets.append(target) return np.array(sequences), np.array(targets) # Define Transformer model def build_transformer_model(input_shape): inputs = Input(shape=input_shape) # Multi-head self-attention attention_output = MultiHeadAttention(num_heads=4, key_dim=input_shape[1])(inputs, inputs) # Skip connection and layer normalization attention_output = LayerNormalization(epsilon=1e-6)(inputs + attention_output) # Feed-forward neural network outputs = Dense(64, activation='relu')(attention_output) outputs = Dropout(0.65)(outputs) outputs = Dense(1, activation='linear')(outputs) # Output shape is set to 1 and linear activation function is used # Model model = Model(inputs=inputs, outputs=outputs) return model # Build and compile the Transformer model sequence_length = 24 # Sequence length used during training transformer_model = build_transformer_model(input_shape=(sequence_length, 1)) transformer_model.compile(optimizer=Adam(learning_rate=0.001), loss=MeanSquaredError(), metrics=[MeanAbsoluteError()]) # Generate sequences for training X_transformer, y_transformer = create_sequences(training_data_normalized, sequence_length) X_transformer = X_transformer.reshape((X_transformer.shape[0], sequence_length, 1)) # Train the Transformer model transformer_model.fit(X_transformer, y_transformer, epochs=10, batch_size=72, verbose=1, validation_split=0.2) # Generate predictions for the next 24 hours future_steps = 24 future_predictions_normalized = [] # Use the last sequence from the actual data as the initial input for predictions current_sequence = training_data_normalized[-sequence_length:].reshape(-1) # Flatten the sequence for i in range(future_steps): # Reshape the sequence to match the input shape of the model current_sequence_reshaped = current_sequence[-sequence_length:].reshape((1, sequence_length, 1)) # Make a prediction prediction = transformer_model.predict(current_sequence_reshaped)[0, 0] # Append the prediction to the list of future predictions future_predictions_normalized.append(prediction) # Update the current sequence by adding the prediction current_sequence = np.append(current_sequence, prediction) # Inverse transform the normalized predictions to get the actual values future_predictions = scaler.inverse_transform(np.array(future_predictions_normalized).reshape(-1, 1)) # Generate timestamps for the future predictions (hourly time points for the next day) last_timestamp = data.index[-1] future_timestamps = [last_timestamp + timedelta(hours=i) for i in range(1, future_steps + 1)] # Format x-axis to display time as '00:00:00' formatted_timestamps = [time.strftime('%H:%M:%S') for time in future_timestamps] # Set the figure size plt.figure(figsize=(15, 8)) # Plot the actual values as a line plt.plot(formatted_timestamps, actual_values, label=f'Actual Values ({specific_day})', linestyle='dashed', color='green') # Plot the predicted values as a line plt.plot(formatted_timestamps, future_predictions, label='Predicted Values', linestyle='solid', color='blue') # Scatter plot for actual values for i, txt in enumerate(actual_values): plt.scatter(formatted_timestamps, txt, color='green', marker='o') plt.annotate(f'{int(txt[0])}', (formatted_timestamps, txt[0]), textcoords="offset points", xytext=(0, 10), ha='center') # Scatter plot for predicted values for i, txt in enumerate(future_predictions): plt.scatter(formatted_timestamps, txt, color='blue', marker='o') plt.annotate(f'{int(txt[0])}', (formatted_timestamps, txt[0]), textcoords="offset points", xytext=(0, 10), ha='center') plt.xlabel('Time (KST)') plt.xticks(rotation=45, ha='right') plt.ylabel('Motion Detected') plt.title(f'Hourly Motion Detected Prediction for the Next 24 Hours ({specific_day})') plt.legend() plt.show() Below are the prediction results. Even if I keep modifying it, the prediction result comes out with the same value. What's the problem?
enter image description here
And below is my training data structure. Motion Detected is the number of motion detections and has a value between 0 and 100. enter image description here
Источник: https://stackoverflow.com/questions/780 ... sults-come