La traduction de cette page n'est pas à jour. Cliquez ici pour voir la dernière version en anglais.
Préparer un réseau pour l’apprentissage par transfert au moyen de Deep Network Designer
Cet exemple montre comment préparer de manière interactive un réseau pour l’apprentissage par transfert au moyen de l'application Deep Network Designer.
L’apprentissage par transfert consiste à prendre un réseau de Deep Learning préentraîné et à l’ajuster précisément pour apprendre une nouvelle tâche. L’apprentissage par transfert est généralement plus rapide et plus facile que l’apprentissage d’un réseau à partir de zéro. Vous pouvez transférer rapidement les caractéristiques apprises vers une nouvelle tâche avec une plus petite quantité de données.
Extraire des données
Extrayez le jeu de données MathWorks Merch. Il s’agit d’un petit jeu de données contenant 75 images de marchandises MathWorks parmi cinq catégories différentes (casquette, cube, cartes à jouer, tournevis et lampe de poche). Les données sont organisées de telle sorte que les images se trouvent dans des sous-dossiers correspondant à ces cinq classes.
folderName = "MerchData"; unzip("MerchData.zip",folderName);
Créez un datastore d’images. Un datastore d’images vous permet de stocker de grandes collections d’images, notamment des données qui ne peuvent pas être stockées en mémoire, et de lire efficacement ces images en batch pendant l’apprentissage d’un réseau de neurones. Spécifiez le dossier contenant les images extraites et indiquez que les noms des sous-dossiers correspondent aux étiquettes d’images.
imds = imageDatastore(folderName, ... IncludeSubfolders=true, ... LabelSource="foldernames");
Affichez quelques exemples d’images.
numImages = numel(imds.Labels); idx = randperm(numImages,16); I = imtile(imds,Frames=idx); figure imshow(I)
Récupérez les noms des classes et le nombre de classes.
classNames = categories(imds.Labels); numClasses = numel(classNames)
numClasses = 5
Partitionnez les données entre des jeux de données d’apprentissage, de validation et de test. Utilisez 70 % des images pour l’apprentissage, 15 % pour la validation et 15 % pour les tests. La fonction splitEachLabel
divise le datastore d’images en deux nouveaux datastores.
[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.7,0.15,0.15,"randomized");
Sélectionner un réseau préentraîné
Pour ouvrir le Deep Network Designer, dans l’onglet Apps, dans la section Machine Learning and Deep Learning, cliquez sur l’icône de l’application. Vous pouvez également ouvrir l’application à partir de la ligne de commande :
deepNetworkDesigner
Deep Network Designer propose un ensemble de réseaux de classification d’images préentraînés qui ont appris des représentations avec de nombreuses caractéristiques convenant à une grande variété d’images. L'apprentissage par transfert fonctionne mieux si vos images sont similaires à celles utilisées au départ pour entraîner le réseau. Si vos images d'apprentissage sont des images naturelles comme celles de la base de données ImageNet, n'importe quel réseau préentraîné convient. Pour obtenir la liste des réseaux disponibles et savoir comment les comparer, veuillez consulter Pretrained Deep Neural Networks.
Si vos données sont très différentes de celles d'ImageNet, par exemple, si vous avez des images minuscules, des spectrogrammes ou des données qui ne sont pas des images, il peut être préférable d'entraîner un nouveau réseau. Vous trouverez un exemple illustrant comment entraîner un réseau à partir de zéro dans Get Started with Time Series Forecasting.
SqueezeNet ne nécessite pas de Support Package supplémentaire. Pour les autres réseaux préentraînés, si le Support Package requis n’est pas installé, l’application propose l’option Install.
Sélectionnez SqueezeNet depuis la liste des réseaux préentraînés et cliquez sur Open.
Explorer un réseau
Deep Network Designer affiche une vue dézoomée de l’ensemble du réseau dans le volet Designer.
Explorez la représentation du réseau. Pour zoomer avec la souris, utilisez Ctrl+ la roulette de défilement de la souris (scroll wheel). Pour vous déplacer dans l’image, utilisez les touches fléchées ou maintenez la roulette de défilement de la souris enfoncée et déplacez la souris. Sélectionnez une couche pour afficher ses propriétés. Désélectionnez toutes les couches pour afficher le résumé du réseau dans le volet Properties.
Sélectionnez la couche d’entrée des images, 'input'
. Vous constaterez que la taille d’entrée de ce réseau est 227 x 227 x 3 pixels.
Enregistrez la taille de l'entrée dans la variable inputSize
.
inputSize = [227 227 3];
Préparer le réseau pour l’apprentissage
Pour utiliser un réseau préentraîné pour l’apprentissage par transfert, vous devez changer le nombre de classes pour correspondre à votre nouveau jeu de données. Commencez par identifier la dernière couche entraînable du réseau. Pour SqueezeNet, la dernière couche entraînable est la dernière couche de convolution, 'conv10'
. Sélectionnez la couche 'conv10'
. Au bas du volet Properties, cliquez sur Unlock Layer. Dans la boîte de dialogue d’avertissement qui apparaît, cliquez sur Unlock Anyway. Les propriétés de la couche sont alors déverrouillées pour que vous puissiez les adapter à votre nouvelle tâche.
Avant R2023b : Pour adapter le réseau aux nouvelles données, vous devez remplacer les couches au lieu de les déverrouiller. Dans la nouvelle couche de convolution 2D, réglez FilterSize sur [1 1].
La propriété NumFilters
définit le nombre de classes pour les problèmes de classification. Modifiez NumFilters
en le définissant sur le nombre de classes voulues dans le nouveau jeu de données, dans cet exemple, 5
.
Modifiez les taux d’apprentissage de sorte que l’apprentissage soit plus rapide dans la nouvelle couche que dans les couches transférées en définissant WeightLearnRateFactor
et BiasLearnRateFactor
à 10
.
Vérifier le réseau
Pour vérifier que le réseau est prêt pour l’apprentissage, cliquez sur Analyze. Deep Learning Network Analyzer n’indique aucune erreur ni aucun avertissement. Le réseau est donc prêt pour l’apprentissage. Pour exporter le réseau, cliquez sur Export. L’application enregistre le réseau dans la variable net_1
.
Préparer les données pour l’apprentissage
Les images du datastore peuvent présenter différentes tailles. Pour redimensionner automatiquement les images d’apprentissage, utilisez un datastore d’images augmentées. L’augmentation des données contribue également à éviter un surajustement (overfitting) du réseau et la mémorisation des détails exacts des images d’apprentissage. Spécifiez ces opérations d’augmentation supplémentaires à réaliser sur les images d’apprentissage : retournez aléatoirement les images d’apprentissage le long de l’axe vertical et effectuez aléatoirement une translation jusqu’à 30 pixels horizontalement et verticalement.
pixelRange = [-30 30]; imageAugmenter = imageDataAugmenter( ... RandXReflection=true, ... RandXTranslation=pixelRange, ... RandYTranslation=pixelRange); augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ... DataAugmentation=imageAugmenter);
Pour redimensionner automatiquement les images de validation et de test sans effectuer d’augmentation des données, utilisez un « Augmented Image Datastore » sans spécifier d’opérations de prétraitement supplémentaires.
augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation); augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);
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.
Effectuez un apprentissage avec l’optimisation Adam.
Définissez le taux d’apprentissage initial à une faible valeur afin de ralentir l’apprentissage dans les couches transférées.
Spécifiez un petit nombre d’epochs. Un epoch est un cycle d’apprentissage complet sur l’ensemble du jeu de données d’apprentissage. Pour l’apprentissage par transfert, vous n’avez pas besoin d’effectuer l’apprentissage sur autant d’epochs.
Spécifiez des données de validation et une fréquence de validation afin que la précision des données de validation soit calculée une fois par epoch.
Spécifiez la taille du mini-batch, c'est-à-dire le nombre d'images à utiliser à chaque itération. Pour faire en sorte que le jeu de données entier soit utilisé à chaque epoch, réglez la taille du mini-batch de manière à diviser uniformément le nombre d'échantillons d'apprentissage.
Affichez la progression de l’apprentissage dans un tracé et surveillez la métrique de précision.
Désactivez la sortie en clair.
options = trainingOptions("adam", ... InitialLearnRate=0.0001, ... MaxEpochs=8, ... ValidationData=imdsValidation, ... ValidationFrequency=5, ... MiniBatchSize=11, ... Plots="training-progress", ... Metrics="accuracy", ... Verbose=false);
Entraîner le réseau de neurones
Entraînez le réseau de neurones avec la fonction trainnet
. Pour les tâches de classification, utilisez la perte d’entropie croisée. 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 trainnet
utilise le CPU. Pour spécifier l’environnement d’exécution, utilisez l’option d’apprentissage ExecutionEnvironment
.
net = trainnet(imdsTrain,net_1,"crossentropy",options);
Tester le réseau de neurones
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.
YTest = minibatchpredict(net,augimdsTest); YTest = scores2label(YTest,classNames);
Visualisez la précision de la classification dans un diagramme de confusion.
TTest = imdsTest.Labels; figure confusionchart(TTest,YTest);
Faire des prédictions avec de nouvelles données
Classez une image. Lisez une image à partir d’un fichier JPEG, redimensionnez-la et convertissez-la en type de données unique.
im = imread("MerchDataTest.jpg");
im = imresize(im,inputSize(1:2));
X = single(im);
Classez l’image. Pour faire une prédiction avec une seule observation, utilisez la fonction predict
. Pour utiliser un GPU, commencez par convertir les données en gpuArray
.
if canUseGPU X = gpuArray(X); end scores = predict(net,X); [label,score] = scores2label(scores,classNames);
Affichez l’image avec l’étiquette prédite et le score correspondant.
figure imshow(im) title(string(label) + " (Score: " + gather(score) + ")")