14 Μαΐου, 1970

Πρόβλεψη 20 αριθμών (seq2seq, LSTM), για το ΚΙΝΟ. (Prediction of 20 numbers (seq2seq, LSTM) for KINO).


Θα προχωρήσουμε σε πρόβλεψη και των 20 αριθμων του ΚΙΝΟ:
We will proceed with predicting all 20 numbers for KINO:

import os
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error, median_absolute_error
from sklearn.metrics import mean_absolute_percentage_error, r2_score

from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import LSTM, Dropout, Dense, Input, Activation, LayerNormalization
from tensorflow.keras.layers import Bidirectional, Add, Concatenate, BatchNormalization
from tensorflow.keras import regularizers
from tensorflow.keras.constraints import UnitNorm
from tensorflow.keras.initializers import RandomUniform
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint, LearningRateScheduler

from colorama import Fore, Style
from typing import Tuple, List

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

seed_value = 1
tf.random.set_seed(seed_value)
np.random.seed(seed_value)

def create_dataset() -> np.ndarray:
return np.array([
        [0.07, 0.08, 0.09, 0.11, 0.14, 0.15, 0.17, 0.23, 0.24, 0.30, 0.32, 0.33, 0.35, 0.51, 0.52,
0.56, 0.59, 0.64, 0.66, 0.74],
[0.16, 0.20, 0.21, 0.28, 0.29, 0.33, 0.34, 0.36, 0.37, 0.38, 0.41, 0.44, 0.52, 0.63, 0.66,
0.71, 0.72, 0.74, 0.77, 0.80],
[0.02, 0.11, 0.13, 0.22, 0.23, 0.27, 0.29, 0.30, 0.39, 0.42, 0.43, 0.50, 0.55, 0.62, 0.64,
0.68, 0.69, 0.71, 0.74, 0.75],
[0.01, 0.03, 0.06, 0.08, 0.12, 0.13, 0.17, 0.19, 0.21, 0.26, 0.30, 0.31, 0.34, 0.41, 0.44,
0.45, 0.53, 0.58, 0.59, 0.60],
[0.02, 0.05, 0.09, 0.10, 0.11, 0.13, 0.14, 0.17, 0.21, 0.24, 0.29, 0.30, 0.31, 0.37, 0.51,
0.55, 0.56, 0.63, 0.66, 0.80],
[0.10, 0.12, 0.21, 0.23, 0.24, 0.34, 0.37, 0.41, 0.49, 0.50, 0.51, 0.56, 0.59, 0.60, 0.68,
0.71, 0.73, 0.76, 0.79, 0.80],
[0.01, 0.07, 0.09, 0.11, 0.13, 0.17, 0.23, 0.26, 0.28, 0.36, 0.38, 0.39, 0.47, 0.50, 0.63,
0.68, 0.73, 0.74, 0.75, 0.77],
[0.01, 0.02, 0.08, 0.11, 0.20, 0.24, 0.28, 0.30, 0.32, 0.34, 0.38, 0.43, 0.44, 0.47, 0.51,
0.58, 0.60, 0.64, 0.72, 0.76],
[0.03, 0.04, 0.14, 0.19, 0.21, 0.23, 0.27, 0.29, 0.34, 0.35, 0.38, 0.48, 0.51, 0.55, 0.56,
0.60, 0.61, 0.70, 0.74, 0.76],
[0.09, 0.10, 0.13, 0.14, 0.15, 0.17, 0.24, 0.26, 0.29, 0.32, 0.35, 0.40, 0.48, 0.55, 0.60,
0.61, 0.70, 0.76, 0.77, 0.80],
])
def create_sequences(data: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
input_data, output_data = [], []
for i in range(len(data) - 1):
input_data.append(data[i])
output_data.append(data[i + 1])
return np.array(input_data), np.array(output_data)

def split_data(input_data: np.ndarray, output_data: np.ndarray, split_ratio: float = 0.75) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
split_point = int(len(input_data) * split_ratio)
return input_data[:split_point], input_data[split_point:], output_data[:split_point], output_data[split_point:]

class CustomAttention(tf.keras.layers.Layer):
def __init__(self, num_heads, key_dim):
super(CustomAttention, self).__init__()
self.num_heads = num_heads
self.key_dim = key_dim
self.query_dense = Dense(key_dim)
self.key_dense = Dense(key_dim)
self.value_dense = Dense(key_dim)

def call(self, inputs):
query, key, value = inputs, inputs, inputs
query = self.query_dense(query)
key = self.key_dense(key)
value = self.value_dense(value)

scores = tf.matmul(query, key, transpose_b=True)
scores = Activation('tanh')(scores)
attention_weights = tf.nn.softmax(scores, axis=-1)
context = tf.matmul(attention_weights, value)
return context

def build_model(input_shape: Tuple[int, int], num_units: List[int], num_heads: int) -> Model:
encoder_inputs = Input(shape=input_shape)

encoder_lstm1 = Bidirectional(LSTM(num_units[0],
activation='tanh',
recurrent_activation='sigmoid',
return_sequences=True,
return_state=True,
unroll=True,
unit_forget_bias=True,
recurrent_dropout=0.1,
stateful=False,
go_backwards=False,
use_bias=True,
bias_constraint=UnitNorm(axis=0),
kernel_constraint=UnitNorm(axis=0),
recurrent_constraint=UnitNorm(axis=0),
bias_initializer=RandomUniform(minval=-1, maxval=1),
kernel_initializer=RandomUniform(minval=-1, maxval=1),
recurrent_initializer=RandomUniform(minval=-1, maxval=1),
bias_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
kernel_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
activity_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
recurrent_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001)))

