Этот пример демонстрирует, как сгенерировать код CUDA® для сети долгой краткосрочной памяти (LSTM). Пример генерирует приложение MEX, которое делает предсказания на каждом шаге входа timeseries. Продемонстрированы два метода: метод с помощью стандартной сети LSTM и метода, усиливающего поведение с сохранением информации той же сети LSTM. Этот пример использует данные о датчике акселерометра из смартфона, продолжил тело и делает предсказания на действии владельца. Пользовательские перемещения классифицируются в одну из пяти категорий, а именно, танца, выполнения, нахождения, положения и обхода. Пример использует предварительно обученную сеть LSTM. Для получения дополнительной информации об обучении смотрите, что Классификация Последовательностей Использует пример Глубокого обучения от Deep Learning Toolbox™.
Необходимый
Этот пример генерирует MEX CUDA и имеет следующие сторонние требования.
CUDA включил NVIDIA® графический процессор и совместимый драйвер.
Дополнительный
Для сборок неMEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.
Инструментарий NVIDIA.
Библиотека NVIDIA cuDNN.
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Стороннее Оборудование (GPU Coder) и Подготовка Необходимых как условие продуктов (GPU Coder).
Используйте coder.checkGpuInstall
Функция (GPU Coder), чтобы проверить, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно.
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
lstmnet_predict
Функция точки входаСеть LSTM от последовательности к последовательности позволяет вам сделать различные предсказания для каждого отдельного временного шага последовательности данных. lstmnet_predict.m функция точки входа берет входную последовательность и передает ее обученной сети LSTM для предсказания. А именно, функция использует сеть LSTM, обученную в Последовательности к Классификации Последовательностей Используя пример Глубокого обучения. Функция загружает сетевой объект от lstmnet_predict.mat
файл в персистентную переменную и повторные использования постоянный объект на последующих вызовах предсказания.
Чтобы отобразить интерактивную визуализацию сетевой архитектуры и информации о слоях сети, используйте analyzeNetwork
функция.
type('lstmnet_predict.m')
function out = lstmnet_predict(in) %#codegen % Copyright 2019 The MathWorks, Inc. persistent mynet; if isempty(mynet) mynet = coder.loadDeepLearningNetwork('lstmnet.mat'); end % pass in input out = predict(mynet,in);
Сгенерировать MEX CUDA для lstmnet_predict.m
функция точки входа, создайте настройку графического процессора, возражают и задают цель, чтобы быть MEX. Установите выходной язык на C++. Создайте объект настройки глубокого обучения, который задает целевую библиотеку как cuDNN. Присоедините этот объект настройки глубокого обучения к объекту настройки графического процессора.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
Во время компиляции GPU Coder™ должен знать типы данных всех входных параметров к функции точки входа. Задайте тип и размер входного параметра к codegen
(MATLAB Coder) команда при помощи coder.typeof
(MATLAB Coder) функция. В данном примере вход имеет двойной тип данных со значением размерности признаков три и переменная длина последовательности. Определение длины последовательности как переменного размера позволяет нам выполнить предсказание на входной последовательности любой длины.
matrixInput = coder.typeof(double(0),[3 Inf],[false true]);
Запустите codegen команду.
codegen -config cfg lstmnet_predict -args {matrixInput} -report
Code generation successful: To view the report, open('codegen/mex/lstmnet_predict/html/report.mldatx').
Загрузите HumanActivityValidate
Matfile. Этот MAT-файл хранит переменную XValidate
это содержит демонстрационный timeseries показаний датчика, на которых можно протестировать сгенерированный код. Вызовите lstmnet_predict_mex
на первом наблюдении.
load HumanActivityValidate
YPred1 = lstmnet_predict_mex(XValidate{1});
YPred1
5 53888 числовая матрица, содержащая вероятности этих пяти классов для каждого из этих 53 888 временных шагов. Для каждого временного шага найдите предсказанный класс путем вычисления индекса максимальной вероятности.
[~, maxIndex] = max(YPred1, [], 1);
Сопоставьте индексы макс. вероятности к соответствующей метке. Отобразите первые десять меток. От результатов вы видите, что сеть предсказала человека, чтобы находиться для первых десяти временных шагов.
labels = categorical({'Dancing', 'Running', 'Sitting', 'Standing', 'Walking'}); predictedLabels1 = labels(maxIndex); disp(predictedLabels1(1:10))
Columns 1 through 6 Sitting Sitting Sitting Sitting Sitting Sitting Columns 7 through 10 Sitting Sitting Sitting Sitting
Используйте график сравнить выходные данные MEX с тестовыми данными.
figure plot(predictedLabels1,'.-'); hold on plot(YValidate{1}); hold off xlabel("Time Step") ylabel("Activity") title("Predicted Activities") legend(["Predicted" "Test Data"])
Вызовите lstmnet_predict_mex
на втором наблюдении с различной длиной последовательности. В этом примере, XValidate{2}
имеет длину последовательности 64 480 тогда как XValidate{1}
имел длину последовательности 53 888. Сгенерированный код обрабатывает предсказание правильно, потому что мы задали размерность длины последовательности, чтобы быть переменным размером.
YPred2 = lstmnet_predict_mex(XValidate{2}); [~, maxIndex] = max(YPred2, [], 1); predictedLabels2 = labels(maxIndex); disp(predictedLabels2(1:10))
Columns 1 through 6 Sitting Sitting Sitting Sitting Sitting Sitting Columns 7 through 10 Sitting Sitting Sitting Sitting
Если вы хотите выполнить предсказание на многих наблюдениях целиком, можно собрать в группу наблюдения в массиве ячеек и передать массив ячеек для предсказания. Массив ячеек должен быть массивом ячейки столбца, и каждая ячейка должна содержать одно наблюдение. Каждое наблюдение должно иметь ту же размерность признаков, но длины последовательности могут варьироваться. В этом примере, XValidate
содержит пять наблюдений. Сгенерировать MEX, который может взять XValidate
как введено, задайте входной тип, чтобы быть массивом ячеек 5 на 1. Далее, укажите, что каждая ячейка имеет тот же тип как matrixInput
, тип вы задали для одного наблюдения в предыдущем codegen
команда.
matrixInput = coder.typeof(double(0),[3 Inf],[false true]); cellInput = coder.typeof({matrixInput}, [5 1]); codegen -config cfg lstmnet_predict -args {cellInput} -report YPred3 = lstmnet_predict_mex(XValidate);
Code generation successful: To view the report, open('codegen/mex/lstmnet_predict/html/report.mldatx').
Выход является массивом ячеек 5 на 1 предсказаний для этих пяти наблюдений, переданных в.
disp(YPred3)
{5×53888 single} {5×64480 single} {5×53696 single} {5×56416 single} {5×50688 single}
Вместо того, чтобы передать целый timeseries, чтобы предсказать за один шаг, мы можем запустить предсказание на входе путем потоковой передачи в один такт за один раз, использования функционального predictAndUpdateState
Эта функция берет во входе, производит выходное предсказание и обновляет внутреннее состояние сети так, чтобы будущие предсказания приняли этот начальный вход во внимание.
Функция точки входа lstmnet_predict_and_update.m берет во входе одно такта и обрабатывает вход с помощью predictAndUpdateState
функция. predictAndUpdateState
выводит предсказание в течение входного такта и обновляет сеть так, чтобы последующие входные параметры были обработаны как последующие такты той же выборки. После передачи во все такты по одному, эквивалентен получившийся выход, если все такты были переданы в как один вход.
type('lstmnet_predict_and_update.m')
function out = lstmnet_predict_and_update(in) %#codegen % Copyright 2019 The MathWorks, Inc. persistent mynet; if isempty(mynet) mynet = coder.loadDeepLearningNetwork('lstmnet.mat'); end % pass in input [mynet, out] = predictAndUpdateState(mynet,in);
Запустите codegen на этом новом файле проекта. Поскольку мы принимаем в один такт каждый звонок, мы задаем matrixInput
иметь фиксированную размерность последовательности 1 вместо переменной длины последовательности.
matrixInput = coder.typeof(double(0),[3 1]); codegen -config cfg lstmnet_predict_and_update -args {matrixInput} -report
Code generation successful: To view the report, open('codegen/mex/lstmnet_predict_and_update/html/report.mldatx').
Запустите сгенерированный MEX на первом такте выборки первой валидации.
firstSample = XValidate{1}; firstTimestep = firstSample(:,1); YPredStateful = lstmnet_predict_and_update_mex(firstTimestep); [~, maxIndex] = max(YPredStateful, [], 1); predictedLabelsStateful1 = labels(maxIndex)
predictedLabelsStateful1 = categorical Sitting
Сравните выходную метку с основной истиной.
YValidate{1}(1)
ans = categorical Sitting