Tutoriel RNN (Recurrent Neural Network) : exemple TensorFlow

⚡ Résumé intelligent

Les réseaux de neurones récurrents ajoutent une mémoire aux neurones classiques, en réutilisant chaque sortie comme entrée suivante afin que le modèle apprenne par séquencement. Ce tutoriel explique comment en construire un avec TensorFlow et prédire une série temporelle.

  • (I.e. État de la mémoire : Chaque neurone récurrent reçoit la sortie précédente ainsi que la nouvelle entrée, ce qui confère au réseau sa conscience temporelle.
  • ☑️ Forme de sortie : Une exécution du réseau jouet renvoie un tenseur (3, 2, 6) : lots, pas de temps et neurones dans cet ordre.
  • ✅ Règle de traitement par lots : Les entrées de séries temporelles sont remodelées en trois dimensions et le tableau d'étiquettes est la même série décalée d'une période.
  • 🧪 Squelette du modèle : Des espaces réservés, une cellule BasicRNNCell enveloppée dans dynamic_rnn, une projection dense, puis une erreur quadratique moyenne avec un optimiseur Adam.
  • ️ Course d'entraînement : 1 500 époques sur 120 neurones récurrents font passer la perte de 502 893 à environ 1 385.
  • (I.e. Limite connue : Les longues séquences déclenchent le problème de disparition du gradient, que les LSTM et leurs variantes à porte ont été conçues pour résoudre.

Réseau neuronal récurrent (RNN)

Pourquoi avons-nous besoin d’un réseau neuronal récurrent (RNN) ?

Le réseau neuronal récurrent (RNN) vous permet de modéliser des unités de mémoire pour conserver les données et modéliser les dépendances à court terme. Il est également utilisé dans la prévision de séries chronologiques pour l’identification de corrélations et de modèles de données. Il permet également de produire des résultats prédictifs pour les données séquentielles en offrant un comportement similaire à celui d'un cerveau humain.

La structure d'un Réseau neuronal artificiel Cette opération est relativement simple et repose principalement sur la multiplication matricielle. Dans un premier temps, les entrées sont multipliées par des poids et un biais initialement aléatoires, puis transformées par une fonction d'activation. Les valeurs de sortie ainsi obtenues servent à effectuer une prédiction. Cette étape permet d'évaluer la précision du modèle par rapport à la réalité.

La métrique appliquée est la perte. Plus la fonction de perte est élevée, plus le modèle est stupide. Pour améliorer la connaissance du réseau, une certaine optimisation est nécessaire en ajustant les poids du réseau. La descente de gradient stochastique est la méthode utilisée pour modifier les valeurs des poids dans le bon sens. Une fois l’ajustement effectué, le réseau peut utiliser un autre lot de données pour tester ses nouvelles connaissances.

L'erreur est heureusement plus faible qu'auparavant, mais pas encore suffisamment réduite. L'optimisation est donc effectuée de manière itérative jusqu'à ce que l'erreur soit minimisée, c'est-à-dire jusqu'à ce qu'aucune information supplémentaire ne puisse être extraite.tracTed.

Le problème avec ce type de modèle est qu’il n’a pas de mémoire. Cela signifie que l'entrée et la sortie sont indépendantes. En d’autres termes, le modèle ne se soucie pas de ce qui a précédé. Cela soulève des questions lorsque vous devez prédire des séries chronologiques ou des phrases, car le réseau a besoin d'informations sur les données historiques ou les mots passés.

Pour pallier ce problème, un nouveau type d'architecture a été développé : le réseau de neurones récurrents (RNN ci-après)

Qu'est-ce qu'un réseau neuronal récurrent (RNN) ?

Un réseau de neurones récurrent (RNN) est un type de réseau de neurones artificiels où les connexions entre les différents nœuds forment un graphe orienté, ce qui lui confère un comportement dynamique dans le temps. Il permet de modéliser des données séquentielles issues de réseaux à propagation directe. Son fonctionnement est similaire à celui du cerveau humain pour fournir des résultats prédictifs.

Un réseau neuronal récurrent ressemble beaucoup à un réseau neuronal traditionnel, sauf qu'un état mémoire est ajouté aux neurones. Le calcul pour inclure une mémoire est simple.

Imaginez un modèle simple avec un seul neurone alimenté par un lot de données. Dans un réseau de neurones traditionnel, le modèle produit la sortie en multipliant l'entrée par le poids et la fonction d'activation. Avec un RNN, cette sortie est renvoyée à elle-même un certain nombre de fois. On l'appelle récursivité. pas de temps le temps nécessaire pour que la sortie devienne l'entrée de la multiplication matricielle suivante.

Par exemple, dans l’image ci-dessous, vous pouvez voir que le réseau est composé d’un neurone. Le réseau calcule la multiplication matricielle entre l'entrée et le poids et ajoute de la non-linéarité avec la fonction d'activation. Cela devient la sortie à t-1. Cette sortie est l'entrée de la deuxième multiplication matricielle.

Un seul neurone récurrent renvoie sa sortie à t-1 comme entrée de la multiplication suivante

Réseau de neurones récurrents (RNN)

Ci-dessous, nous codons un simple RNN dans TensorFlow pour comprendre l'étape ainsi que la forme de la sortie.

Le réseau est composé de :

  • Quatre entrées
  • Six neurones
  • 2 étapes

Le réseau fonctionnera comme le montre l'image ci-dessous.

Réseau de neurones récurrents déroulé avec quatre entrées, six neurones et deux étapes temporelles

Le réseau est dit « récurrent » car il effectue la même opération dans chaque case activée. Le réseau a calculé les poids des entrées et de la sortie précédente avant d'utiliser une fonction d'activation.

Note de version : Le code de ce tutoriel cible l'API graphique de TensorFlow 1.x. Sur TensorFlow 2.x, le même script s'exécute toujours après import tensorflow.compat.v1 as tf plus tf.disable_v2_behavior(), car les espaces réservés, les sessions et le module rnn_cell résident désormais sous tf.compat.v1L'équivalent idiomatique en 2.x est 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
    ])

