Tutorial su RNN (Rete Neurale Ricorrente): Esempio di TensorFlow
⚡ Riepilogo intelligente
Le reti neurali ricorrenti aggiungono uno stato di memoria ai neuroni ordinari, reinserendo ogni output come input successivo, in modo che il modello possa apprendere dall'ordine. Questa guida illustra come crearne una in TensorFlow e come effettuare previsioni su una serie temporale.

Perché abbiamo bisogno di una rete neurale ricorrente (RNN)?
La rete neurale ricorrente (RNN) consente di modellare unità di memoria per persistere i dati e modellare dipendenze a breve termine. Viene utilizzato anche nelle previsioni di serie temporali per l'identificazione di correlazioni e modelli di dati. Aiuta anche a produrre risultati predittivi per dati sequenziali fornendo un comportamento simile a quello di un cervello umano.
La struttura di un Rete neurale artificiale È relativamente semplice e si basa principalmente sulla moltiplicazione di matrici. Durante il primo passaggio, gli input vengono moltiplicati per pesi e bias inizialmente casuali, trasformati con una funzione di attivazione e i valori di output vengono utilizzati per effettuare una previsione. Questo passaggio fornisce un'idea di quanto la rete si discosti dalla realtà.
La metrica applicata è la perdita. Più alta è la funzione di perdita, più stupido è il modello. Per migliorare la conoscenza della rete è necessaria una certa ottimizzazione aggiustando i pesi della rete. La discesa del gradiente stocastico è il metodo utilizzato per modificare i valori dei pesi nella direzione giusta. Una volta effettuato l’adeguamento, la rete può utilizzare un’altra serie di dati per testare la sua nuova conoscenza.
L'errore, fortunatamente, è inferiore a prima, ma non ancora abbastanza piccolo. La fase di ottimizzazione viene eseguita iterativamente fino a quando l'errore non è minimizzato, ovvero non è possibile estrarre ulteriori informazioni.tracted.
Il problema con questo tipo di modello è che non ha memoria. Significa che l'input e l'output sono indipendenti. In altre parole, al modello non interessa ciò che è accaduto prima. Sorge qualche dubbio quando è necessario prevedere serie temporali o frasi perché la rete ha bisogno di informazioni sui dati storici o sulle parole passate.
Per superare questo problema, è stato sviluppato un nuovo tipo di architettura: la rete neurale ricorrente (di seguito RNN)
Cos'è una rete neurale ricorrente (RNN)?
Una rete neurale ricorrente (RNN) è una classe di reti neurali artificiali in cui la connessione tra diversi nodi forma un grafo orientato per fornire un comportamento dinamico nel tempo. Aiuta a modellare dati sequenziali derivati da reti feedforward. Funziona in modo simile al cervello umano per fornire risultati predittivi.
Una rete neurale ricorrente è molto simile a una rete neurale tradizionale, tranne per il fatto che ai neuroni viene aggiunto uno stato di memoria. Il calcolo per includere una memoria è semplice.
Immaginiamo un modello semplice con un solo neurone alimentato da un batch di dati. In una rete neurale tradizionale, il modello produce l'output moltiplicando l'input per il peso e la funzione di attivazione. Con una RNN, questo output viene inviato a se stesso un certo numero di volte. Chiamiamo passo temporale la quantità di tempo in cui l'output diventa l'input della successiva moltiplicazione di matrici.
Ad esempio, nell'immagine qui sotto, puoi vedere che la rete è composta da un neurone. La rete calcola la moltiplicazione delle matrici tra l'input e il peso e aggiunge la non linearità con la funzione di attivazione. Diventa l'uscita a t-1. Questo output è l'input della seconda moltiplicazione di matrici.
Rete neurale ricorrente (RNN)
Di seguito, codifichiamo un semplice RNN in TensorFlow per comprendere il passaggio e anche la forma dell'output.
La rete è composta da:
- Quattro ingressi
- Sei neuroni
- 2 passaggi temporali
La rete procederà come illustrato nell'immagine seguente.
La rete è detta 'ricorrente' perché esegue la stessa operazione in ogni casella attivata. La rete calcolava i pesi degli input e dell'output precedente prima di utilizzare una funzione di attivazione.
Nota sulla versione: Il codice in questo tutorial è destinato all'API del grafo di TensorFlow 1.x. Su TensorFlow 2.x lo stesso script viene comunque eseguito dopo import tensorflow.compat.v1 as tf più tf.disable_v2_behavior(), perché i segnaposto, le sessioni e il modulo rnn_cell ora risiedono sotto tf.compat.v1. L'equivalente idiomatico 2.x è tf.keras.layers.SimpleRNN.
import numpy as np import tensorflow as tf n_inputs = 4 n_neurons = 6 n_timesteps = 2 The data is a sequence of a number from 0 to 9 and divided into three batches of data. ## Data X_batch = np.array([ [[0, 1, 2, 5], [9, 8, 7, 4]], # Batch 1 [[3, 4, 5, 2], [0, 0, 0, 0]], # Batch 2 [[6, 7, 8, 5], [6, 5, 4, 2]], # Batch 3 ])
Possiamo costruire la rete con un segnaposto per i dati, la fase ricorrente e l'output.
Definire il segnaposto per i dati
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])
Qui:
- Nessuno: sconosciuto e avrà la dimensione del batch
- n_timesteps: numero di volte in cui la rete invierà l'output al neurone
- n_inputs: numero di input per batch
Definire la rete ricorrente
Come accennato nell'immagine sopra, la rete è composta da 6 neuroni. La rete calcolerà il prodotto di due punti:
- Inserisci i dati con il primo set di pesi (cioè 6: uguale al numero di neuroni)
- Output precedente con un secondo set di pesi (ad esempio, 6: corrispondente al numero di output)
Da notare che, durante il primo feedforward, i valori dell'output precedente sono pari a zero perché non abbiamo alcun valore a disposizione.
L'oggetto per costruire un RNN è tf.contrib.rnn.BasicRNNCell con l'argomento num_units per definire il numero di input
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
Ora che la rete è definita, puoi calcolare gli output e gli stati
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
Questo oggetto utilizza un ciclo interno per moltiplicare le matrici il numero appropriato di volte.
Si noti che il neurone ricorrente è una funzione di tutti gli input dei passi temporali precedenti. È così che la rete costruisce la propria memoria. Le informazioni del tempo precedente possono propagarsi nel tempo futuro. Questa è la magia delle reti neurali ricorrenti.
## Define the shape of the tensor X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs]) ## Define the network basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons) outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) init = tf.global_variables_initializer() init = tf.global_variables_initializer() with tf.Session() as sess: init.run() outputs_val = outputs.eval(feed_dict={X: X_batch}) print(states.eval(feed_dict={X: X_batch})) [[ 0.38941205 -0.9980438 0.99750966 0.7892596 0.9978241 0.9999997 ] [ 0.61096436 0.7255889 0.82977575 -0.88226104 0.29261455 -0.15597084] [ 0.62091285 -0.87023467 0.99729395 -0.58261937 0.9811445 0.99969864]]
A scopo esplicativo, vengono stampati i valori dello stato precedente. L'output stampato sopra mostra l'output dell'ultimo stato. Ora stampa tutto l'output: puoi notare che gli stati corrispondono all'output precedente di ogni batch. Ovvero, l'output precedente contiene le informazioni sull'intera sequenza.
print(outputs_val) print(outputs_val.shape) [[[-0.75934666 -0.99537754 0.9735819 -0.9722234 -0.14234993 -0.9984044 ] [ 0.99975264 -0.9983206 0.9999993 -1. -0.9997506 -1. ]] [[ 0.97486496 -0.98773265 0.9969686 -0.99950117 -0.7092863 -0.99998885] [ 0.9326837 0.2673438 0.2808514 -0.7535883 -0.43337247 0.5700631 ]] [[ 0.99628735 -0.9998728 0.99999213 -0.99999976 -0.9884324 -1. ] [ 0.99962527 -0.9467421 0.9997403 -0.99999714 -0.99929446 -0.9999795 ]]] (3, 2, 6)
La vista annotata qui sotto scompone lo stesso tensore stampato batch per batch.
L'output ha la forma di (3, 2, 6):
- 3: Numero di lotti
- 2: Numero del timestep
- 6: Numero di neuroni
L'ottimizzazione di una rete neurale ricorrente è identica a quella di una rete neurale tradizionale. Vedrai più in dettaglio come codificare l'ottimizzazione nella parte successiva di questo tutorial sulla rete neurale ricorrente.
Applicazioni della RNN
La RNN ha molteplici usi, soprattutto quando si tratta di prevedere il futuro. Nel settore finanziario, l'RNN può essere utile per prevedere i prezzi delle azioni o il segno della direzione del mercato azionario (ovvero, positivo o negativo).
L'RNN è utile per un'auto autonoma poiché può evitare un incidente stradale anticipando la traiettoria del veicolo.
RNN è ampiamente utilizzato nell'analisi del testo, nei sottotitoli delle immagini, nell'analisi del sentiment e nella traduzione automatica. Ad esempio, si può utilizzare la recensione di un film per comprendere la sensazione che lo spettatore ha percepito dopo aver visto il film. Automatizzare questa attività è molto utile quando la società cinematografica non ha abbastanza tempo per rivedere, etichettare, consolidare e analizzare le recensioni. La macchina può svolgere il lavoro con un livello di precisione più elevato.
Limitazioni dell'RNN
In teoria, RNN dovrebbe trasportare le informazioni fino a volte. Tuttavia, è piuttosto impegnativo propagare tutte queste informazioni quando il passaggio temporale è troppo lungo. Quando una rete ha troppi strati profondi, diventa inaddestrabile. Questo problema si chiama: problema gradiente evanescente. Se ricordi, la rete neurale aggiorna il peso utilizzando l'algoritmo di discesa del gradiente. I gradienti si riducono quando la rete avanza verso gli strati inferiori.
In conclusione, i gradienti rimangono costanti, il che significa che non c'è margine di miglioramento. Il modello apprende da una variazione del gradiente; questa variazione influenza l'output della rete. Tuttavia, se la differenza nel gradiente è troppo piccola (ovvero, i pesi cambiano di poco), la rete non può apprendere nulla e quindi l'output non può variare. Pertanto, una rete che si trova ad affrontare un problema di gradiente evanescente non può convergere verso una buona soluzione.
Miglioramento LSTM
Per superare il potenziale problema del gradiente evanescente che affligge le reti neurali ricorrenti (RNN), tre ricercatori, Hochreiter, Schmidhuber e Bengio, hanno migliorato le RNN con un'architettura chiamata Long Short-Term Memory (LSTM). In breve, LSTM fornisce alla rete informazioni rilevanti dal passato a momenti più recenti. La macchina utilizza un'architettura migliore per selezionare e riportare le informazioni a momenti successivi.
L'architettura LSTM è disponibile in TensorFlow, tf.contrib.rnn.LSTMCell. LSTM non rientra nell'ambito di questo tutorial. Puoi fare riferimento alla documentazione ufficiale. documentazione per ulteriori informazioni
Su TensorFlow 2.x quella cella viene raggiunta come tf.compat.v1.nn.rnn_cell.LSTMCell, mentre il nuovo codice normalmente utilizza tf.keras.layers.LSTM o il cancello più leggero tf.keras.layers.GRU, che raggiunge un'accuratezza comparabile con un minor numero di parametri.
RNN in serie temporali
In questo tutorial su TensorFlow RNN, utilizzerai una rete neurale ricorrente (RNN) con dati di serie temporali. Le serie temporali dipendono dal tempo precedente, il che significa che i valori passati contengono informazioni rilevanti da cui la rete può apprendere. L'idea alla base della previsione delle serie temporali è quella di stimare il valore futuro di una serie, ad esempio il prezzo delle azioni, la temperatura, il PIL e così via.
La preparazione dei dati per Keras RNN e le serie temporali può essere un po' complicata. Prima di tutto, l'obiettivo è prevedere il valore successivo della serie, ovvero utilizzerai le informazioni passate per stimare il valore t + 1. L'etichetta è uguale alla sequenza di input e spostata in avanti di un periodo. In secondo luogo, il numero di input è impostato su 1, ovvero un'osservazione alla volta. Infine, il passo temporale è uguale alla sequenza del valore numerico. Ad esempio, se imposti l'intervallo temporale su 10, la sequenza di input restituirà dieci volte consecutive.
Guarda il grafico qui sotto, abbiamo rappresentato i dati della serie temporale a sinistra e una sequenza di input fittizia a destra. Crei una funzione per restituire un set di dati con valore casuale per ogni giorno da gennaio 2001 a dicembre 2016
# To plot pretty figures %matplotlib inline import matplotlib import matplotlib.pyplot as plt import pandas as pd def create_ts(start = '2001', n = 201, freq = 'M'): rng = pd.date_range(start=start, periods=n, freq=freq) ts = pd.Series(np.random.uniform(-18, 18, size=len(rng)), rng).cumsum() return ts ts= create_ts(start = '2001', n = 192, freq = 'M') ts.tail(5)
Uscita
2016-08-31 -93.459631 2016-09-30 -95.264791 2016-10-31 -95.551935 2016-11-30 -105.879611 2016-12-31 -123.729319 Freq: M, dtype: float64
ts = create_ts(start = '2001', n = 222) # Left plt.figure(figsize=(11,4)) plt.subplot(121) plt.plot(ts.index, ts) plt.plot(ts.index[90:100], ts[90:100], "b-", linewidth=3, label="A training instance") plt.title("A time series (generated)", fontsize=14) # Right plt.subplot(122) plt.title("A training instance", fontsize=14) plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance") plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red') plt.legend(loc="upper left") plt.xlabel("Time") plt.show()
La parte destra del grafico mostra tutte le serie. Inizia nel 2001 e termina nel 2019. Non ha senso inserire tutti i dati nella rete; è invece necessario creare un batch di dati di lunghezza pari all'intervallo di tempo. Questo batch rappresenterà la variabile X. La variabile Y è identica a X ma traslata di un periodo (ovvero, si desidera prevedere il valore a t+1).
Entrambi i vettori hanno la stessa lunghezza. Puoi vederlo nella parte destra del grafico sopra. La linea rappresenta i dieci valori dell'input X, mentre i punti rossi sono i dieci valori dell'etichetta Y. Nota che l'etichetta inizia un periodo prima di X e termina un periodo dopo.
Crea un RNN per prevedere le serie temporali in TensorFlow
Ora, in questo corso di formazione RNN, è il momento di costruire il tuo primo RNN per prevedere la serie di cui sopra. È necessario specificare alcuni iperparametri (i parametri del modello, ad esempio il numero di neuroni, ecc.) per il modello:
- Numero di ingressi: 1
- Passo temporale (finestre nella serie temporale): 10
- Numero di neuroni: 120
- Numero di uscite: 1
La tua rete neurale apprenderà da una sequenza di 10 giorni e conterrà 120 neuroni ricorrenti. Il modello viene alimentato con un singolo input, ovvero un giorno. Sentiti libero di modificare i valori per verificare se il modello è migliorato.
Prima di costruire il modello, è necessario suddividere il dataset in un set di addestramento e un set di test. Il dataset completo contiene 222 punti dati; utilizzerete i primi 201 punti per addestrare il modello e gli ultimi 21 punti per testarlo.
Dopo aver definito un set di training e un set di test, è necessario creare un oggetto contenente i batch. In questi batch, si avranno valori X e valori Y. Ricorda che i valori X sono ritardati di un periodo. Pertanto, si utilizzano le prime 200 osservazioni e il passo temporale è pari a 10. L'oggetto X_batches dovrebbe contenere 20 batch di dimensione 10*1. L'oggetto y_batches ha la stessa struttura dell'oggetto X_batches ma con un periodo in avanti.
Passo 1) Crea il treno e prova
Prima di tutto, converti la serie in a NumPy array; quindi si definiscono le finestre (ovvero il numero di volte in cui la rete apprenderà), il numero di input, output e la dimensione del train set come mostrato nell'esempio TensorFlow RNN riportato di seguito.
series = np.array(ts) n_windows = 20 n_input = 1 n_output = 1 size_train = 201
Successivamente, dividi semplicemente l'array in due set di dati.
## Split data train = series[:size_train] test = series[size_train:] print(train.shape, test.shape) (201,) (21,)
Passo 2) Crea la funzione per restituire X_batches e y_batches
Per semplificare, puoi creare una funzione che restituisca due array diversi, uno per X_batches e uno per y_batches.
Scriviamo una funzione RNN TensorFlow per costruire i batch.
Si noti che i batch X sono in ritardo di un periodo (prendiamo il valore t-1). L'output della funzione dovrebbe avere tre dimensioni. La prima dimensione è uguale al numero di batch, la seconda alla dimensione delle finestre e l'ultima al numero di input.
La parte difficile è selezionare correttamente i punti dati. Per i punti dati X, scegli le osservazioni da t = 1 a t = 200, mentre per il punto dati Y, restituisci le osservazioni da t = 2 a 201. Una volta che hai i punti dati corretti, è semplice rimodellare la serie.
Per costruire l'oggetto con i lotti, è necessario dividere il set di dati in dieci lotti di uguale lunghezza (cioè 20). È possibile utilizzare il metodo di rimodellamento e passare -1 in modo che la serie sia simile alla dimensione del batch. Il valore 20 è il numero di osservazioni per batch e 1 è il numero di input.
Devi fare lo stesso passaggio ma per l'etichetta.
Tieni presente che devi traslare i dati del numero di volte che desideri prevedere. Ad esempio, se vuoi prevedere un giorno in anticipo, devi traslare la serie di 1. Se vuoi prevedere due giorni in anticipo, devi traslare i dati di 2.
x_data = train[:size_train-1]: Select all the training instance minus one day X_batches = x_data.reshape(-1, windows, input): create the right shape for the batch e.g (10, 20, 1) def create_batches(df, windows, input, output): ## Create X x_data = train[:size_train-1] # Select the data X_batches = x_data.reshape(-1, windows, input) # Reshape the data ## Create y y_data = train[n_output:size_train] y_batches = y_data.reshape(-1, windows, output) return X_batches, y_batches
Ora che la funzione è definita, puoi chiamarla per creare i batch come mostrato nell'esempio RNN seguente.
X_batches, y_batches = create_batches(df = train,
windows = n_windows,
input = n_input,
output = n_output)
È possibile stampare la forma per assicurarsi che le dimensioni siano corrette.
print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)
È necessario creare il set di test con un solo batch di dati e 20 osservazioni.
Tieni presente che, se esegui previsioni giorno dopo giorno, significa che il secondo valore previsto sarà basato sul valore reale del primo giorno (t+1) del set di dati di test. In effetti, il vero valore sarà noto.
Se si desidera prevedere t+2 (ovvero due giorni in anticipo), è necessario utilizzare il valore previsto t+1; se intendi pronosticare t+3 (tre giorni in anticipo), devi utilizzare il valore previsto t+1 e t+2. È logico che sia difficile prevedere con precisione con t+n giorni di anticipo.
X_test, y_test = create_batches(df = test, windows = 20,input = 1, output = 1)
print(X_test.shape, y_test.shape)
(10, 20, 1) (10, 20, 1)
Bene, la dimensione del tuo batch è pronta, puoi costruire l'architettura RNN. Ricorda, hai 120 neuroni ricorrenti.
Passo 3) Costruisci il modello
Per creare il modello è necessario definire tre parti:
- La variabile con i tensori
- La RNN
- La perdita e l'ottimizzazione
Passo 3.1) Variabili
È necessario specificare le variabili X e y con la forma appropriata. Questo passaggio è banale. Il tensore ha la stessa dimensione degli oggetti X_batches e y_batches.
Ad esempio, il tensore X è un segnaposto (controlla il tutorial su Introduzione a TensorFlow per rinfrescarti la mente sulla dichiarazione delle variabili) ha tre dimensioni:
- Nota: dimensione del lotto
- n_windows: Lunghezza delle finestre. Ovvero, il numero di volte in cui il modello guarda indietro
- n_input: numero di input
Il risultato è:
tf.placeholder(tf.float32, [None, n_windows, n_input])
## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output])
Passo 3.2) Creare la RNN
Nella seconda parte di questo esempio RNN TensorFlow, devi definire l'architettura della rete. Come prima, usi l'oggetto BasicRNNCell e dynamic_rnn da TensorFlow estimator.
## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
La parte successiva è un po' più complicata ma consente calcoli più rapidi. È necessario trasformare l'output della corsa in uno strato denso e quindi convertirlo nuovamente per avere la stessa dimensione dell'input.
stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])
Passo 3.3) Creare la perdita e l'ottimizzazione
L'ottimizzazione del modello dipende dal compito che stai eseguendo. Nel tutorial precedente su CNNNel tuo tutorial precedente, l'obiettivo era classificare le immagini; in questo tutorial sulle reti neurali ricorrenti (RNN), l'obiettivo è leggermente diverso. Ti viene chiesto di fare una previsione su una variabile continua rispetto a una classe.
Questa differenza è importante perché cambierà il problema di ottimizzazione. Il problema di ottimizzazione per una variabile continua è minimizzare l’errore quadratico medio. Per costruire queste metriche in TF, puoi utilizzare:
tf.reduce_sum(tf.square(uscite – y))
Il resto del codice RNN è lo stesso di prima; usi un ottimizzatore Adam per ridurre la perdita (ad esempio, MSE):
tf.train.AdamOptimizer(learning_rate=learning_rate)
ottimizzatore.minimizzare(perdita)
Questo è tutto, puoi mettere tutto insieme e il tuo modello è pronto per l'addestramento.
tf.reset_default_graph() r_neuron = 120 ## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output]) ## 2. create the model basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu) rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output]) ## 3. Loss + optimization learning_rate = 0.001 loss = tf.reduce_sum(tf.square(outputs - y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) training_op = optimizer.minimize(loss) init = tf.global_variables_initializer()
Addestrerai il modello utilizzando 1500 epoche e stamperai la perdita ogni 150 iterazioni. Una volta addestrato il modello, valutalo sul set di test e crea un oggetto contenente le previsioni come mostrato nell'esempio di rete neurale ricorrente riportato di seguito.
iteration = 1500 with tf.Session() as sess: init.run() for iters in range(iteration): sess.run(training_op, feed_dict={X: X_batches, y: y_batches}) if iters % 150 == 0: mse = loss.eval(feed_dict={X: X_batches, y: y_batches}) print(iters, "\tMSE:", mse) y_pred = sess.run(outputs, feed_dict={X: X_test}) 0 MSE: 502893.34 150 MSE: 13839.129 300 MSE: 3964.835 450 MSE: 2619.885 600 MSE: 2418.772 750 MSE: 2110.5923 900 MSE: 1887.9644 1050 MSE: 1747.1377 1200 MSE: 1556.3398 1350 MSE: 1384.6113
Finalmente in questo tutorial sull'RNN Deep Learning, puoi tracciare il valore effettivo della serie con il valore previsto. Se il modello viene corretto, i valori previsti dovrebbero essere messi sopra i valori effettivi.
Come puoi vedere, il modello ha margini di miglioramento. Sta a te modificare gli iperparametri come le finestre, la dimensione del batch o il numero di neuroni ricorrenti.
plt.title("Forecast vs Actual", fontsize=14) plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="Actual", color='green') plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="Forecast", color='red') plt.legend(loc="lower left") plt.xlabel("Time") plt.show()
Previsione vs Effettivo





