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.
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.
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.
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.
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()
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 :
- La variable avec les tenseurs
- Le RNN
- 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()
Prรฉvisions vs Rรฉel