Nous pouvons construire le réseau avec un espace réservé pour les données, l'étape récurrente et le résultat.

Définir l'espace réservé pour les données

X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Ici:

  • Aucun : Inconnu et prendra la taille du lot
  • n_timesteps : nombre de fois que le réseau renverra la sortie au neurone
  • n_inputs : nombre d'entrées par lot

Définir le réseau récurrent

Comme mentionné sur l'image ci-dessus, le réseau est composé de 6 neurones. Le réseau calculera deux produits scalaires :

  • Données d'entrée avec le premier ensemble de poids (c'est-à-dire 6 : égal au nombre de neurones)
  • Sortie précédente avec un deuxième ensemble de pondérations (c.-à-d. 6 : correspondant au nombre de sorties)

Notez que, lors du premier feedforward, les valeurs de la sortie précédente sont égales à des zéros car nous n'avons aucune valeur disponible.

L'objet pour construire un RNN est tf.contrib.rnn.BasicRNNCell avec l'argument num_units pour définir le nombre d'entrées

basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)

Maintenant que le réseau est défini, vous pouvez calculer les sorties et les états

outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)

Cet objet utilise une boucle interne pour multiplier les matrices le nombre de fois approprié.

Notez que le neurone récurrent est fonction de toutes les entrées des instants précédents. C'est ainsi que le réseau construit sa propre mémoire. L'information de l'instant précédent peut se propager dans le futur. C'est là toute la magie des réseaux de neurones récurrents.

## 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]]

À titre explicatif, vous affichez les valeurs de l'état précédent. L'affichage ci-dessus correspond à la sortie du dernier état. Affichez maintenant toutes les sorties : vous constaterez que les états correspondent aux sorties précédentes de chaque lot. Autrement dit, la sortie précédente contient les informations relatives à la séquence complète.

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 vue annotée ci-dessous décompose le même tenseur imprimé lot par lot.