encoder_outputs1, forward_h1, forward_c1, backward_h1, backward_c1 = encoder_lstm1(encoder_inputs)
encoder_outputs1 = BatchNormalization()(encoder_outputs1)

state_h1 = Concatenate()([forward_h1, backward_h1])
state_c1 = Concatenate()([forward_c1, backward_c1])

attention1 = CustomAttention(num_heads=num_heads, key_dim=num_units[0])
attention_output1 = attention1(encoder_outputs1)

encoder_lstm2 = Bidirectional(LSTM(num_units[1],
activation='tanh',
recurrent_activation='sigmoid',
return_sequences=True,
return_state=True,
unroll=True,
unit_forget_bias=True,
recurrent_dropout=0.1,
stateful=False,
go_backwards=False,
use_bias=True,
bias_constraint=UnitNorm(axis=0),
kernel_constraint=UnitNorm(axis=0),
recurrent_constraint=UnitNorm(axis=0),
bias_initializer=RandomUniform(minval=-1, maxval=1),
kernel_initializer=RandomUniform(minval=-1, maxval=1),
recurrent_initializer=RandomUniform(minval=-1, maxval=1),
bias_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
kernel_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
activity_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
recurrent_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001)))

encoder_outputs2, forward_h2, forward_c2, backward_h2, backward_c2 = encoder_lstm2(attention_output1)
encoder_outputs2 = BatchNormalization()(encoder_outputs2)

state_h2 = Concatenate()([forward_h2, backward_h2])
state_c2 = Concatenate()([forward_c2, backward_c2])

attention2 = CustomAttention(num_heads=num_heads, key_dim=num_units[1])
attention_output2 = attention2(encoder_outputs2)

encoder_states = [state_h2, state_c2]

decoder_inputs = Input(shape=input_shape)
decoder_lstm1 = LSTM(num_units[0],
activation='tanh',
recurrent_activation='sigmoid',
return_sequences=True,
return_state=True,
unroll=True,
unit_forget_bias=True,
recurrent_dropout=0.1,
stateful=False,
go_backwards=False,
use_bias=True,
bias_constraint=UnitNorm(axis=0),
kernel_constraint=UnitNorm(axis=0),
recurrent_constraint=UnitNorm(axis=0),
bias_initializer=RandomUniform(minval=-1, maxval=1),
kernel_initializer=RandomUniform(minval=-1, maxval=1),
recurrent_initializer=RandomUniform(minval=-1, maxval=1),
bias_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
kernel_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
activity_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
recurrent_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001
))

state_h1_proj = Dense(num_units[0], activation='tanh')(state_h1)
state_c1_proj = Dense(num_units[0], activation='tanh')(state_c1)

decoder_outputs1, _, _ = decoder_lstm1(decoder_inputs, initial_state=[state_h1_proj, state_c1_proj])
decoder_outputs1 = BatchNormalization()(decoder_outputs1)

attention3 = CustomAttention(num_heads=num_heads, key_dim=num_units[0])
attention_output3 = attention3(decoder_outputs1)

decoder_lstm2 = LSTM(num_units[1],
activation='tanh',
recurrent_activation='sigmoid',
return_sequences=True,
return_state=True,
unroll=True,
unit_forget_bias=True,
recurrent_dropout=0.1,
stateful=False,
go_backwards=False,
use_bias=True,
bias_constraint=UnitNorm(axis=0),
kernel_constraint=UnitNorm(axis=0),
recurrent_constraint=UnitNorm(axis=0),
bias_initializer=RandomUniform(minval=-1, maxval=1),
kernel_initializer=RandomUniform(minval=-1, maxval=1),
recurrent_initializer=RandomUniform(minval=-1, maxval=1),
bias_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
kernel_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
activity_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
recurrent_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001))

