Main Content

Créer un réseau de neurones simple de Deep Learning pour la classification

Cet exemple montre comment créer et entraîner un réseau de neurones à convolution simple pour la classification Deep Learning.

Les réseaux de neurones à convolution sont des outils essentiels pour le Deep Learning et conviennent parfaitement à la reconnaissance d'images.

Cet exemple illustre comment :

  • Charger et explorer des images.

  • Définir l’architecture du réseau de neurones.

  • Spécifier les options d’apprentissage.

  • Entraîner le réseau de neurones.

  • Prédire les étiquettes des nouvelles données et calculer la précision de la classification.

Vous trouverez un exemple illustrant comment créer et entraîner de manière interactive un réseau de neurones simple pour la classification d’images dans Démarrer avec la classification d’images.

Charger et explorer des images

Chargez les données numériques sous la forme d’un datastore d’images avec la fonction imageDatastore et spécifiez le dossier contenant les images. Un datastore d’images vous permet de stocker de grandes images, notamment des données qui ne peuvent pas être stockées en mémoire, et de lire efficacement des images en batch pendant l’apprentissage d’un réseau de neurones à convolution.

unzip("DigitsData.zip");
dataFolder = "DigitsData";
imds = imageDatastore(dataFolder, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");

Affichez certaines images dans le datastore.

figure
tiledlayout("flow");
perm = randperm(10000,20);
for i = 1:20
    nexttile
    imshow(imds.Files{perm(i)});
end

Calculez le nombre d’images dans chaque catégorie. labelCount est une table contenant les étiquettes et le nombre d’images correspondant à chaque étiquette. Le datastore contient 1 000 images pour chaque chiffre de 0 à 9, soit un total de 10 000 images. Vous pouvez spécifier le nombre de classes dans la dernière couche entièrement connectée de votre réseau de neurones avec l’argument OutputSize.

classNames = categories(imds.Labels);
labelCount = countEachLabel(imds)
labelCount=10×2 table
    Label    Count
    _____    _____

      0      1000 
      1      1000 
      2      1000 
      3      1000 
      4      1000 
      5      1000 
      6      1000 
      7      1000 
      8      1000 
      9      1000 

Vous devez spécifier la taille des images dans la couche d’entrée du réseau de neurones. Vérifiez la taille de la première image dans digitData. Chaque image est de taille 28 x 28 x 1 pixels.

img = readimage(imds,1);
size(img)
ans = 1×2

    28    28

Spécifier les jeux d’apprentissage et de validation

Divisez les données en jeux de données d’apprentissage et de validation de sorte que chaque catégorie dans le jeu d’apprentissage contienne 750 images et que le jeu de validation contienne les images restantes pour chaque étiquette. splitEachLabel divise le datastore imds en deux nouveaux datastores imdsTrain et imdsValidation.

numTrainFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,"randomize");

Définir l’architecture du réseau de neurones

Définissez l’architecture du réseau de neurones à convolution.

layers = [
    imageInputLayer([28 28 1])
    
    convolution2dLayer(3,8,Padding="same")
    batchNormalizationLayer
    reluLayer
    
    maxPooling2dLayer(2,Stride=2)
    
    convolution2dLayer(3,16,Padding="same")
    batchNormalizationLayer
    reluLayer
    
    maxPooling2dLayer(2,Stride=2)
    
    convolution2dLayer(3,32,Padding="same")
    batchNormalizationLayer
    reluLayer
    
    fullyConnectedLayer(10)
    softmaxLayer];

Couche d’entrée des images Un imageInputLayer vous permet de spécifier la taille des images qui est, dans ce cas, 28 x 28 x 1. Ces nombres correspondent à la hauteur, la largeur et la taille du canal. Les données numériques se composent d’images en niveaux de gris, donc la taille du canal (canal de couleur) est égale à 1. Pour une image en couleur, la taille du canal est égale à 3, ce qui correspond aux valeurs RGB. Vous n’avez pas besoin de mélanger les données, car trainnet, par défaut, mélange les données au début de l’apprentissage. trainnet peut également mélanger automatiquement les données au début de chaque epoch pendant l’apprentissage.

Couche de convolution Dans la couche de convolution, le premier argument est filterSize, qui correspond à la hauteur et la largeur des filtres utilisés par la fonction d’apprentissage lors du balayage des images. Dans cet exemple, le nombre 3 indique que la taille du filtre est 3 x 3. Vous pouvez spécifier des tailles différentes pour la hauteur et la largeur du filtre. Le deuxième argument est le nombre de filtres, numFilters, qui correspond au nombre de neurones qui se connectent à la même région de l’entrée. Ce paramètre détermine le nombre de cartes des fonctionnalités. Utilisez l’argument de type nom-valeur Padding pour réaliser le remplissage (padding) sur l’objet Map des caractéristiques, donné en entrée. Pour une couche de convolution avec un pas par défaut de 1, le remplissage "same" garantit que la taille spatiale en sortie est la même que la taille en entrée. Vous pouvez également définir le pas et les taux d’apprentissage pour cette couche avec les arguments de type nom-valeur de convolution2dLayer.

Couche de normalisation par batch Les couches de normalisation par batch normalisent les activations et les gradients se propageant dans un réseau de neurones, ce qui facilite le problème d’optimisation de l’apprentissage du réseau. Utilisez des couches de normalisation par batch entre des couches de convolution et des non-linéarités, comme des couches ReLU, pour accélérer l’apprentissage du réseau de neurones et réduire la sensibilité à l’initialisation du réseau. Utilisez batchNormalizationLayer pour créer une couche de normalisation par batch.

