В этом примере показано, как классифицировать данные последовательности с использованием сети LSTM.
Для обучения глубокой нейронной сети классификации данных последовательности можно использовать сеть LSTM. Сеть LSTM позволяет вводить данные последовательности в сеть и делать прогнозы на основе отдельных временных шагов данных последовательности.
В этом примере используется набор данных Vowels на японском языке, как описано в [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. Укажите входной размер, который будет представлять собой последовательности размера 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'. Обучение на GPU, если доступно, установить '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 с использованием указанных вариантов обучения trainNetwork.
net = trainNetwork(XTrain,YTrain,layers,options);

Загрузите тестовый набор и классифицируйте последовательности в динамики.
Загрузите данные теста японских гласных. 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}
Сеть LSTM net был обучен с использованием мини-партий последовательностей аналогичной длины. Убедитесь, что тестовые данные организованы таким же образом. Сортировка тестовых данных по длине последовательности.
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: набор данных японских гласных. https://archive.ics.uci.edu/ml/datasets/Japanese+Vowels
bilstmLayer | lstmLayer | sequenceInputLayer | trainingOptions | trainNetwork