state_h2_proj = Dense(num_units[1], activation='tanh')(state_h2)
state_c2_proj = Dense(num_units[1], activation='tanh')(state_c2)

decoder_outputs2, _, _ = decoder_lstm2(attention_output3, initial_state=[state_h2_proj, state_c2_proj])
decoder_outputs2 = BatchNormalization()(decoder_outputs2)

attention4 = CustomAttention(num_heads=num_heads, key_dim=num_units[1])
attention_output4 = attention4(decoder_outputs2)

decoder_outputs2 = Add()([decoder_outputs2, attention_output4])

decoder_dense = Dense(input_shape[1],
activation='tanh',
use_bias=True,
bias_initializer=RandomUniform(minval=-1, maxval=1),
kernel_initializer=RandomUniform(minval=-1, maxval=1),
bias_constraint=UnitNorm(axis=0),
kernel_constraint=UnitNorm(axis=0),
bias_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
activity_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001),
kernel_regularizer=regularizers.l1_l2(l1=0.00000001, l2=0.00000001))

decoder_outputs = decoder_dense(decoder_outputs2)

return Model([encoder_inputs, decoder_inputs], decoder_outputs)

def scheduler(epoch, lr):
if epoch < 20:
return lr
else:
return float(lr * tf.math.exp(-0.1))

def train_model(model: Model, train_X: np.ndarray, train_Y: np.ndarray, val_X: np.ndarray, val_Y: np.ndarray,
batch_size: int = 32, epochs: int = 150) -> tf.keras.callbacks.History:

early_stopping = EarlyStopping(monitor='val_loss', patience=75, verbose=2, mode='min', restore_best_weights=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=30, verbose=2, mode='min', factor=0.001, min_lr=1e-7)
model_checkpoint = ModelCheckpoint('best_model.keras', monitor='val_loss', save_best_only=True, mode='min', verbose=2)
lr_scheduler = LearningRateScheduler
(scheduler)

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss=tf.keras.losses.MeanSquaredError(),
metrics=[tf.keras.metrics.MeanSquaredError(),
tf.keras.metrics.MeanAbsoluteError(),
tf.keras.metrics.MeanAbsolutePercentageError()])

return model.fit([train_X, train_X], train_Y,
epochs=epochs,
batch_size=batch_size,
validation_data=([val_X, val_X], val_Y),
callbacks=[early_stopping, reduce_lr, model_checkpoint, lr_scheduler])

def make_predictions(model: Model, val_X: np.ndarray) -> np.ndarray:
return model.predict([val_X, val_X])

def display_results(predicted_next_line: np.ndarray, dataset: np.ndarray) -> None:
predictions = np.round(predicted_next_line * 100).astype(int)
predicted_values = np.round(predicted_next_line * 100).astype(int)
actual_values = np.round(dataset[-1] * 100).astype(int)
predicted_set = set(predicted_values)
actual_set = set(actual_values)
common_values = predicted_set.intersection(actual_set)
common_values_sorted = sorted(common_values)
sorted_predictions = sorted(predictions)

print(f"\nΟΙ ΠΡΟΒΛΕΠΟΜΕΝΟΙ ΑΡΙΘΜΟΙ: {', '.join(map(str, sorted_predictions))}")
temperatures = ', '.join(f"{temp * 100:.0f}" for temp in dataset[-1])
print(f"Η ΤΕΛΕΥΤΑΙΑ ΚΛΗΡΩΣΗ: {temperatures}")
print(f"\nΚΟΙΝΕΣ ΤΙΜΕΣ: {common_values_sorted}")

def main():
dataset = create_dataset()
input_data, output_data = create_sequences(dataset)
input_data = input_data.reshape(input_data.shape[0], 1, input_data.shape[1])
output_data = output_data.reshape(output_data.shape[0], 1, output_data.shape[1])

train_X, val_X, train_Y, val_Y = split_data(input_data, output_data)

num_units = [256, 256]
num_heads = 20

model = build_model((1, dataset.shape[1]), num_units, num_heads)
history = train_model(model, train_X, train_Y, val_X, val_Y)

next_line_input = dataset[-1].reshape(1, 1, dataset.shape[1])
predicted_next_line = make_predictions(model, next_line_input).reshape(-1)

display_results(predicted_next_line, dataset)
tf.keras.backend.clear_session()

if __name__ == "__main__":
main()

Αποτελέσματα:
Result:

Το πρόγραμμα αυτό χρησιμοποιεί την τεχνητή νοημοσύνη για να δημιουργήσει και να εκπαιδεύσει ένα νευρωνικό δίκτυο που προβλέπει τις μελλοντικές τιμές μιας σειράς δεδομένων.

