Классификация последовательностей с использованием глубокого обучения

В этом примере показано, как классифицировать данные последовательности с помощью сети долгой краткосрочной памяти (LSTM).

Чтобы обучить глубокую нейронную сеть классифицировать данные последовательности, можно использовать сеть LSTM. Сеть LSTM позволяет вам вводить данные последовательности в сеть и делать предсказания на основе отдельных временных шагов данных последовательности.

Этот пример использует набор данных японских гласных, как описано в [1] и [2]. Этот пример обучает сеть LSTM распознавать говорящего по данным временных рядов, представляющих два японских гласных, на которых говорят последовательно. Обучающие данные содержат данные временных рядов для девяти дикторов. Каждая последовательность имеет 12 функции и изменяется в длине. Набор данных содержит 270 обучающих наблюдений и 370 тестовых наблюдений.

Загрузка данных последовательности

Загрузите обучающие данные японских гласных. XTrain - массив ячеек, содержащий 270 последовательностей размерности 12 различной длины. Y является категориальным вектором меток «1», «2»..., «9», которые соответствуют этим девяти дикторам. Записи в XTrain матрицы с 12 строками (по одной строке для каждой функции) и меняющимся количеством столбцов (по одному столбцу для каждого временного шага).

[XTrain,YTrain] = japaneseVowelsTrainData;
XTrain(1:5)
ans=5×1 cell array
    {12×20 double}
    {12×26 double}
    {12×22 double}
    {12×20 double}
    {12×21 double}

Визуализируйте первые временные ряды на графике. Каждая линия соответствует функции.

figure
plot(XTrain{1}')
xlabel("Time Step")
title("Training Observation 1")
numFeatures = size(XTrain{1},1);
legend("Feature " + string(1:numFeatures),'Location','northeastoutside')

Подготовка данных к заполнению

Во время обучения по умолчанию программное обеспечение разделяет обучающие данные на мини-пакеты и заполняет последовательности так, чтобы они имели одинаковую длину. Слишком большое количество заполнения может негативно влияние на эффективность сети.

Чтобы предотвратить добавление слишком большого количества заполнений в процесс обучения, можно отсортировать обучающие данные по длине последовательности и выбрать размер мини-пакета, чтобы последовательности в мини-пакете имели одинаковую длину. Следующий рисунок показывает эффект заполнения последовательностей до и после сортировки данных.

Получите длины последовательности для каждого наблюдения.

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

Отсортируйте данные по длине последовательности.

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

Просмотрите отсортированные длины последовательности на столбчатой диаграмме.

figure
bar(sequenceLengths)
ylim([0 30])
xlabel("Sequence")
ylabel("Length")
title("Sorted Data")

Выберите мини-пакет размером 27, чтобы разделить обучающие данные равномерно и уменьшить количество заполнения в мини-пакетах. Следующий рисунок иллюстрирует заполнение, добавленное к последовательностям.

miniBatchSize = 27;

Определение сетевой архитектуры LSTM

Определите сетевую архитектуру LSTM. Задайте размер входа, чтобы быть последовательностями размера 12 (размерность входных данных). Задайте двунаправленный слой LSTM со 100 скрытыми модулями измерения и выведите последний элемент последовательности. Наконец, задайте девять классов, включив полностью соединенный слой размера 9, затем слой softmax и слой классификации.

Если у вас есть доступ к полным последовательностям во время предсказания, то вы можете использовать двунаправленный слой LSTM в сети. Двунаправленный слой LSTM учится из полной последовательности на каждом временном шаге. Если у вас нет доступа к полной последовательности во время предсказания, для примера, если вы прогнозируете значения или прогнозируете один временной шаг за раз, используйте вместо этого слоя LSTM.

inputSize = 12;
numHiddenUnits = 100;
numClasses = 9;

layers = [ ...
    sequenceInputLayer(inputSize)
    bilstmLayer(numHiddenUnits,'OutputMode','last')
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer]
layers = 
  5×1 Layer array with layers:

     1   ''   Sequence Input          Sequence input with 12 dimensions
     2   ''   BiLSTM                  BiLSTM with 100 hidden units
     3   ''   Fully Connected         9 fully connected layer
     4   ''   Softmax                 softmax
     5   ''   Classification Output   crossentropyex

Теперь задайте опции обучения. Задайте решатель, который будет 'adam', порог градиента, равный 1, и максимальное количество эпох, равное 100. Чтобы уменьшить количество заполнения в мини-пакетах, выберите мини-пакет размером 27. Чтобы дополнить данные такой же длиной, как и самые длинные последовательности, задайте длину последовательности, которая будет 'longest'. Чтобы убедиться, что данные остаются отсортированными по длине последовательности, задайте, чтобы никогда не тасовать данные.

Поскольку мини-пакеты являются маленькими с короткими последовательностями, обучение лучше подходит для центрального процессора. Задайте 'ExecutionEnvironment' чтобы быть 'cpu'. Для обучения на графическом процессоре, при наличии, установите 'ExecutionEnvironment' на 'auto' (это значение по умолчанию).

maxEpochs = 100;
miniBatchSize = 27;

options = trainingOptions('adam', ...
    'ExecutionEnvironment','cpu', ...
    'GradientThreshold',1, ...
    'MaxEpochs',maxEpochs, ...
    'MiniBatchSize',miniBatchSize, ...
    'SequenceLength','longest', ...
    'Shuffle','never', ...
    'Verbose',0, ...
    'Plots','training-progress');

Обучите сеть LSTM

Обучите сеть LSTM с заданными опциями обучения при помощи trainNetwork.

net = trainNetwork(XTrain,YTrain,layers,options);

Тестируйте сеть LSTM

Загрузите тестовый набор и классифицируйте последовательности в динамики.

Загрузите тестовые данные японских гласных. XTest - массив ячеек, содержащий 370 последовательностей размерности 12 различной длины. YTest является категориальным вектором меток «1», «2»... «9», которые соответствуют этим девяти дикторам.

[XTest,YTest] = japaneseVowelsTestData;
XTest(1:3)
ans=3×1 cell array
    {12×19 double}
    {12×17 double}
    {12×19 double}

Сетевые net LSTM была обучена с использованием мини-партий последовательностей аналогичной длины. Убедитесь, что тестовые данные организованы таким же образом. Отсортируйте тестовые данные по длине последовательности.

numObservationsTest = numel(XTest);
for i=1:numObservationsTest
    sequence = XTest{i};
    sequenceLengthsTest(i) = size(sequence,2);
end
[sequenceLengthsTest,idx] = sort(sequenceLengthsTest);
XTest = XTest(idx);
YTest = YTest(idx);

Классификация тестовых данных. Чтобы уменьшить количество заполнения, введенного процессом классификации, установите размер мини-партии равным 27. Чтобы применить то же заполнение, что и обучающие данные, задайте длину последовательности, которая будет 'longest'.

miniBatchSize = 27;
YPred = classify(net,XTest, ...
    'MiniBatchSize',miniBatchSize, ...
    'SequenceLength','longest');

Вычислите классификационную точность предсказаний.

acc = sum(YPred == YTest)./numel(YTest)
acc = 0.9730

Ссылки

[1] М. Кудо, Дж. Тояма и М. Симбо. «Многомерная классификация кривых с использованием областей». Распознавание Букв. Том 20, № 11-13, стр. 1103-1111.

[2] UCI Machine Learning Repository: Японский набор данных гласных. https://archive.ics.uci.edu/ml/datasets/Japanese+Vowels

См. также

| | | |

Похожие темы