RDFIA TP4 : Apprentissage d`un réseau de convolution sur 15

Transcription

RDFIA TP4 : Apprentissage d`un réseau de convolution sur 15
RDFIA TP4 : Apprentissage d’un réseau de convolution
sur 15 Scene
Taylor Mordan, Thomas Robert, Matthieu Cord
30 novembre 2016 et 07 décembre 2016
Pour les TP sur les réseaux de neurones, vous devrez rendre :
— Un compte rendu à la fin de chaque séance (manuscrit ou par mail à taylor.mordan@
lip6.fr ou [email protected] selon votre encadrant de TP, les compte-rendus en
retard ne seront pas acceptés). Ce compte-rendu devra décrire le travail effectué pendant
la séance et les résultats importants obtenus.
— Un compte rendu global une semaine après la dernière séance (par mail), dont le but est
de reprendre au propre le travail effectué pendant l’intégralité des séances de TP, en
prenant du recul sur ce qui a été fait. Ce compte rendu représentera la majorité de la
note de TP.
Les données et une version numérique du sujet sont accessibles
à l’adresse http://webia.lip6.fr/~robert
1
Objectifs
Lors de ce TP, nous allons apprendre un petit réseau de convolution sur la base d’images 15
Scene, déjà utilisée au cours des TP précédents. Pour cela, nous spécifierons l’architecture du
réseau et effectuerons l’apprentissage et l’évaluation avec la bibliothèque MatConvNet. Nous
étudierons ensuite quelques techniques simples et très communes, mais néanmoins efficaces,
pour améliorer les performances du modèle. Enfin, dans une dernière partie, nous verrons
comment ré-utiliser le modèle CNN-F sur la base 15 Scene.
2
Apprentissage from scratch du modèle
Cette première partie se compose de plusieurs étapes décrites dans la suite : le chargement des
données, la définition de l’architecture et l’apprentissage. La première chose à faire est comme
toujours d’initialiser MatConvNet :
1 run / usr / local / matconvnet -1.0 - beta23 / matlab / vl_setupnn ;
1
RDFIA TP4 : Apprentissage d’un réseau de convolution sur 15 Scene
2.1
Chargement des données
La première étape consiste à charger et pré-traiter les images. Nous utiliserons le même découpage des données qu’au TP précédent, nous réutiliserons donc le fichier 15SceneSplit.mat
donnant les chemins des images d’apprentissage et de validation, ainsi que les classes vérités.
Le pré-traitement des images contient le passage en simple précision et le redimensionnement,
mais nous n’utiliserons pas de normalisation en moyenne pour l’instant. Pour accélérer l’apprentissage, nous redimensionnerons les images en 64 × 64 pixels, cela n’affectant que peu les
performances. L’apprentissage se fera avec une fonction, fournie avec MatConvNet, implémentant une descente de gradient. Il faut donc formater les données pour cette fonction avec la
structure imdb.images :
— les images seront stockées dans le champ imdb.images.data, initialisé par
1 imdb . images . data = zeros (64 , 64 , 1 , nImages , ' single ') ;
— les classes vérités seront stockées dans le champ imdb.images.labels, initialisé par
1 imdb . images . labels = zeros (1 , nImages , ' single ') ;
— un dernier champ imdb.images.set contiendra la valeur 1 pour indiquer les exemples
d’apprentissage et 2 pour ceux de validation, il sera initialisé par
1 imdb . images . set = zeros (1 , nImages , ' uint8 ') ; % train :1/ val :2
Questions
1. Expliquer de façon générale les différences entre les ensembles d’apprentissage, de validation et de test.
2. Pourquoi réduire les images en 64 × 64 pixels accélère l’apprentissage ?
2.2
Définition du réseau de convolution
Nous allons maintenant créer une architecture de réseau de convolution adaptée aux nouvelles
images. Nous utiliserons un petit réseau pour que le temps d’apprentissage ne soit pas trop
long, mais les réseaux sont généralement bien plus gros. Notre réseau sera composé des couches
suivantes :
1. conv1 : couche de convolution avec 10 filtres de taille 9 × 9, un stride de 1 et pas de
padding ;
2. pool1 : couche de max pooling sur des voisinages de taille 7 × 7, un stride de 7 et pas
de padding ;
3. relu1 : couche de fonction de transfert non-linéaire de type ReLU ;
4. fc2 : couche totalement connectée.
Nous stockerons le modèle dans une structure net, initialisée par
1 net . layers = {};
Chaque couche est ensuite ajoutée de la façon suivante :
2
RDFIA TP4 : Apprentissage d’un réseau de convolution sur 15 Scene
1 net . layers { end +1} = struct ( ' param1 ' , valeur1 , ...
2
' param2 ' , valeur2 , ...
3
...
4
' paramn ' , valeurn ) ;
Certains paramètres sont communs pour toutes les couches, ce sont name, qui attend une chaîne
de caractères correspondant au nom de la couche, et type, qui attend une chaîne de caractères
correspondant au type de la couche ('conv', 'pool' et 'relu' pour les couches nous concernant). Chaque type de couche possède également ses propres paramètres, qui sont :
— couche de convolution :
— weights : valeurs des matrices de poids et de biais (sous la forme {{W, B}}) ;
— stride : pas de la convolution ;
— pad : taille du padding ;
— couche de pooling :
— method : le type de pooling, ici 'max' ;
— pool : taille du voisinage (sous la forme [h w]) ;
— stride : pas du pooling ;
— pad : taille du padding ;
— couche ReLU : ne prend pas de paramètre supplémentaire.
La couche totalement connectée fc2 se définit comme une couche de convolution.
Les poids des couches conv1 et fc2, seront définis de la façon suivante :
1 ' weights ' , {{0.01* randn (h , w , n_in , n_out , ' single ') , zeros (1 ,
n_out , ' single ') }}
où il y a n_out filtres de tailles h × w sur n_in canaux d’entrée.
Nous rajouterons en plus une dernière couche pour implémenter la fonction de coût :
1 net . layers { end +1} = struct ( ' type ' , ' softmaxloss ') ;
Enfin, pour éviter tout problème de version, convertissez le réseau dans la bonne version avec
1 net = vl_simplenn_tidy ( net ) ;
Questions
1. Quelles sont les contraintes sur la taille de la couche fc2 ? En déduire les paramètres
pour l’instancier.
2. Combien le réseau contient-il de paramètres ? Comparer cela au nombre d’exemples.
3. Comment ce réseau se compare-t-il à CNN-F [1] ? Comparer le nombre de paramètres à
apprendre avec celui de l’approche BoW+SVM.
2.3
Apprentissage du réseau
L’apprentissage du modèle se fera avec la fonction cnn_train fournie dans MatConvNet. Cette
fonction implémente plusieurs algorithmes de descente de gradients et nous devons spécifier
certains paramètres. Cela se fera par l’intermédiaire de la variable opts dont nous définirons
les champs :
3
RDFIA TP4 : Apprentissage d’un réseau de convolution sur 15 Scene
— opts.batchSize la taille de mini-batch, que nous fixerons à 50 ;
— opts.learningRate le pas d’apprentissage, 0.0001 est une bonne valeur (vous pourrez
avoir besoin de changer cette valeur suivant les configurations) ;
— opts.numEpochs le nombre d’époques d’apprentissage, à régler en fonction du temps
d’apprentissage ;
— opts.expDir qui sera mis à 'exp/' ;
— opts.continue qui sera mis à false.
L’échantillonnage des exemples est géré de façon générique par une fonction à fournir en argument à cnn_train. Nous utiliserons la fonction suivante :
1 function [ im , labels ] = getBatch ( imdb , batch )
2 % S é lection des images et des classes v é rit é s ind é x é es par batch
3
im = imdb . images . data (: ,: ,: , batch ) ;
4
labels = imdb . images . labels (1 , batch ) ;
5 end
Enfin, l’apprentissage est réalisé par l’appel à cnn_train :
1 % Train and test
2 [ net , info ] = cnn_train ( net , imdb , @ getBatch , ...
3
opts , ...
4
' val ' , find ( imdb . images . set == 2) ) ;
La variable net contiendra maintenant le modèle appris et info des données sur le déroulement
de l’apprentissage. En particulier nous nous intéresserons à la précision top-1 sur l’ensemble
de validation (les valeurs reportées dans info sont les erreurs top-1), en reportant la meilleure
précision au cours des époques.
Questions
1. Rappeler le principe de l’algorithme de backpropagation.
2. Quels sont les effets du pas d’apprentissage (learning rate) et de la taille de mini-batch ?
3. Quelle est l’erreur à la première époque ? Comment s’interprète-t-elle ?
4. Interpréter les résultats. Qu’est-ce qui ne va pas ? Quel est ce phénomène et comment le
mettre en évidence ?
3
Améliorations des résultats
Nous allons maintenant voir trois techniques classiques pour améliorer les performances de
notre modèle. Les deux premières ne sont pas spécifiques aux réseaux de neurones et peuvent
être utilisées avec n’importe quel algorithme d’apprentissage.
3.1
Augmentation du nombre d’exemples d’apprentissage par data augmentation
Les réseaux de convolutions contiennent habituellment plusieurs millions de paramètres et sont
appris sur de très grosses bases d’images. Même si notre réseaux n’en contient pas autant,
4
RDFIA TP4 : Apprentissage d’un réseau de convolution sur 15 Scene
l’ensemble d’apprentissage de 15 Scene ne compte que peu d’images, bien moins que le nombre
de paramètres du modèle. Il n’est pas étonnant dans ce cas que l’apprentissage ne donne pas de
très bons résultats. Les méthodes de data augmentation cherchent à artificiellement augmenter
le nombre d’exemples disponibles, ce qui peut être crucial quand l’ensemble d’apprentissage est
petit.
Nous proposons d’implémenter cela par symétrie horizontale sur les images. Pour cela, modifier
la fonction getBatch pour qu’elle applique cette symétrie de façon aléatoire sur les exemples de
chaque mini-batch, avec une probabilité 0.5 pour chaque image. Les fonctions MATLAB rand
et fliplr seront utiles.
Relancer l’apprentissage avec cet ajout ; la précision top-1 devrait augmenter de 10%.
Questions
1. En comptant les exemples originaux et les nouveaux générés, combien l’ensemble d’apprentissage contient-il d’exemples maintenant ? Comment cela se compare-t-il au cas où
il y aurait autant d’exemples, mais que des originaux ?
2. Comparer l’évolution de l’erreur d’apprentissage avec le cas précédent (sans data augmentation). Que cela signifie-t-il ?
3. Est-ce que cette approche par symétrie horizontale vous semble utilisable sur tout type
d’images ? Dans quels cas peut-elle l’être ou ne pas l’être ?
Bonus La symétrie horizontale n’est pas le seul moyen de créer de nouveaux exemples d’apprentissage. Proposer de nouvelles approches et les tester. Pour chaque méthode, donner au
moins :
1. Le nombre de nouveaux exemples qu’elle apporte ;
2. La comparaison avec la symétrie horizontale en termes de taux de bonne classification ;
3. La complémentarité avec la symétrie horizontale et les autres approches proposées (est-il
utile de les combiner ?).
3.2
Normalisation des exemples d’apprentissage
Une astuce courante en Machine Learning est de normaliser les exemples afin de mieux conditionner l’apprentissage. Pour cela, modifier la génération des ensembles d’apprentissage et de
validation en calculant l’image moyenne sur tous les exemples d’apprentissage et en la soustrayant aux images.
Avec cette normalisation, la précision top-1 devrait encore augmenter de 15%.
Questions
1. Quel est l’effet de la normalisation des images sur l’apprentissage ?
2. Pourquoi ne calculer l’image moyenne que sur les exemples d’apprentissage et normaliser
les exemples de validation avec la même image ?
3. Quelle était l’étape correspondante avec CNN-F ?
5
RDFIA TP4 : Apprentissage d’un réseau de convolution sur 15 Scene
Bonus Il existe d’autres schémas de normalisation qui peuvent etre plus efficaces, comme par
exemple la normalisation en moyenne et écart-type, la normalisation ZCA. Essayer d’autres
méthodes, expliquer les différences et comparer les à celle demandée.
3.3
Régularisation du réseau par dropout
Le modèle n’était jusqu’ici que très peu régularisé, et le risque de sur-apprentissage n’était
donc pas négligeable. Pour remédier à cela, nous allons ajouter une couche permettant une
régularisation très efficace pour les réseaux de neurones : la couche de dropout. Toutes les
informations nécessaires sur cette couche se trouvent dans l’article correspondant [2].
Ajouter une couche de dropout dans le réseau pour le régulariser, juste avant la couche totalement connectée. Ce type de couche n’a besoin que de deux paramètres pour être défini, dont
l’un est un hyper-paramètre à choisir (que nous laisserons à sa valeur standard 0.5) :
— Le paramètre type avec pour valeur 'dropout' ;
— Le paramètre rate avec pour valeur 0.5.
Relancer l’apprentissage avec un peu plus d’époques (et en diminuant éventuellement le learning
rate). Le modèle devrait maintenant atteindre 60% de bonne classification.
Questions
1. Quel est l’intérêt de la régularisation ? Quel est son effet sur l’apprentissage ?
2. Quelle autre régularisation était déjà utilisée (implicitement par cnn_train) dans les
questions précédentes ? Quel est son fonctionnement ?
3. Rappeler le principe de dropout. Quelles sont les interprétations de son efficacité ?
4. Quelle est l’influence de l’hyper-paramètre rate ?
5. Quel est l’effet de la couche de dropout sur la courbe d’erreur ?
6. Quelle est la différence de comportement de la couche de dropout entre l’apprentissage
et l’inférence ?
Références
[1] Ken Chatfield, Karen Simonyan, Andrea Vedaldi, and Andrew Zisserman. Return of the
devil in the details : Delving deep into convolutional nets. In Proceedings of the British
Machine Vision Conference (BMVC), 2014.
[2] Nitish Srivastava, Geoffrey E Hinton, Alex Krizhevsky, Ilya Sutskever, and Ruslan Salakhutdinov. Dropout : a simple way to prevent neural networks from overfitting. Journal of
Machine Learning Research (JMLR), 15(1) :1929–1958, 2014.
6