1. Εισαγωγή και Αρχικοποίηση

  • Βιβλιοθήκες: Χρησιμοποιούνται βιβλιοθήκες όπως το TensorFlow για νευρωνικά δίκτυα, το NumPy για αριθμητικές λειτουργίες, το Matplotlib για γραφήματα και το Scikit-learn για την προεπεξεργασία δεδομένων και την αξιολόγηση του μοντέλου.
  • Καταστολή Προειδοποιήσεων: Καταστέλλονται οι προειδοποιήσεις από το TensorFlow για καθαρότερη έξοδο.
  • Ορισμός Τυχαίων Σπόρων: Ορίζονται τυχαίοι σπόροι για να εξασφαλιστεί η αναπαραγωγιμότητα των αποτελεσμάτων.

2. Δημιουργία Συνόλου Δεδομένων

  • Συνάρτηση create_dataset: Δημιουργεί ένα προκαθορισμένο σύνολο δεδομένων, το οποίο αποτελείται από τέσσερις λίστες με αριθμούς.

3. Δημιουργία Ακολουθιών

  • Συνάρτηση create_sequences: Μετατρέπει το σύνολο δεδομένων σε ακολουθίες εισόδων και εξόδων. Κάθε είσοδος είναι μια σειρά αριθμών και η αντίστοιχη έξοδος είναι η επόμενη σειρά.

4. Διαίρεση Δεδομένων

  • Συνάρτηση split_data: Χωρίζει τα δεδομένα σε σύνολα εκπαίδευσης και επαλήθευσης με βάση μια προκαθορισμένη αναλογία.

5. Κατασκευή Προσαρμοσμένου Επιπέδου Προσοχής

  • Κλάση CustomAttention: Δημιουργεί ένα προσαρμοσμένο επίπεδο προσοχής που ενισχύει τη σημασία των εισόδων με βάση τις σχέσεις τους.

6. Κατασκευή Μοντέλου

  • Συνάρτηση build_model: Κατασκευάζει το νευρωνικό δίκτυο που αποτελείται από διπλά LSTM επίπεδα με διπλή κατεύθυνση και επίπεδα προσοχής. Τα LSTM επίπεδα χρησιμοποιούνται για την επεξεργασία ακολουθιών δεδομένων.

7. Εκπαίδευση του Μοντέλου

  • Συνάρτηση train_model: Εκπαιδεύει το μοντέλο με τα δεδομένα εκπαίδευσης χρησιμοποιώντας διάφορα callbacks όπως η πρόωρη διακοπή, η μείωση του ρυθμού μάθησης και η αποθήκευση του καλύτερου μοντέλου.

8. Πρόβλεψη

  • Συνάρτηση make_predictions: Χρησιμοποιεί το εκπαιδευμένο μοντέλο για να κάνει προβλέψεις στα δεδομένα εισόδου.

9. Εμφάνιση Αποτελεσμάτων

  • Συνάρτηση display_results: Εμφανίζει τις προβλέψεις και συγκρίνει τις προβλεπόμενες τιμές με τις πραγματικές τιμές από το τελευταίο δείγμα του συνόλου δεδομένων.

10. Κύρια Συνάρτηση

  • Συνάρτηση main: Εκτελεί τα παραπάνω βήματα με τη σωστή σειρά:
    1. Δημιουργεί το σύνολο δεδομένων.
    2. Δημιουργεί τις ακολουθίες εισόδων και εξόδων.
    3. Αναδιατάσσει και χωρίζει τα δεδομένα.
    4. Κατασκευάζει το μοντέλο.
    5. Εκπαιδεύει το μοντέλο.
    6. Κάνει προβλέψεις με το εκπαιδευμένο μοντέλο.
    7. Εμφανίζει τα αποτελέσματα.
    8. Καθαρίζει τη συνεδρία του TensorFlow για να απελευθερώσει πόρους.

ΟΙ ΠΡΟΒΛΕΠΟΜΕΝΟΙ ΑΡΙΘΜΟΙ: 4, 8, 14, 15, 19, 23, 26, 28, 35, 36, 39, 42, 46, 53,
57, 63, 66, 71, 72, 78
ΟΙ ΑΡΙΘΜΟΙ ΤΗΣ ΤΕΛΕΥΤΑΙΑΣ ΚΛΗΡΩΣΗΣ: 9, 10, 13, 14, 15, 17, 24, 26, 29, 32, 35, 
40, 48, 55, 60, 61,70, 76, 77, 80

ΚΟΙΝΕΣ ΤΙΜΕΣ ΜΕΤΑΞΥ ΠΡΟΒΛΕΨΗΣ ΚΑΙ ΤΕΛΕΥΤΑΙΑΣ ΚΛΗΡΩΣΗΣ: [14, 15, 26, 35]