Contenu principal

Entraîner un réseau de neurones à convolution pour la régression

Cet exemple indique comment entraîner un réseau de neurones à convolution afin de prédire les angles de rotation des chiffres écrits à la main.

Les tâches de régression impliquent la prédiction de valeurs numériques continues au lieu d'étiquettes de classe discrètes. Cet exemple crée une architecture de réseau de neurones à convolution pour la régression, entraîne le réseau et utilise le réseau entraîné pour prédire les angles des chiffres écrits à la main après rotation.

Ce schéma suivant illustre le flux de données d’image dans un réseau de neurones de régression.

Charger les données

L'ensemble de données contient des images synthétiques de chiffres écrits à la main, ainsi que les angles de rotation (en degrés) correspondants appliqués à chaque image.

Chargez respectivement les données d’apprentissage et de test à partir des fichiers MAT DigitsDataTrain.mat et DigitsDataTest.mat. Les variables anglesTrain et anglesTest correspondent aux angles de rotation en degrés. Les jeux de données d’apprentissage et de test contiennent 5 000 images chacun.

load DigitsDataTrain
load DigitsDataTest

Affichez certaines images d’apprentissage.

numObservations = size(XTrain,4);
idx = randperm(numObservations,49);
I = imtile(XTrain(:,:,:,idx));
figure
imshow(I);

Figure contains an axes object. The hidden axes object contains an object of type image.

Partitionnez XTrain et anglesTrain entre les partitions d'apprentissage et de validation avec la fonction trainingPartitions jointe à cet exemple comme fichier de support. Pour accéder à cette fonction, ouvrez l’exemple en tant que live script. Réservez 15 % des données d’apprentissage pour la validation.

[idxTrain,idxValidation] = trainingPartitions(numObservations,[0.85 0.15]);

XValidation = XTrain(:,:,:,idxValidation);
anglesValidation = anglesTrain(idxValidation);

XTrain = XTrain(:,:,:,idxTrain);
anglesTrain = anglesTrain(idxTrain);

Vérifier la normalisation des données

Lors de l‘apprentissage des réseaux de neurones, il est souvent utile de s'assurer que vos données sont normalisées à toutes les étapes du réseau. La normalisation aide à stabiliser et à accélérer l'apprentissage du réseau par une descente de gradient. Si vos données ne sont pas mises à l’échelle correctement, la perte peut devenir NaN et les paramètres du réseau peuvent diverger au cours de l’apprentissage. Parmi les méthodes courantes de normalisation des données, citons le changement d'échelle des données afin que leur plage devienne [0,1] ou qu'elles aient une moyenne de zéro et un écart type de un. Vous pouvez normaliser les données suivantes :

  • Données en entrée. Normalisez les prédicteurs avant de les entrer dans le réseau. Dans cet exemple, les images en entrée sont déjà normalisées pour la plage [0,1].

  • Sorties des couches. Vous pouvez normaliser les sorties de chaque couche de convolution entièrement connectée en utilisant une couche de normalisation par batch.

  • Réponses. Si vous utilisez des couches de normalisation par batch pour normaliser les sorties des couches à la fin du réseau, les prédictions du réseau sont normalisées au début de l'apprentissage. Si la réponse présente une échelle très différente de ces prédictions, la convergence de l’apprentissage du réseau peut échouer. Si la mise à l’échelle de votre réponse est incorrecte, tentez de la normaliser et voyez si l'apprentissage du réseau s'améliore. Si vous normalisez la réponse avant l'apprentissage, vous devez transformer les prédictions du réseau entraîné afin d’obtenir les prédictions de la réponse d’origine.

Tracez la distribution de la réponse. La réponse (angle de rotation en degrés) est distribuée de manière quasiment uniforme entre -45 et 45, ce qui fonctionne bien sans nécessiter de normalisation. Dans les problèmes de classification, les sorties sont des probabilités de classe toujours normalisées.

figure
histogram(anglesTrain)
axis tight
ylabel("Counts")
xlabel("Rotation Angle")

Figure contains an axes object. The axes object with xlabel Rotation Angle, ylabel Counts contains an object of type histogram.

En règle générale, les données n’ont pas besoin d’être normalisées avec précision. Toutefois, si vous entraînez le réseau dans cet exemple pour prédire 100*anglesTrain ou anglesTrain+500 plutôt que anglesTrain, la perte devient NaN et les paramètres du réseau divergent au début de l'apprentissage. Ces résultats se produisent même si la seule différence entre un réseau prédisant aY+b et un réseau prédisant Y est un simple changement d’échelle des poids et biais de la dernière couche entièrement connectée.