Tenseur de sortie RNN annoté indiquant les trois lots, les six sorties neuronales et la forme (3, 2, 6).

La sortie a la forme de (3, 2, 6) :

  • 3 : Nombre de lots
  • 2 : Numéro du pas de temps
  • 6 : Nombre de neurones

L'optimisation d'un réseau de neurones récurrent est identique à un réseau de neurones traditionnel. Vous verrez plus en détail comment coder l'optimisation dans la prochaine partie de ce tutoriel sur les réseaux de neurones récurrents.

Applications du RNN

RNN a de multiples utilisations, notamment lorsqu’il s’agit de prédire l’avenir. Dans le secteur financier, RNN peut être utile pour prédire les cours des actions ou le signe de la direction du marché boursier (c'est-à-dire positive ou négative).

Le RNN est utile pour une voiture autonome car il permet d’éviter un accident de voiture en anticipant la trajectoire du véhicule.

RNN est largement utilisé dans l’analyse de texte, le sous-titrage d’images, l’analyse des sentiments et la traduction automatique. Par exemple, on peut utiliser une critique de film pour comprendre le sentiment ressenti par le spectateur après avoir regardé le film. L'automatisation de cette tâche est très utile lorsque la société cinématographique ne dispose pas de suffisamment de temps pour réviser, étiqueter, consolider et analyser les critiques. La machine peut effectuer le travail avec un niveau de précision plus élevé.

Limites du RNN

En théorie, RNN est censé transporter les informations plusieurs fois. Cependant, il est assez difficile de propager toutes ces informations lorsque le pas de temps est trop long. Lorsqu’un réseau comporte trop de couches profondes, il devient impossible à entraîner. Ce problème s'appelle : problème de gradient en voie de disparition. Si vous vous en souvenez, le réseau neuronal met à jour le poids à l'aide de l'algorithme de descente de gradient. Les gradients diminuent à mesure que le réseau descend vers les couches inférieures.

En conclusion, les gradients restent constants, ce qui signifie qu'il n'y a pas de marge d'amélioration. Le modèle apprend d'une variation du gradient ; cette variation influence la sortie du réseau. Cependant, si la différence de gradient est trop faible (c'est-à-dire si les poids varient peu), le réseau ne peut rien apprendre et, par conséquent, la sortie ne peut évoluer. Ainsi, un réseau confronté à un problème de gradient nul ne peut converger vers une solution satisfaisante.

Amélioration LSTM

Pour pallier le problème potentiel de disparition du gradient auquel sont confrontés les réseaux de neurones récurrents (RNN), trois chercheurs, Hochreiter, Schmidhuber et Bengio, ont amélioré ces réseaux grâce à une architecture appelée LSTM (Long Short-Term Memory). En résumé, LSTM fournit au réseau des informations passées pertinentes pour les périodes plus récentes. Le système utilise ainsi une architecture plus performante pour sélectionner et transmettre les informations aux périodes ultérieures.

L'architecture LSTM est disponible dans TensorFlow, sous le nom tf.contrib.rnn.LSTMCell. LSTM n'est pas abordée dans ce tutoriel. Vous pouvez consulter la documentation officielle. Documentation pour plus d'informations

Sur TensorFlow 2.x, cette cellule est atteinte comme tf.compat.v1.nn.rnn_cell.LSTMCell, tandis que le nouveau code utilise normalement tf.keras.layers.LSTM ou le portail allumeur tf.keras.layers.GRU, ce qui permet d'atteindre une précision comparable avec moins de paramètres.

RNN en séries chronologiques

Dans ce tutoriel TensorFlow sur les réseaux de neurones récurrents (RNN), vous utiliserez un RNN avec des données de séries temporelles. Les séries temporelles dépendent des données passées, ce qui signifie que ces valeurs contiennent des informations pertinentes dont le réseau peut tirer des enseignements. L'objectif de la prédiction de séries temporelles est d'estimer la valeur future d'une série, par exemple le cours d'une action, la température, le PIB, etc.

La préparation des données pour Keras RNN et les séries chronologiques peut être un peu délicate. Tout d'abord, l'objectif est de prédire la prochaine valeur de la série, ce qui signifie que vous utiliserez les informations passées pour estimer la valeur à t + 1. L'étiquette est égale à la séquence d'entrée et décalée d'une période en avant. Deuxièmement, le nombre d'entrées est fixé à 1, c'est-à-dire une observation par fois. Enfin, le pas de temps est égal à la séquence de la valeur numérique. Par exemple, si vous définissez le pas de temps sur 10, la séquence d'entrée sera renvoyée dix fois consécutives.

Regardez le graphique ci-dessous, nous avons représenté les données de la série chronologique à gauche et une séquence d'entrée fictive à droite. Vous créez une fonction pour renvoyer un ensemble de données avec une valeur aléatoire pour chaque jour de janvier 2001 à décembre 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)

Sortie

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()

Série temporelle générée à gauche et exemple d'entraînement en dix étapes avec cibles décalées à droite

La partie droite du graphique présente toutes les séries. Elles commencent en 2001 et se terminent en 2019. Il est inutile d'injecter toutes les données dans le réseau ; il est préférable de créer un lot de données dont la longueur correspond à l'intervalle de temps. Ce lot constituera la variable X. La variable Y est identique à X, mais décalée d'une période (c'est-à-dire que l'on souhaite prévoir la valeur à t+1).

Les deux vecteurs ont la même longueur. Vous pouvez le voir dans la partie droite du graphique ci-dessus. La ligne représente les dix valeurs de l'entrée X, tandis que les points rouges sont les dix valeurs de l'étiquette, Y. Notez que l'étiquette commence une période avant X et se termine une période après.

Créer un RNN pour prédire des séries temporelles dans TensorFlow

Maintenant, dans cette formation RNN, il est temps de créer votre premier RNN pour prédire la série ci-dessus. Vous devez spécifier certains hyperparamètres (les paramètres du modèle, c'est-à-dire le nombre de neurones, etc.) pour le modèle :

  • Nombre d'entrée : 1
  • Pas de temps (fenêtres en séries temporelles) : 10
  • Nombre de neurones : 120
  • Nombre de sortie : 1

Votre réseau apprendra à partir d'une séquence de 10 jours et comprendra 120 neurones récurrents. Vous alimenterez le modèle avec une seule entrée, soit un jour. N'hésitez pas à modifier les valeurs pour observer si le modèle s'est amélioré.

Avant de construire le modèle, vous devez diviser l'ensemble de données en un ensemble d'entraînement et un ensemble de test. L'ensemble de données complet comporte 222 points ; vous utiliserez les 201 premiers points pour entraîner le modèle et les 21 derniers pour le tester.

Après avoir défini les ensembles d'entraînement et de test, vous devez créer un objet contenant les lots. Ces lots comprennent les valeurs X et Y. Les valeurs X sont décalées d'une période. Par conséquent, vous utilisez les 200 premières observations et le pas de temps est de 10. L'objet `X_batches` doit contenir 20 lots de taille 10 × 1. L'objet `y_batches` a la même structure que `X_batches`, mais avec une période d'avance.

Étape 1) Créer le train et tester

Tout d'abord, vous convertissez la série en un NumPy tableau; Ensuite, vous définissez les fenêtres (c'est-à-dire le nombre de fois où le réseau apprendra), le nombre d'entrées, de sorties et la taille de la rame, comme indiqué dans l'exemple TensorFlow RNN ci-dessous.

series = np.array(ts)
n_windows = 20   
n_input =  1
n_output = 1
size_train = 201

Après cela, vous divisez simplement le tableau en deux ensembles de données.

## Split data
train = series[:size_train]
test = series[size_train:]
print(train.shape, test.shape)
(201,) (21,)

Étape 2) Créez la fonction pour renvoyer X_batches et y_batches

