Vous êtes sur la page 1sur 6

TP3 : CNN & RNN

16 Janvier 2022

Pour appliquer certaines techniques que nous avons vues jusqu’à présent, nous utiliserons un
ensemble de données sur la valeur du bitcoin en USD et le volume des transactions entre le 1er
janvier 2020 et le 19 avril 2021, les données sont collectées pour chaque minute entre ces deux dates,
de l’ouverture de la bourse à la fermeture. Nos objectifs seront de prédire le prix d’ouverture de la
monnaie en utilisant les données antérieures telles que le prix le plus élevé, le prix le plus bas, le prix
de clôture et le volume des transactions. Et aussi, de créer le modèle d’apprentissage le plus rapide
sans perte importante de précision.

Figure 1 – Les 5 premières lignes du jeu de données.

La configuration la plus adaptée à ce type de données est l’utilisation d’un réseau de neurones
récurrent, comme le montre la figure 2 qui représente le résultat d’un réseau GRU entraı̂né sur ces
données. Comme le temps d’exécution est important, nous allons essayer d’approcher la précision de ce
modèle par des techniques beaucoup moins coûteuses et de les comparer pour choisir la configuration
la plus appropriée.

Figure 2 – Résultat d’un réseau GRU entraı̂né sur ce jeu de données.

Avant de commencer à construire les modèles et l’entraı̂nement, nous devons préparer nos données.

Mehdi Bouskri 1 mehdi bouskri@um5.ac.ma


Nous allons importer quelques bibliothèques pour la préparation des données :
import pandas as pd

Nous allons utiliser Pandas pour manipuler nos données.


from sklearn . preprocessing import MinMaxScaler

Et MinMaxScaler de sklearn pour redimensionner notre jeu de données.

Nous allons lire les données comme un data frame :


import os
data_dir = ’/ Users / B . Mehdi / Desktop ’
fname = os . path . join ( data_dir , ’ g e m i n i _ B T C U S D _ 2 0 2 0 _ 1 m i n . csv ’)
data = pd . read_csv ( fname )

Ensuite, nous supprimerons les trois premières colonnes, car nous ne les utiliserons pas pour
l’apprentissage :
Data = data . iloc [ : ,3 : ]

Nous utiliserons MinMaxScaler pour redimensionner l’ensemble de données entre 0 et 1 :


scaler = MinMaxScaler () . fit ( Data )
Data = scaler . transform ( Data )

