Main Content

Questa pagina si riferisce alla release precedente. La corrispondente pagina in inglese è stata rimossa nella release attuale.

Transfer learning utilizzando una rete preaddestrata

Questo esempio mostra come perfezionare una rete neurale convoluzionale GoogLeNet preaddestrata per eseguire la classificazione di una nuova raccolta di immagini.

GoogLeNet è stata addestrata su oltre un milione di immagini ed è in grado di classificare le immagini in 1000 categorie di oggetti (ad esempio, tastiera, tazza da caffè, matita e molti animali). La rete ha appreso ricche rappresentazioni di feature per un’ampia gamma di immagini. La rete prende un’immagine come input e produce come output un’etichetta per l’oggetto all’interno dell’immagine, insieme alle probabilità che l’oggetto appartenga a ciascuna delle altre categorie di oggetti.

Il transfer learning è ampiamente utilizzato nelle applicazioni di Deep Learning. Si può prendere una rete preaddestrata e utilizzarla come punto di partenza per l’apprendimento di una nuova attività. Solitamente, eseguire il fine-tuning di una rete tramite il transfer learning è molto più veloce e semplice che addestrare una rete con pesi inizializzati da zero su base casuale. È possibile trasferire rapidamente le feature apprese a una nuova attività utilizzando un numero minore di immagini di addestramento.

Caricamento dei dati

Decomprimere e caricare le nuove immagini come un datastore di immagini. imageDatastore etichetta automaticamente le immagini in base ai nomi delle cartelle e memorizza i dati come un oggetto ImageDatastore. Un datastore di immagini consente di memorizzare i dati delle immagini di grandi dimensioni, compresi quelli che non entrano nella memoria, e di leggere in modo efficiente i batch delle immagini durante l’addestramento di una rete neurale convoluzionale.