Pour faciliter les choses, vous pouvez créer une fonction qui renvoie deux tableaux différents, un pour X_batches et un pour y_batches.

Écrivons une fonction RNN TensorFlow pour construire les lots.

A noter que les lots X sont décalés d'une période (on prend la valeur t-1). La sortie de la fonction doit avoir trois dimensions. Les premières dimensions sont égales au nombre de lots, la seconde à la taille des fenêtres et la dernière au nombre d'entrées.

La partie la plus délicate consiste à sélectionner correctement les points de données. Pour les points de données X, vous choisissez les observations de t = 1 à t = 200, tandis que pour le point de données Y, vous renvoyez les observations de t = 2 à 201. Une fois que vous avez les points de données corrects, il est simple de remodeler les séries.

Pour construire l'objet avec les lots, vous devez diviser l'ensemble de données en dix lots de longueur égale (c'est-à-dire 20). Vous pouvez utiliser la méthode reshape et transmettre -1 pour que la série soit similaire à la taille du lot. La valeur 20 est le nombre d'observations par lot et 1 est le nombre d'entrées.

Vous devez faire la même étape mais pour l’étiquette.

Notez qu'il est nécessaire de décaler les données du nombre de périodes de prévision souhaitées. Par exemple, pour une prévision à un jour, décalez la série de 1. Pour une prévision à deux jours, décalez les données de 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

Maintenant que la fonction est définie, vous pouvez l'appeler pour créer les lots comme indiqué dans l'exemple RNN ci-dessous.

X_batches, y_batches = create_batches(df = train,
                                      windows = n_windows,
                                      input = n_input,
                                      output = n_output)

Vous pouvez imprimer la forme pour vous assurer que les dimensions sont correctes.

print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)

