Université Cadi Ayyad Licence, 3IASD
Ecole Supérieure de 2024 – 2025
Technologie Essaouira Semestre 6
DEEP LEARNING
TD 3: RESEAUX DE NEURONES CONVOLUTIFS
EXERCICE 1 :
1. Entrainer le réseau de neurones convolutifs suivant pour prédire l’objet sur les
images CIFAR10 :
Extracteur de caractéristiques :
• Une seule couche de convolutions ayant 32 filtres.
• Fonction d’activation : ReLU
• Max Pooling de taille 2 pour réduire la dimensionnalité
Classificateur :
• Couche complétement connectée de 64 neurones activée par ReLU
• Couche finale pour prédire le nombre sur l’image.
2. Entraîner un deuxième modèle qui se compose de 5 couches de convolutions (conv,
batchnorm, activation, maxpooling) de filtres 32, 64, 128, 256 et 512, suivies d’un
classificateur se composant de 3 couches complétement connectées de 1024, 512
puis la couche finale.
3. Comparer les résultats des deux modèles, a-t-on underfitting ? overfitting ?
4. Proposer alors un modèle qui réalise un fitting mieux que les deux modèles
précédents en ajustant la complexité de l’architecture et en utilisant la
régularisation.
EXERCICE 2 :
1. Construire un réseau de neurones convolutif de 8 couches de convolutions :
a. Chaque couche a 32 filtres.
b. L’activation est sigmoid.
c. Le pooling est appliqué seulement pour les deux premières couches.
2. Entraîner ce modèle sur le dataset cifar10.
3. Que peut-on dire sur sa performance ?
4. Changer l’activation sigmoid en ReLU ou l’une de ses variantes, puis ré-
entrainer le modèle et visualiser les gradients encore.
5. Modifier l’architecture du modèle en utilisant les blocs résiduels afin de
résoudre le problème des vanishing gradients.
EXERCICE 3 :
Pour calculer le gradient d’une fonction sur tensorflow, on peut utiliser la fonction
"tf.GradientTape" comme suit :
X = tf.Variable(valeur de x)
With tf.GradientTape() as tape :
Function = expression en function de x
dFunction _sur_dX = tape.gradient(Function, X)
#on peut l’afficher par :
Print("derivee de f par rapport à x : ", dFunction _sur_dX.numpy())
1. Calculer et afficher le gradient de la fonction f(x)=x^3 – 3x^2 + x -1 par
rapport à la variable x=1.
2. Calculer et afficher le gradient de la même fonction de la question 1 par
rapport aux variable x=1, 2, 3.
3. Calculer et afficher le gradient de la fonction f(x, y)=x^2 – 3y^2 + 4x par
rapport aux variable x=1 et y=-1.
4. Calculer et afficher la dérivée seconde de la fonction f(x)=x^3 – 3x^2 + x -1
par rapport à la variable x=1.
5. Dans le contexte des ANN :
5.1. Définir une fonction : Y = W.X + B, où X représentent les neurones d’une
certaine couche, B le biais, et W la matrice des poids. Y contient les
neurones résultants.
5.2. Définir un vecteur Y_true et considérer la fonction loss = erreur
quadratique, puis calculer Y et la loss.
5.3. Calculer puis afficher le gradient de la loss par rapport à W et B
6. Avec la fonction "open" et "write", on peut ouvrir un fichier et écrire dedans.
Par exemple :
With open(chemin_du_fichier, "a") as file :
file.write("Hello world !")
Utiliser cette fonction pour écrire le gradient de la question 5.3 sur un fichier
nommé gradients.txt
7. Définir une classe my_callback pour définir un callback qui s’exécute à la fin
de chaque epoch en utilisant la fonction on_epoch_end :
class GradLogger(Callback):
def __init__(self, model, x_trn, y_trn, file_path='./gradients_log.txt'):
super(GradLogger, self).__init__()
#on définit ici les attributs de la classe
def on_epoch_end(self, epoch, logs=None):
#écrire le code pour calculer le gradient de la loss en fonction
#des poids du modèles, on trouve les poids dans la varibale
#self.model.trainable_variables, et on calcule la loss par la
#fonction : self.model.compiled_loss
with open(self.file_path, 'a') as f:
f.write(f'\nEpoch {epoch + 1}\n')
f.write('======================================\n')
for var, grad in zip(self.model.trainable_variables, gradients):
if grad is not None:
f.write(f'Variable: {var.name}\n')
f.write(f' Shape: {grad.shape}\n')
f.write(f' Mean: {tf.reduce_mean(grad).numpy()}\n')
f.write(f' Std: {tf.math.reduce_std(grad).numpy()}\n')
f.write(f' Min: {tf.reduce_min(grad).numpy()}\n')
f.write(f' Max: {tf.reduce_max(grad).numpy()}\n')
f.write('---------------------------\n')
8. Utiliser le callback définit dans la question précédente afin de suivre
l’évolution des gradients avant et après avoir introduit le bloc résiduel dans
le model.