Hauptinhalt

Sequenz-Klassifizierung mithilfe von Deep Learning

Dieses Beispiel veranschaulicht, wie Sie Sequenzdaten mithilfe eines LSTM-Netzes (Long-Short-Term-Memory, langes Kurzzeitgedächtnis) klassifizieren können.

Zum Trainieren eines tiefen neuronalen Netzes für die Klassifizierung von Sequenzdaten können Sie ein neuronales LSTM-Netz verwenden. Mit einem neuronalen LSTM-Netz können Sie Sequenzdaten in ein Netz eingeben und Vorhersagen auf der Grundlage der einzelnen Zeitschritte der Sequenzdaten treffen.

Dieses Diagramm stellt den Fluss von Sequenzdaten durch ein neuronales Netz zur Sequenzklassifizierung dar.

In diesem Beispiel wird der Waveform-Datensatz verwendet. In diesem Beispiel wird ein neuronales LSTM-Netz trainiert, um die Art der Wellenform anhand von Zeitreihendaten zu erkennen. Die Trainingsdaten umfassen Zeitreihendaten für vier Arten von Wellenformen. Jede Sequenz hat drei Kanäle und variiert in der Länge.

Laden von Sequenzdaten

Laden Sie die Beispieldaten aus WaveformData. Die Sequenzdaten bestehen aus einem numObservations-mal-1-Zellen-Array aus Sequenzen, wobei numObservations der Anzahl Sequenzen entspricht. Jede Sequenz ist ein numerisches numTimeSteps-mal--numChannels-Array, bei dem numTimeSteps der Anzahl Zeitschritte der Sequenz und numChannels der Anzahl Kanäle der Sequenz entspricht. Die Kennzeichnungsdaten sind ein kategorischer numObservations-mal-1-Vektor.

load WaveformData 

Visualisieren Sie einige Sequenzen in einem Diagramm.

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

Sehen Sie sich die Klassennamen an.

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

Reservieren Sie Daten für Testzwecke. Unterteilen Sie die Daten in einen Trainingssatz, der 90 % der Daten enthält, und einen Testsatz, der die übrigen 10 % der Daten umfasst. Um die Daten zu partitionieren, verwenden Sie die trainingPartitions-Funktion, die diesem Beispiel als unterstützende Datei angehängt ist. Um auf diese Datei zuzugreifen, öffnen Sie das Beispiel als Live-Skript.

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

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

Vorbereiten von Daten auf das Auffüllen

Während des Trainings teilt die Software die Trainingsdaten standardmäßig auf Mini-Batches auf und füllt die Sequenzen auf, sodass sie dieselbe Länge haben. Ein übermäßiges Auffüllen kann negative Auswirkungen auf die Netzleistung haben.

Um zu verhindern, dass der Trainingsprozess eine zu starke Auffüllung vornimmt, können Sie die Trainingsdaten nach Sequenzlänge sortieren und eine Mini-Batch-Größe so festlegen, dass die Sequenzen in einem Mini-Batch ähnliche Längen aufweisen. Die folgende Abbildung zeigt die Auswirkung einer Auffüllung von Sequenzen vor nach dem Sortieren der Daten.

Rufen Sie die Sequenzlängen für jede Beobachtung ab.

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

Sortieren Sie die Daten nach Sequenzlänge.

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

Zeigen Sie die sortierten Sequenzlängen in einem Balkendiagramm an.

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

Definieren von neuronalen LSTM-Netzarchitekturen

Definieren Sie die Architektur des neuronalen LSTM-Netzes.

  • Legen Sie die Eingangsgröße auf die Anzahl Kanäle in den Eingangsdaten fest.

  • Legen Sie eine bidirektionale LSTM-Schicht mit 120 verborgenen Einheiten fest und geben Sie das letzte Element der Sequenz aus.

  • Fügen Sie schließlich eine vollständig verbundene Schicht mit einer Ausgangsgröße, die der Anzahl Klassen entspricht, hinzu, gefolgt von einer Softmax-Schicht.

Wenn Sie zur Vorhersagezeit Zugriff auf vollständige Sequenzen haben, können Sie eine bidirektionale LSTM-Schicht für Ihr Netzwerk verwenden. Eine bidirektionale LSTM-Schicht lernt zu jedem Zeitschritt aus der vollständigen Sequenz. Wenn Sie zur Vorhersagezeit keinen Zugriff auf die vollständige Sequenz haben, beispielsweise beim Vorhersagen von Werten oder Vorhersagen von jeweils einem Schritt, verwenden Sie stattdessen eine LSTM-Schicht.

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

Festlegen von Trainingsoptionen

Legen Sie die Trainingsoptionen fest. Die Auswahl aus diesen Optionen erfordert eine empirische Analyse. Um verschiedene Konfigurationen von Trainingsoptionen durch Experimente zu untersuchen, können Sie die App Experiment Manager verwenden.

  • Trainieren Sie mithilfe des Adam-Solvers.

  • Trainieren Sie über 200 Epochen hinweg.

  • Legen Sie eine Lerngeschwindigkeit von 0,002 fest.

  • Begrenzen Sie die Gradienten mit einem Grenzwert von 1.

  • Um die Sequenzen nach Länge zu sortieren, deaktivieren Sie das Mischen.

  • Zeigen Sie den Trainingsfortschritt in einem Diagramm an und überwachen Sie die Genauigkeit.

  • Deaktivieren Sie die ausführliche Ausgabe.

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

Trainieren von neuronalen LSTM-Netzen

Trainieren Sie das neuronale Netz mit der Funktion trainnet. Verwenden Sie zur Klassifizierung den Kreuzentropieverlust. Standardmäßig verwendet die trainnet-Funktion eine GPU, sofern vorhanden. Die Verwendung einer GPU erfordert eine Parallel Computing Toolbox™-Lizenz und ein unterstütztes GPU-Gerät. Informationen zu unterstützten Geräten finden Sie unter GPU Computing Requirements (Parallel Computing Toolbox). Andernfalls verwendet die Funktion die CPU. Um die Ausführungsumgebung festzulegen, verwenden Sie die Trainingsoption ExecutionEnvironment.

net = trainnet(XTrain,TTrain,layers,"crossentropy",options);

Testen von neuronalen LSTM-Netzen

Bereiten Sie die Testdaten vor. Das neuronale LSTM-Netz net wurde mithilfe von Mini-Batches aus Sequenzen ähnlicher Länge trainiert. Stellen Sie sicher, dass die Testdaten auf dieselbe Weise organisiert sind. Sortieren Sie die Testdaten nach Sequenzlänge.

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);

Testen Sie das neuronale Netz mit der Funktion testnet. Evaluieren Sie die Genauigkeit der Single-Label-Klassifizierung. Die Genauigkeit ist der Prozentsatz der richtig vorhergesagten Bezeichnungen. Standardmäßig verwendet die testnet-Funktion eine GPU, sofern vorhanden. Um die Ausführungsumgebung manuell auszuwählen, verwenden Sie das Argument ExecutionEnvironment der testnet-Funktion.

acc = testnet(net,XTest,TTest,"accuracy")
acc = 84

Bilden Sie die Klassifizierungsergebnisse in einem Konfusionsdiagramm ab. Machen Sie Vorhersagen mit der Funktion minibatchpredict und wandeln Sie die Ergebnisse mit der Funktion scores2label in Bezeichnungen um. Standardmäßig verwendet die minibatchpredict-Funktion eine GPU, sofern vorhanden.

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

Bilden Sie die Klassifizierungsergebnisse in einem Konfusionsdiagramm ab.

figure
confusionchart(TTest,YTest)

Siehe auch

| | | | |

Themen