Vous devez créer l'ensemble de test avec un seul lot de données et 20 observations.

Notez que si vous prévoyez jours après jours, cela signifie que la deuxième valeur prédite sera basée sur la valeur réelle du premier jour (t+1) de l'ensemble de données de test. En fait, la vraie valeur sera connue.

Si vous souhaitez prévoir t+2 (c'est-à-dire deux jours à l'avance), vous devez utiliser la valeur prédite t+1 ; si vous souhaitez prédire t+3 (trois jours à l'avance), vous devez utiliser les valeurs prédites t+1 et t+2. Il est logique qu’il soit difficile de prédire avec précision t+n jours à l’avance.

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)

Très bien, la taille de votre lot est prête, vous pouvez créer l'architecture RNN. N'oubliez pas que vous disposez de 120 neurones récurrents.

Étape 3) Construisez le modèle

Pour créer le modèle, vous devez définir trois parties :

  1. La variable avec les tenseurs
  2. Le RNN
  3. La perte et l'optimisation

Étape 3.1) Variables

Vous devez spécifier les variables X et y avec la forme appropriée. Cette étape est triviale. Le tenseur a la même dimension que les objets X_batches et y_batches.

Par exemple, le tenseur X est un espace réservé (consultez le tutoriel sur Introduction à TensorFlow pour vous rafraîchir l'esprit sur la déclaration des variables) a trois dimensions :

  • Remarque : taille du lot
  • n_windows : Longueur des fenêtres, c’est-à-dire le nombre de fois où le modèle regarde en arrière.
  • n_input : nombre d'entrées

Le résultat est:

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])

Étape 3.2) Créer le RNN

Dans la deuxième partie de cet exemple RNN TensorFlow, vous devez définir l'architecture du réseau. Comme auparavant, vous utilisez les objets BasicRNNCell et Dynamic_rnn de l'estimateur TensorFlow.

## 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 partie suivante est un peu plus délicate mais permet un calcul plus rapide. Vous devez transformer la sortie de l'exécution en une couche dense, puis la convertir à nouveau pour avoir la même dimension que l'entrée.

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])  

Étape 3.3) Créer la perte et l'optimisation

L'optimisation du modèle dépend de la tâche que vous effectuez. Dans le tutoriel précédent sur CNNDans votre tutoriel précédent, l'objectif était de classifier des images. L'objectif est légèrement différent : il s'agit de prédire si une variable continue appartient à une classe.