Couche ReLU La couche de normalisation par batch est suivie par une fonction d’activation non linéaire. La fonction d’activation la plus courante est l’unité linéaire rectifiée (ReLU). Utilisez reluLayer pour créer une couche ReLU.

Couche de max pooling Les couches de convolution (avec fonctions d’activation) sont parfois suivies par une opération de sous-échantillonnage qui réduit la taille spatiale de l'objet Map des caractéristiques et supprime les informations spatiales redondantes. Le sous-échantillonnage permet d’augmenter le nombre de filtres dans les couches de convolution plus profondes sans augmenter la quantité de calculs nécessaire par couche. Une des méthodes de sous-échantillonnage est l’utilisation d’un max pooling, que vous créez avec maxPooling2dLayer. La couche de max pooling renvoie les valeurs maximales des régions rectangulaires des entrées, spécifiées par le premier argument, poolSize. Dans cet exemple, la taille de la région rectangulaire est [2,2]. L’argument de type nom-valeur Stride spécifie la taille du pas que la fonction d’apprentissage utilise lors du parcours des données en entrée.

Couche entièrement connectée Les couches de convolution et de sous-échantillonnage sont suivies par une ou plusieurs couches entièrement connectées. Comme son nom l’indique, une couche entièrement connectée est une couche dans laquelle les neurones se connectent à tous les neurones de la couche précédente. Cette couche combine toutes les caractéristiques apprises par les couches précédentes sur l’image pour identifier les plus grands motifs (patterns). La couche entièrement connectée combine les caractéristiques pour classer les images. Ainsi, le paramètre OutputSize dans la dernière couche entièrement connectée est égal au nombre de classes dans les données cibles. Dans cet exemple, la taille en sortie est égale à 10, ce qui correspond aux 10 classes. Utilisez fullyConnectedLayer pour créer une couche entièrement connectée.

Couche softmax La fonction d’activation softmax normalise la sortie de la couche entièrement connectée. La sortie de la couche softmax se compose de nombres positifs dont la somme est égale à un et qui peuvent ensuite être utilisés comme probabilités de classification par la couche de classification. Créez une couche softmax avec la fonction softmaxLayer après la dernière couche entièrement connectée.

Spécifier les options d’apprentissage

Spécifiez les options d’apprentissage. Le choix des options nécessite une analyse empirique. Pour explorer différentes configurations dans les options d’apprentissage au cours de vos expérimentations, vous pouvez utiliser l’application Experiment Manager.

  • Entraînez le réseau de neurones avec une descente de gradient stochastique avec moment (SGDM) utilisant un taux d’apprentissage initial de 0,01.

  • Définissez le nombre maximal d’epochs à 4. Un epoch est un cycle d’apprentissage complet sur l’ensemble du jeu de données d’apprentissage.

  • Mélangez les données à chaque epoch.

  • Surveillez la précision du réseau de neurones pendant l’apprentissage en spécifiant les données de validation et une fréquence de validation. Le software entraîne le réseau de neurones sur les données d’apprentissage et calcule la précision sur les données de validation à intervalles réguliers pendant l’apprentissage. Les données de validation ne sont pas utilisées pour mettre à jour les poids du réseau de neurones.

  • Affichez la progression de l’apprentissage dans un tracé et surveillez la précision.

  • Désactivez la sortie en clair.

options = trainingOptions("sgdm", ...
    InitialLearnRate=0.01, ...
    MaxEpochs=4, ...
    Shuffle="every-epoch", ...
    ValidationData=imdsValidation, ...
    ValidationFrequency=30, ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

Entraîner le réseau de neurones avec des données d’apprentissage

Entraînez le réseau de neurones avec l’architecture définie par layers, les données d’apprentissage et les options d’apprentissage. Par défaut et selon disponibilité, trainnet utilise un GPU. Sinon, il utilise un CPU. L’apprentissage sur un GPU nécessite Parallel Computing Toolbox™ et un dispositif GPU supporté. Pour plus d'information sur les dispositifs supportés, veuillez consulter GPU Computing Requirements (Parallel Computing Toolbox). Vous pouvez également spécifier l’environnement d’exécution avec l’argument de type nom-valeur ExecutionEnvironment dans trainingOptions.

Le tracé de la progression de l’apprentissage montre la perte (loss) et la précision des mini-batchs, ainsi que la perte (loss) et la précision de la validation. Pour plus d’informations sur le tracé de la progression de l’apprentissage, veuillez consulter Surveiller la progression de l'apprentissage du Deep Learning. La perte (loss) est la perte d’entropie croisée. La précision est le pourcentage d’images que le réseau de neurones classe correctement.

net = trainnet(imdsTrain,layers,"crossentropy",options);

Classer les images de validation et calculer la précision

Classez les images de test. Pour réaliser des prédictions avec plusieurs observations, utilisez la fonction minibatchpredict. Pour convertir les scores de prédiction en étiquettes, utilisez la fonction scores2label. La fonction minibatchpredict utilise automatiquement un GPU si disponible. Sinon, la fonction utilise le CPU.

scores = minibatchpredict(net,imdsValidation);
YValidation = scores2label(scores,classNames);

Calculez la précision de la classification. La précision est le pourcentage d’étiquettes correctement prédites.

TValidation = imdsValidation.Labels;
accuracy = mean(YValidation == TValidation)
accuracy = 0.9928

Voir aussi

| | | |

Sujets associés