Main Content

Classification de séquences avec le Deep Learning

Cet exemple montre comment classer des données séquentielles avec un réseau LSTM (long short-term memory).

Vous pouvez utiliser un réseau de neurones LSTM pour entraîner un réseau de neurones profond à classer des données séquentielles. Un réseau de neurones LSTM vous permet d’entrer des données séquentielles dans un réseau et de réaliser des prédictions en fonction des pas de temps individuels de ces données.

Le schéma suivant illustre le flux de données séquentielles dans un réseau de neurones de classification de séquences.

Cet exemple utilise le jeu de données Waveform. Cet exemple entraîne un réseau de neurones LSTM à reconnaître le type de forme d’onde à partir de données de séries temporelles. Les données d’apprentissage contiennent les données de séries temporelles de quatre types de formes d’onde. Les séquences possèdent chacune trois canaux et sont de longueur variable.

Charger les données séquentielles

Chargez les données d'exemple depuis WaveformData. Les données séquentielles sont un cell array numObservations x 1 de séquences, où numObservations est le nombre de séquences. Chaque séquence est un tableau numérique numTimeSteps x -numChannels, où numTimeSteps est le nombre de pas de temps de la séquence et numChannels est le nombre de canaux de la séquence. Les données d’étiquette sont un vecteur catégoriel numObservations x 1.

load WaveformData 

Visualisez certaines des séquences dans un tracé.

numChannels = size(data{1},2);

idx = [3 4 5 12];
figure
tiledlayout(2,2)
for i = 1:4
    nexttile
    stackedplot(data{idx(i)},DisplayLabels="Channel "+string(1:numChannels))
    
    xlabel("Time Step")
    title("Class: " + string(labels(idx(i))))
end

Affichez les noms des classes.

classNames = categories(labels)
classNames = 4×1 cell
    {'Sawtooth'}
    {'Sine'    }
    {'Square'  }
    {'Triangle'}

Réservez des données pour les tests. Partitionnez les données entre un jeu d’apprentissage contenant 90 % des données et un jeu de test contenant les 10 % restants. Pour partitionner les données, utilisez la fonction trainingPartitions jointe à cet exemple comme fichier de support. Pour accéder à ce fichier, ouvrez l’exemple en tant que live script.

numObservations = numel(data);
[idxTrain,idxTest] = trainingPartitions(numObservations,[0.9 0.1]);
XTrain = data(idxTrain);
TTrain = labels(idxTrain);

XTest = data(idxTest);
TTest = labels(idxTest);

Préparer les données pour le remplissage

Pendant l’apprentissage, par défaut, le software divise les données d’apprentissage en mini-lots et remplit les séquences afin qu’elles aient la même longueur. Un remplissage excessif peut avoir un impact négatif sur les performances du réseau.

Pour éviter que le processus d’apprentissage ajoute trop de remplissage, vous pouvez trier les données d’apprentissage par longueur de séquence et choisir une taille de mini-batch afin que les séquences d’un mini-batch aient une longueur similaire. La figure suivante montre l’effet du remplissage des séquences avant et après le tri des données.

Accédez aux longueurs de séquence pour chaque observation.

numObservations = numel(XTrain);
for i=1:numObservations
    sequence = XTrain{i};
    sequenceLengths(i) = size(sequence,1);
end

Triez les données par longueur de séquence.

[sequenceLengths,idx] = sort(sequenceLengths);
XTrain = XTrain(idx);
TTrain = TTrain(idx);

Affichez les longueurs de séquence triées dans un graphique à barres.

figure
bar(sequenceLengths)
xlabel("Sequence")
ylabel("Length")
title("Sorted Data")

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

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

  • Spécifiez la taille en entrée comme étant le nombre de canaux des données en entrée.

  • Spécifiez une couche de neurones LSTM bidirectionnels avec 120 unités cachées et donnant en sortie le dernier élément de la séquence.

  • Enfin, ajoutez une couche entièrement connectée avec une taille en sortie correspondant au nombre de classes suivie d’une couche softmax.

Si vous avez accès à des séquences complètes au moment de la prédiction, vous pouvez utiliser une couche de neurones LSTM bidirectionnels dans votre réseau. Une couche de LSTM bidirectionnels apprend à partir de la séquence complète à chaque pas de temps. Si vous n’avez pas accès à la séquence complète au moment de la prédiction, par exemple si vous réaliser des prévisions de valeurs ou des prédictions à chaque pas de temps, utilisez une couche de LSTM à la place.

numHiddenUnits = 120;
numClasses = 4;

layers = [
    sequenceInputLayer(numChannels)
    bilstmLayer(numHiddenUnits,OutputMode="last")
    fullyConnectedLayer(numClasses)
    softmaxLayer]
layers = 
  4×1 Layer array with layers:

     1   ''   Sequence Input    Sequence input with 3 dimensions
     2   ''   BiLSTM            BiLSTM with 120 hidden units
     3   ''   Fully Connected   4 fully connected layer
     4   ''   Softmax           softmax

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 le solveur Adam.

  • Effectuez un apprentissage sur 200 epochs.

  • Spécifiez un taux d’apprentissage de 0,002.

  • Limitez les gradients avec un seuil égal à 1.

  • Pour que les séquences restent triées par longueur, désactivez le mélange des données.

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

  • Désactivez la sortie en clair.

options = trainingOptions("adam", ...
    MaxEpochs=200, ...
    InitialLearnRate=0.002,...
    GradientThreshold=1, ...
    Shuffle="never", ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

Entraîner le réseau de neurones LSTM

Entraînez le réseau de neurones avec la fonction trainnet. Pour la 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 GPU Computing Requirements (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,TTrain,layers,"crossentropy",options);

Tester le réseau de neurones LSTM

Classez les données de test et calculez la précision de la classification des prédictions.

Le réseau de neurones LSTM net a été entraîné avec des mini-batchs de séquences de longueur similaire. Assurez-vous que les données de test sont organisées de la même manière. Triez les données de test par longueur de séquence.

numObservationsTest = numel(XTest);
for i=1:numObservationsTest
    sequence = XTest{i};
    sequenceLengthsTest(i) = size(sequence,1);
end

[sequenceLengthsTest,idx] = sort(sequenceLengthsTest);
XTest = XTest(idx);
TTest = TTest(idx);

Classez les données de test et calculez la précision de la classification des prédictions.

Réalisez des prédictions avec la fonction minibatchpredict et convertissez les scores en étiquettes avec la fonction scores2label. Par défaut et selon disponibilité, la fonction minibatchpredict utilise un GPU.

scores = minibatchpredict(net,XTest);
YTest = scores2label(scores,classNames);

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

acc = mean(YTest == TTest)
acc = 0.8700

Affichez les résultats de la classification dans un diagramme de confusion.

figure
confusionchart(TTest,YTest)

Voir aussi

| | | | |

Sujets associés