Afin d’utiliser les données préparées, nous devons créer un générateur de données, comme nous
l’avons fait pour l’ensemble de données météorologiques de Jena, ce générateur produira les entrées
qui seront le prix le plus élevé, le prix le plus bas, le prix de clôture et le volume des transactions et
les données cibles qui sont le prix d’ouverture :
def extract_data ( data , window , prediction , batch , step , min_index , max_index ,
shuffle ) :
if max_index is None :
max_index = len ( data ) - prediction - 1
i = min_index + window
while 1 :
if shuffle :
rows = np . random . randint ( min_index + window , max_index , size = batch )
else :
if i + batch > = max_index :
i = min_index + window
rows = np . arange (i , min ( i + batch , max_index ) )
i + = len ( rows )
samples = np . zeros (( len ( rows ) , window // step , 4 ) )
targets = np . zeros (( len ( rows ) ,) )
for j , row in enumerate ( rows ) :
indices = range ( rows [ j ] - window , rows [ j ] , step )
samples [ j ] = data [ indices , 1 : ]
targets [ j ] = data [ rows [ j ] + prediction , 1 ]
yield samples , targets

Mehdi Bouskri 2 mehdi bouskri@um5.ac.ma


Les variables utilisées par le générateur sont :

Window : combien de temps nous retournons dans les données, nous utiliserons 1440 ce qui
signifie 24 heures de données.

Prediction : à quand doit se situer notre prédiction, nous utiliserons 10, ce qui signifie que nous
allons prédire la valeur après 10 minutes des dernières données d’entrée.

Step : combien de points de données nous devrions utiliser, ce sera 1, donc on aura un point
chaque minute.

Batch : est la taille des données à générer à chaque époque.

Min index et max index : déterminent l’intervalle à partir duquel nos données seront prélevées.

Shuffle : sers à randomiser la génération des données.

Générateurs des données d’apprentissage et de validation :


window = 1440
prediction = 10
step = 1
batch = 128

train_gen = extract_data ( train , window = window ,


prediction = prediction , min_index = 200000 ,
max_index = 300000 , shuffle = True ,
step = step , batch = batch )
val_gen = extract_data ( train , window = window ,
prediction = prediction , min_index = 300001 ,
max_index = 400000 , shuffle = False ,
step = step , batch = batch )

Les résultats de la figure 2 ont été obtenus par le modèle suivant, avec un temps d’apprentissage
de 104 secondes par époque :
model = Sequential ()
model . add ( layers . GRU ( 32 ,
rec urrent _dropo ut = 0 . 25 ,
return_sequences = True ,
input_shape = ( None , 4 ) ) )
model . add ( layers . Dropout ( 0 . 5 ) )
model . add ( layers . GRU ( 32 ,
rec urrent _dropo ut = 0 . 25 ) )
model . add ( layers . Dropout ( 0 . 5 ) )
model . add ( layers . Dense ( 1 ) )

model . compile ( optimizer = ’ rmsprop ’ , loss = ’ mae ’)

history = model . fit_generator ( train_gen , steps_per_epoch = 40 , epochs = 20 ,


validation_data = val_gen , validation_steps = 40 )

Mehdi Bouskri 3 mehdi bouskri@um5.ac.ma


(Vous n’êtes pas censé exécuter le modèle ci-dessus)

Afin de réduire le temps d’apprentissage tout en maintenant une perte de validation comparable,
nous allons construire un modèle qui combine le modèle GRU ci-dessus et un réseau de convolution
unidimensionnel.

1. Créez un modèle avec les paramètres suivants :

— La première couche est un Conv1D avec 32 filtres, une fenêtre de convolution de taille 5 et
une fonction d’activation ReLu.
— La deuxième est un MaxPooling1d avec une fenêtre de taille 3.
— La troisième couche a les mêmes paramètres que la première.
— Et enfin ajoutez le réseau GRU utilisé ci-dessus.

2. Entraı̂nez le modèle créé pendant 20 époques, avec 40 étapes, et 40 étapes de validation, avec
la MAE comme fonction de perte.

Nous allons essayer une autre configuration avec plusieurs entrées et plusieurs branches de convo-
lution qui seront concaténées et transmises au réseau GRU. Notez que cette configuration n’est pas
une convolution séparable en profondeur, puisque nous utiliserons la même entrée pour toutes les
branches.

Vous pouvez vous référer à cet article [1] pour en savoir plus sur cette architecture. La différence
entre notre méthode et celle décrite dans l’article est que nous ne diviserons pas nos entrées et ne
passerons pas chaque caractéristique à une convolution spécifique, mais toutes les caractéristiques de
l’entrée seront utilisées conjointement pour chaque branche.

3. Créez le modèle présenté dans la figure 4, notez que nous utilisons toujours le même réseau
GRU.(La première couche de convolution de chaque branche a une fenêtre de taille 5. La deuxième
couche de convolution de chaque branche a une fenêtre de taille 7.)

4. Entraı̂nez le modèle avec les mêmes paramètres que précédemment.

5. ajouter une couche de Batchnormalization après la deuxième convolution de chaque branche


et entraı̂ner le modèle.

6. Comparez les résultats de tous les modèles créés avec le modèle purement RNN.

Les données de séries chronologiques ont tendance à être corrélées dans le temps, ce qui signifie
que l’indice au temps ”t+n” est très probablement proche de l’indice au temps ”t”, nous ne pouvons
pas savoir si notre modèle, lorsqu’il prédit la valeur au temps ”t+n”, utilise simplement la valeur
au temps ”t” comme prédiction. Ainsi, évaluer simplement les pouvoirs prédictifs des modèles en
calculant directement les mesures d’erreur peut être très trompeuses.

Nous allons transformer nos données en une série temporelle stationnaire où les propriétés sta-
tistiques des données, telles que la moyenne et la variance, sont toutes constantes dans le temps, et
cela se fait en calculant simplement la différence des valeurs en t+1 et t.

Mehdi Bouskri 4 mehdi bouskri@um5.ac.ma


def difference ( dataset , interval = 1 ) :
diff = [ ]
for i in range (1 , len ( dataset ) ) :
value = dataset [i , 0 ] - dataset [ i - interval , 0 ]
diff . append ( value )
return diff

(Notez que cette méthode permet de transformer la première colonne du data frame et renvoie
une liste, vous devez transformer toutes les colones et transformer le résultat en data frame pour
l’utiliser pour l’entraı̂nement.)

Après la transformation des données on peut visualiser la première colone :

(a) (b)

Figure 3 – (a) La première colonne avant la transformation.(b) La première colonne après la transforma-
tion.

7. Redimensionnez les données transformées en utilisant MinMaxscaler.

8. Utilisez le meilleur modèle que vous avez trouvé jusqu’à présent et entraı̂nez-le sur les données
transformées.

9. Comment se comporte votre modèle ?

Références

[1] M. Canizo, I. Triguero, A. Conde, and E. Onieva, “Multi-head cnn–rnn for multi-time series
anomaly detection : An industrial case study,” Neurocomputing, vol. 363, pp. 246–260, 2019.

Mehdi Bouskri 5 mehdi bouskri@um5.ac.ma


Figure 4 – Configuration d’un modèle avec multiple branche de convolution en plus d’un réseau GRU.

Mehdi Bouskri 6 mehdi bouskri@um5.ac.ma

Vous aimerez peut-être aussi