cntk — Полностью сверточное сетевое обучение по переполнению стека

Я пытаюсь перенести обучение FCN из BrainScript в программу C ++. Для начала я просто загружаю и переобучаю существующую модель. Я что-то получаю, но trainer-> TrainMinibatch () выдает исключение (и я не могу понять, как получить описание исключения). Грубый код ниже:

CNTK::DeviceDescriptor& device=  CNTK::DeviceDescriptor::GPUDevice(gpuid);

FunctionPtr rootFunc = nullptr;
try {
rootFunc = Function::Load(modelname, device);
}
catch (char *err) {
printf("Load fail: %s\n",err);
return;
}
catch (...) {
printf("Load fail\n");
return;
}

std::cerr << "Loaded model ok" << std::endl;MinibatchSourcePtr minibatchSource;
try {
minibatchSource = HG_CreateMinibatchSource(64);
}
catch (char* err) {
std::cerr << "Failed to init src: " << err << std::endl;
return;
}
catch (...) {
std::cerr << "Failed to init src " << std::endl;
return;
}

auto imageStreamInfo = minibatchSource->StreamInfo(L"features");
auto labelStreamInfo = minibatchSource->StreamInfo(L"labels"); // We don't use labels as is FCN

auto inputImageShape = imageStreamInfo.m_sampleLayout;

std::cerr << "Input Shape: " << inputImageShape.AsString() << std::endl;

auto imageInputName = L"features";
auto imageInput = InputVariable(inputImageShape, imageStreamInfo.m_elementType, imageInputName);
auto classifierOutput = rootFunc;

//EITHER - construct error from output+target
std::wstring outputLayerName = L"op";
FunctionPtr outputLayer = rootFunc->FindByName(outputLayerName);
std::wstring targetLayerName = L"opool3";
FunctionPtr targetLayer = rootFunc->FindByName(targetLayerName);

// OR - just get from network
std::wstring errLayerName = L"e";
FunctionPtr errLayer = rootFunc->FindByName(errLayerName);

std::cerr << "Setup-got op layer" << outputLayer->Output().Shape().AsString() <<   std::endl;
std::cerr << "Setup-got tgt layer" << targetLayer->Output().Shape().AsString() << std::endl;
std::cerr << "Setup-got err layer" << errLayer->Output().Shape().AsString() << std::endl;

auto trainingLoss = CNTK::SquaredError(outputLayer, targetLayer);
auto prediction = CNTK::SquaredError(outputLayer, targetLayer);

LearningRateSchedule learningRatePerSample = TrainingParameterPerSampleSchedule(5e-8);

// Either
auto trainer = CreateTrainer(classifierOutput, trainingLoss->Output(), prediction->Output(), { SGDLearner(classifierOutput->Parameters(), learningRatePerSample) });

// Or
//auto trainer = CreateTrainer(classifierOutput, errLayer, errLayer, { SGDLearner(classifierOutput->Parameters(), learningRatePerSample) });

const size_t minibatchSize = 1;
size_t numMinibatchesToTrain = 100;
size_t outputFrequencyInMinibatches = 10;
try {
for (size_t i = 0; i < numMinibatchesToTrain; ++i)
{
std::cerr << "Iteration: " << i << std::endl;
auto minibatchData = minibatchSource->GetNextMinibatch(minibatchSize, device);

std::cerr << "  got data for "<< imageInput.AsString() << std::endl;

trainer->TrainMinibatch({ { imageInput, minibatchData[imageStreamInfo] } }, device); // This line throws exception!

std::cerr << "Eval=" << trainer->PreviousMinibatchEvaluationAverage() << "," << trainer->PreviousMinibatchLossAverage() << std::endl;
}
}
// Question edited as result of comment on exceptions below
catch (const std::exception & err) {
std::cerr << "Training error:" << err.what() << std::endl;
}
catch (...) {
std::cerr << "Training error" << std::endl;
}

Непонятно, как именно определить функцию потерь (я думаю, здесь нет никакой документации). В сети произошла потеря (‘e’), используемая CNTK.exe / Brainscript, которая представляет собой квадратную ошибку между выводом (‘op’) и целью (‘opool3’). Я попробовал как использовать e напрямую, так и определить ошибку в C ++ с помощью CNTK :: SquaredError (). Оба выдают одинаковый вывод, что указывает на исключение, генерируемое trainer-> TrainMinibatch:

Loaded model ok
Input Shape:B[1024 x 1024 x 3]
Setup-got op layeB[63 x 127 x 3]
Setup-got tgt layeB[63 x 127 x 3]
Setup-got err layeB[]
Iteration: 0
got data forB,Input('features', [1024 x 1024 x 3], [*, #])
Training error:Values for 1 required arguments 'Input('features', [1024 x 1024 x 3], [, #])', that the requested output(s) 'Output('aggregateLoss', [], []), Output('Block233_Output_0', [], [, #]), Output('aggregateEvalMetric', [], [])' depend on, have not been provided.

Что я здесь не так делаю?

Спасибо!

D.

Изменить: Исключение составляет:

Обучающая ошибка: значения для 1 обязательных аргументов ‘Input (‘ features ‘, [1024 x 1024 x 3], [, #])’, которые запрошенные выходные данные » Output (‘aggregateLoss’, [], []) , Output (‘Block233_Output_0’, [], [, #]), Output (‘aggregateEvalMetric’, [], []) ‘зависят от, не были предоставлены.

Обновление: Посмотрев на код cntk (CompositeFunction.cpp), кажется, что проблема заключается в несоответствии между вводом и требуемым вводом:

Поставляемая переменная: Input («функции», [1024 x 1024 x 3], [*, #])

Обязательный аргумент: Ввод (‘особенности’, [1024 x 1024 x 3], [, #])

Разница заключается в [*. #] против [, #]

Не уверен, как это исправить, хотя!

1

Решение

Эта проблема из-за imageInput это новая переменная, которая не имеет ничего общего с сетевыми аргументами. Вместо этого вам нужно получить входную переменную (и), связанную с сетевыми аргументами, и связать их с miniatchData, например. что-то вроде

std::unordered_map<Variable, ValuePtr> inputDataMap = { { classifierOutput.Arguments()[0], minibatchData[imageStreamInfo] } }

Тогда пройдите inputDataMap тренировать минибатч. Смотрите также этот оценка пример (обучение и оценка имеют довольно похожие API)

0

Другие решения

Других решений пока нет …