Si la distribution de l'entrée ou de la réponse est très inégale ou asymétrique, vous pouvez également réaliser des transformations non linéaires (par exemple, prendre les logarithmes) sur les données avant d'entraîner le réseau.

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

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

  • Pour les images en entrée, spécifiez une couche d'entrée pour les images.

  • Spécifier quatre blocs de convolution-batchnorm-ReLU avec un nombre croissant de filtres.

  • Entre chaque bloc, spécifiez une couche de pooling moyen avec des régions de pooling et un pas de taille 2.

  • À la fin du réseau, ajoutez une couche entièrement connectée avec une taille en sortie correspondant au nombre de réponses.

numResponses = 1;

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

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.

  • Définissez le taux d'apprentissage initial à 0,001 et réduisez le taux d'apprentissage après 20 epochs.

  • Surveillez la précision du réseau pendant l’apprentissage en spécifiant des données de validation et une fréquence de validation. Le software entraîne le réseau 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.

  • Affichez la progression de l’apprentissage dans un tracé et surveillez la racine de l’erreur quadratique moyenne.

  • Désactivez la sortie en clair.

miniBatchSize  = 128;
validationFrequency = floor(numel(anglesTrain)/miniBatchSize);

options = trainingOptions("sgdm", ...
    MiniBatchSize=miniBatchSize, ...
    InitialLearnRate=1e-3, ...
    LearnRateSchedule="piecewise", ...
    LearnRateDropFactor=0.1, ...
    LearnRateDropPeriod=20, ...
    Shuffle="every-epoch", ...
    ValidationData={XValidation,anglesValidation}, ...
    ValidationFrequency=validationFrequency, ...
    Plots="training-progress", ...
    Metrics="rmse", ...
    Verbose=false);

Entraîner le réseau de neurones

Entraînez le réseau de neurones avec la fonction trainnet. Pour la régression, utilisez la perte d’erreur quadratique moyenne. Par défaut et selon disponibilité, la fonction trainnet utilise un GPU. L’utilisation d’un GPU nécessite une licence Parallel Computing Toolbox™ et un dispositif GPU supporté. Pour plus d'information sur les dispositifs supportés, veuillez consulter Exigences de calcul du GPU (Parallel Computing Toolbox). Sinon, la fonction utilise le CPU. Pour spécifier l’environnement d’exécution, utilisez l’option d’apprentissage ExecutionEnvironment.

net = trainnet(XTrain,anglesTrain,layers,"mse",options);

Tester le réseau

Testez le réseau de neurones en utilisant la fonction testnet. Pour la régression, évaluez la racine de l’erreur quadratique moyenne (RMSE, Root Mean Squared Error). Par défaut et selon disponibilité, la fonction testnet utilise un GPU. Pour sélectionner manuellement l’environnement d’exécution, utilisez l’argument ExecutionEnvironment de la fonction testnet.

rmse = testnet(net,XTest,anglesTest,"rmse")
rmse = 
4.9079

Visualisez la précision dans un tracé en faisant des prédictions avec les données de test et en comparant les prédictions aux cibles. Réalisez des prédictions avec la fonction minibatchpredict. Par défaut et selon disponibilité, la fonction minibatchpredict utilise un GPU.

YTest = minibatchpredict(net,XTest);

Tracez les valeurs prédites par rapport aux cibles.

figure
scatter(YTest,anglesTest,"+")
xlabel("Prediction")
ylabel("Target")

hold on
plot([-60 60], [-60 60],"r--")

Figure contains an axes object. The axes object with xlabel Prediction, ylabel Target contains 2 objects of type scatter, line.

Faire des prédictions avec de nouvelles données

Utilisez le réseau de neurones pour faire une prédiction avec la première image test. Pour faire une prédiction avec une seule image, utilisez la fonction predict. Pour utiliser un GPU, commencez par convertir les données en gpuArray.

X = XTest(:,:,:,1);
if canUseGPU
    X = gpuArray(X);
end
Y = predict(net,X)
Y = single

39.6617
figure
imshow(X)
title("Angle: " + gather(Y))

Figure contains an axes object. The hidden axes object with title Angle: 39.6617 contains an object of type image.

Voir aussi

| |

Rubriques