Этот пример демонстрирует, как сгенерировать код CUDA® для сети долгой краткосрочной памяти (LSTM). Пример генерирует приложение MEX, которое делает предсказания на каждом шаге входа timeseries. Продемонстрированы два метода: метод с помощью стандартной сети LSTM и метода, усиливающего поведение с сохранением информации той же сети LSTM. Этот пример использует данные о датчике акселерометра из смартфона, продолжил тело и делает предсказания на действии владельца. Пользовательские перемещения классифицируются в одну из пяти категорий, а именно, танца, выполнения, нахождения, положения и обхода. Пример использует предварительно обученную сеть LSTM. Для получения дополнительной информации об обучении смотрите, что Классификация Последовательностей Использует пример Глубокого обучения от Deep Learning Toolbox™.
CUDA включил NVIDIA®, графический процессор с вычисляет возможность 3.5 или выше.
NVIDIA инструментарий CUDA и драйвер.
Библиотека NVIDIA cuDNN.
Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, смотрите Сторонние продукты (GPU Coder). Для подготовки переменных окружения смотрите Подготовку Необходимых как условие продуктов (GPU Coder).
Интерфейс GPU Coder для Библиотек Глубокого обучения поддерживает пакет. Чтобы установить этот пакет поддержки, используйте Add-On Explorer.
Используйте coder.checkGpuInstall
функция, чтобы проверить, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно.
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
команда при помощи coder.typeof
функция. В данном примере вход имеет двойной тип данных со значением размерности признаков три и переменная длина последовательности. Определение длины последовательности как переменного размера позволяет нам выполнить предсказание на входной последовательности любой длины.
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