Вопрос о синтаксисе программирования при использовании CNTKLibrary из C++

Это просто вопрос о синтаксисе программирования на С++ (я думаю). У меня есть 192 поплавка в такой структуре, как:

std::vector outputData(192);

Я хочу вызвать встроенную функцию Softmax в CNTKLibrary для этого вектора 192x1 — документация в файле заголовка:

/// Создаем экземпляр встроенной в CNTK операции softmax для указанного входного операнда тензора CNTK_API FunctionPtr Softmax(const Variable& operand, const std::wstring& name = L"");

Как я могу это сделать? Думаю, сначала я получаю указатель на функцию, а затем применяю его, но я не понимаю, каков будет синтаксис. Что-то вроде этого...

// Захватите указатель функции Softmax

FunctionPtr SoftmaxFuncPtr = Softmax(outputData); // как привести аргумент?

// Как оценить этот FuntionPtr?

SoftmaxFuncPtr->eval(); // WAG - понятия не имею...

Куда девается результат вычислений?

Спасибо, если подскажете...


person Tullhead    schedule 01.05.2017    source источник
comment
Прочтите это, а затем убедитесь, что ваш вопрос выглядит так, как вы задумали. Используйте панель предварительного просмотра под полем редактирования.   -  person n. 1.8e9-where's-my-share m.    schedule 01.05.2017


Ответы (1)


Сначала вам нужно определить переменную для ввода Softmax, например:

auto inputVar = InputVariable(DimensionsOfInput, DataType::Float, L"InputSoftMax");

Затем вы создаете составную функцию, используя Softmax, например

FunctionPtr SoftmaxFuncPtr = Softmax(inputVar, L"SoftMax"); 
auto EvalFuncPtr = AsComposite(SoftmaxFuncPtr, L"EvalSoftMax");

После этого создайте карту ввода и вывода, чтобы подготовить данные для оценки, а затем вызовите Forward() или Evaluate(), чтобы выполнить оценку входных данных и получить результат вывода.

Пример MultiThreadsEvaluationWithNewFunction() в EvalMultithreads.cpp демонстрирует, как создать новую функцию для оценки. На странице описано, как использовать эти примеры. Функция там содержит несколько уровней и поддерживает оценку с использованием многопоточности, поэтому у нее может быть некоторый код, который не требуется для вашего случая. И образец по-прежнему использует низкоуровневые API для управления входными и выходными данными, и у нас также есть удобные методы высокого уровня, такие как Value::CreateBatch/Sequence/BatchOfSequence(), Value::CopyVariableValueTo(), которые помогут вам подготовить входные данные. /выводить данные, не зная низкоуровневых деталей. В CNTKLibrary.h также есть описание этих APIS.

Пожалуйста, дайте нам знать о любых ваших вопросах. Спасибо,

person Zhou    schedule 01.05.2017
comment
Хммм... ОК, я пытаюсь понять весь синтаксис и значение.... это кажется сложным, потому что CNTK настроен так, чтобы разрешать произвольные тензоры и т. д. Мне бы очень хотелось просто сделать такой вызов : std:vector‹float› answer = softmax(outputData); но похоже, что мне нужно сделать что-то вроде (см. следующий пост)... - person Tullhead; 02.05.2017
comment
// определяем входную переменную NDShape DimensionsOfInput(1, ntot); auto inputVar = InputVariable(DimensionsOfInput, DataType::Float, LInputSoftMax); std::vector‹float› inputData(inputVar.Shape().TotalSize()); // заполняем входную переменную данными for (i = 0; i ‹ ntot; i++) { inputData[i] = theApp.pNetworkOutput-›GetAt(i); } // построить составную функцию FunctionPtr SoftmaxFuncPtr = Softmax(inputVar, LSoftMax); auto EvalFuncPtr = AsComposite(SoftmaxFuncPtr, LEvalSoftMax); ...продолжение... - person Tullhead; 02.05.2017
comment
// создать ввод ValuePtr ValuePtr inputValue = MakeSharedObject‹Value›(MakeSharedObject‹NDArrayView›(inputVar.Shape(), inputData, true)); // мне нужен 'SharedObject? // создать вывод ValuePtr ValuePtr outputValue; auto outputVar = EvalFuncPtr-›Output(); std::unordered_map‹Variable, ValuePtr› outputs = { {outputVar, outputValue} }; // применяем функцию EvalFuncPtr-›Forward({ { inputVar, inputValue } }, outputs); // получаем выходное значение outputValue = outputs[outputVar]; // делаем что-то еще, чтобы извлечь массив outputData из outputValue - person Tullhead; 02.05.2017
comment
Другая причина предоставления сопоставления данных заключается в том, что функция может иметь несколько входных данных (у Softmax есть только один), поэтому необходимо указать, какие данные сопоставляются с какой переменной. И API поддерживает оценку пакетных данных, данных последовательности или пакета последовательности, поэтому вызывающей стороне необходимо указать, как обрабатывать свои данные. Методы CreateBatch(), CreateSequence() и CreateBatchOfSequence() помогают пользователям создавать различные типы входных значений из входных простых данных. С помощью этих методов вы можете избежать работы с NDArrayView и другими низкоуровневыми типами. - person Zhou; 03.05.2017
comment
Вы можете найти примеры использования этих методов на C# здесь (github .com/Microsoft/CNTK/blob/master/Examples/Evaluation/). Использование в C++ очень похоже (мы надеемся вскоре представить примеры использования этих методов в C++). Пожалуйста, сообщите нам, если у вас есть какие-либо предложения по улучшению API. Благодарю вас! - person Zhou; 03.05.2017