Cette différence est importante car elle va changer le problème d'optimisation. Le problème d'optimisation pour une variable continue est de minimiser l'erreur quadratique moyenne. Pour construire ces métriques dans TF, vous pouvez utiliser :

tf.reduce_sum(tf.square(sorties – y))

Le reste du code RNN est le même qu’avant ; vous utilisez un optimiseur Adam pour réduire la perte (c'est-à-dire MSE) :

tf.train.AdamOptimizer(learning_rate=learning_rate)

optimiseur.minimiser (perte)

Voilà, vous pouvez tout emballer et votre modèle est prêt à s'entraîner.

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() 

Vous entraînerez le modèle en utilisant 1500 150 époques et imprimerez la perte toutes les itérations. Une fois le modèle entraîné, vous évaluez le modèle sur l'ensemble de test et créez un objet contenant les prédictions, comme indiqué dans l'exemple de réseau neuronal récurrent ci-dessous.

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

Enfin, dans ce didacticiel RNN Deep Learning, vous pouvez tracer la valeur réelle de la série avec la valeur prédite. Si votre modèle est corrigé, les valeurs prédites doivent être placées au-dessus des valeurs réelles.

Comme vous pouvez le constater, le modèle peut être amélioré. Il vous appartient de modifier les hyperparamètres tels que la taille des fenêtres, la taille des lots ou le nombre de neurones récurrents.

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()

Graphique prévisionnel versus réel, avec les points réels en vert et les points prévus en rouge.

Prévisions vs Réel

FAQ

Commencez par une fenêtre couvrant un cycle complet du motif, puis affinez-la. Des fenêtres plus longues capturent davantage de contexte, mais ralentissent l'entraînement et accentuent l'atténuation du gradient. Dix étapes suffisent pour la série journalière ; la saisonnalité hebdomadaire en nécessite généralement davantage.

Oui, avec un shim. Remplacez l'importation par tensorflow.compat.v1 et appelez disable_v2_behavior(), car les espaces réservés, les sessions et rnn_cell ont été déplacés sous l'espace de noms compat. TensorFlow Les projets devraient plutôt utiliser tf.keras.layers.SimpleRNN.

Les assistants IA suggèrent des tailles de fenêtre, repèrent les incohérences de forme avant l'exécution et génèrent un brouillon de code de chargement de données à partir d'un schéma. Ils raccourcissent le cycle d'essais et d'erreurs qui caractérise la modélisation récurrente, même si les choix définitifs d'hyperparamètres nécessitent toujours une validation sur des données de test.

Copilot gère efficacement les tâches répétitives : blocs de session, dictionnaires d’alimentation et impression périodique des pertes. La forme des tenseurs et le décalage des étiquettes restent les points critiques ; il est donc essentiel de toujours vérifier soi-même les dimensions des lots avant de se fier à une boucle générée.

Les couches récurrentes attendent un modèle de type (lot, pas de temps, caractéristique). Le redimensionnement en (-1, fenêtres, entrée) indique au système le nombre de séquences existantes, la profondeur de chaque séquence analysée et le nombre de valeurs reçues par pas. Une dimension manquante provoque une erreur de rang.

Le LSTM utilise trois portes logiques et un état de cellule distinct ; le GRU fusionne les portes d'oubli et d'entrée et supprime l'état de cellule. Le GRU s'entraîne plus rapidement avec moins de paramètres, tandis que le LSTM prend souvent l'avantage sur les dépendances très longues.

Les prévisions continues minimisent l'erreur quadratique moyenne, comme le montre cette démonstration avec la fonction `reduce_sum of squared residuals`. La classification de séquences, telle que l'étiquetage des sentiments ou les tâches d'analyse d'images abordées dans la section… CNN Ce tutoriel utilise à la place l'entropie croisée.

Les modèles Transformer dominent le traitement du langage naturel car l'attention est parallélisée tout au long d'une séquence. Les modèles récurrents restent compétitifs pour les flux de données, les prévisions univariées courtes et les appareils à faible mémoire, où le traitement étape par étape constitue un avantage plutôt qu'un goulot d'étranglement.

Résumez cet article avec :