unzip('MerchData.zip');
imds = imageDatastore('MerchData', ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

Dividere i dati in set di dati di addestramento e di convalida. Utilizzare il 70% delle immagini per l’addestramento e il 30% per la convalida. splitEachLabel suddivide il datastore di immagini in due nuovi datastore.

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');

Questo set di dati molto piccolo contiene adesso 55 immagini di addestramento e 20 immagini di convalida. Visualizzare alcune immagini di esempio.

numTrainImages = numel(imdsTrain.Labels);
idx = randperm(numTrainImages,16);
figure
for i = 1:16
    subplot(4,4,i)
    I = readimage(imdsTrain,idx(i));
    imshow(I)
end

Caricamento della rete preaddestrata

Caricare la rete neurale preaddestrata GoogLeNet. Se Deep Learning Toolbox™ Model for GoogLeNet Network non è installato, il software fornisce un link per il download.

net = googlenet;

Utilizzare deepNetworkDesigner per visualizzare una visualizzazione interattiva dell'architettura di rete e informazioni dettagliate sui livelli della rete.

deepNetworkDesigner(net)

Il primo livello, ossia il livello di input delle immagini, richiede immagini di input di dimensioni 224x224x3, dove 3 indica il numero di canali del colore.

inputSize = net.Layers(1).InputSize
inputSize = 1×3

   224   224     3

Sostituzione dei livelli finali

Il livello completamente connesso e il livello di classificazione della rete preaddestrata net sono configurati per 1000 classi. Questi due livelli, loss3-classifier e output in GoogLeNet, contengono le informazioni su come combinare le feature estratte dalla rete in probabilità di classe, in un valore di perdita e in etichette previste. Per riaddestrare una rete preaddestrata alla classificazione di nuove immagini, sostituire questi due livelli con i nuovi livelli adattati al nuovo set di dati.

Estrarre il grafico di livello dalla rete addestrata.

lgraph = layerGraph(net); 

Sostituire il livello completamente connesso con un nuovo livello completamente connesso con un numero di output pari al numero di classi. Per rendere l’apprendimento più veloce nei nuovi livelli rispetto a quelli trasferiti, aumentare i valori WeightLearnRateFactor e BiasLearnRateFactor del livello completamente connesso.

numClasses = numel(categories(imdsTrain.Labels))
numClasses = 5
newLearnableLayer = fullyConnectedLayer(numClasses, ...
    'Name','new_fc', ...
    'WeightLearnRateFactor',10, ...
    'BiasLearnRateFactor',10);
    
lgraph = replaceLayer(lgraph,'loss3-classifier',newLearnableLayer);

Il livello di classificazione specifica le classi di output della rete. Sostituire il livello di classificazione con uno nuovo senza etichette di classe. trainNetwork imposta automaticamente le classi di output del livello al momento dell'addestramento.

newClassLayer = classificationLayer('Name','new_classoutput');
lgraph = replaceLayer(lgraph,'output',newClassLayer);

Addestramento della rete

La rete richiede immagini di input di dimensioni 224x224x3, ma le immagini nel datastore di immagini hanno dimensioni diverse. Utilizzare un datastore di immagini aumentate per ridimensionare automaticamente le immagini di addestramento. Specificare ulteriori operazioni di aumento da eseguire sulle immagini di addestramento: capovolgere casualmente le immagini di addestramento lungo l'asse verticale e traslarle casualmente fino a 30 pixel in orizzontale e verticale. L’aumento dei dati aiuta la rete ad evitare l’overfitting e a memorizzare i dettagli esatti delle immagini di addestramento.

pixelRange = [-30 30];
imageAugmenter = imageDataAugmenter( ...
    'RandXReflection',true, ...
    'RandXTranslation',pixelRange, ...
    'RandYTranslation',pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
    'DataAugmentation',imageAugmenter);

Per ridimensionare automaticamente le immagini di convalida senza eseguire un ulteriore aumento dei dati, utilizzare un datastore di immagini aumentate senza specificare alcuna ulteriore operazione di pre-elaborazione.

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

Specificare le opzioni di addestramento. Per il transfer learning, mantenere le feature dei livelli precedenti della rete preaddestrata (i pesi dei livelli trasferiti). Per rallentare l’apprendimento nei livelli trasferiti, impostare la velocità di apprendimento iniziale su un valore ridotto. Nel passaggio precedente, sono stati aumentati i fattori della velocità di apprendimento del livello completamente connesso per accelerare l'apprendimento nei nuovi livelli finali. Questa combinazione di impostazioni della velocità di apprendimento porta ad un apprendimento veloce solo nei nuovi livelli e ad un apprendimento più lento negli altri livelli. Quando si esegue il transfer learning, non è necessario l’addestramento per un numero elevato di epoche. Un'epoca è un ciclo di addestramento completo sull'intero set di dati di addestramento. Specificare la dimensione del mini-batch e i dati di convalida. Il software convalida la rete ogni ValidationFrequency iterazioni durante l’addestramento.

options = trainingOptions('sgdm', ...
    'MiniBatchSize',10, ...
    'MaxEpochs',6, ...
    'InitialLearnRate',1e-4, ...
    'Shuffle','every-epoch', ...
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',3, ...
    'Verbose',false, ...
    'Plots','training-progress');

Addestrare la rete composta dai livelli trasferiti e da quelli nuovi. Per impostazione predefinita, trainNetwork utilizza una GPU se è disponibile. Questo richiede Parallel Computing Toolbox™ e un dispositivo GPU supportato. Per informazioni sui dispositivi supportati, vedere GPU Computing Requirements (Parallel Computing Toolbox). In caso contrario, utilizza una CPU. Inoltre, si può specificare l’ambiente di esecuzione tramite l’argomento nome-valore dell’'ExecutionEnvironment' delle trainingOptions.

netTransfer = trainNetwork(augimdsTrain,lgraph,options);

Classificazione delle immagini di convalida

Classificare le immagini di convalida utilizzando la rete ottimizzata.

[YPred,scores] = classify(netTransfer,augimdsValidation);

Visualizzare quattro immagini di convalida di esempio con le etichette previste.

idx = randperm(numel(imdsValidation.Files),4);
figure
for i = 1:4
    subplot(2,2,i)
    I = readimage(imdsValidation,idx(i));
    imshow(I)
    label = YPred(idx(i));
    title(string(label));
end

Calcolare la precisione della classificazione sul set di convalida. La precisione è la frazione di etichette che la rete predice correttamente.

YValidation = imdsValidation.Labels;
accuracy = mean(YPred == YValidation)
accuracy = 1

Per suggerimenti su come migliorare la precisione della classificazione, vedere Deep Learning Tips and Tricks.

Riferimenti

[1] Krizhevsky, Alex, Ilya Sutskever, and Geoffrey E. Hinton. "ImageNet Classification with Deep Convolutional Neural Networks." Advances in neural information processing systems 25 (2012).

[2] Szegedy, Christian, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, and Andrew Rabinovich. "Going deeper with convolutions." Proceedings of the IEEE conference on computer vision and pattern recognition (2015): 1–9.

Vedi anche

| | | | |

Argomenti complementari