神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测

跳坑里爬了三天,爬不出来了。
VS2013新建CPP工程,把

\cntk\Examples\Evaluation\CPPEvalClient\CPPEvalClient.cpp
拷贝到工程里,在项目上右键->属性,分别设置
VC++目录:
包含目录->\cntk\Include
库目录->\cntk\cntk
链接器
输入->附加依赖项->EvalDll.lib
神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测
文章图片

神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测
文章图片

代码:
#include "stdafx.h" #include "Eval.h" #ifdef _WIN32 #include "Windows.h" #endifusing namespace Microsoft::MSR::CNTK; template using GetEvalProc = void(*)(IEvaluateModel**); typedef std::pair*> MapEntry; typedef std::map*> Layer; int main(int argc, char* argv[]) { IEvaluateModel *model; GetEvalF(&model); return 0; }

神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测
文章图片

GetEvalF在Eavl.h里的声明:
template void EVAL_API GetEval(IEvaluateModel** peval); extern "C" EVAL_API void GetEvalF(IEvaluateModel** peval); extern "C" EVAL_API void GetEvalD(IEvaluateModel** peval);

刚爬出坑来,终于找到问题解释,EvalDll.dll必须在vs2013 update5的64位平台下编译,默认32位是不行的。
From Github/Microsoft/CNTK/CNTK Evaluation Overview
The Windows C++ project must be compiled with an x64 target configuration platform, otherwise some issues arise when calling the EvalDLL library. Refer to the Common Pitfalls page for more information.
神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测
文章图片

PS.在解决这个问题的三天里,积累了很多解决问题的思路和方法,遇到了很多热心的网友,虽相隔千里,语种不同,但代码和关键字成了共同的语言,这是件很奇妙的事。查看dll依赖的Dependents.exe,lib和dll的原理,github上提问,读英文文档,预编译的 __declspec(dllimport)和 __declspec(dllexport)等知识。
正文
(接上边环境配置)
【神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测】一定要将调试模式改为Release模式,否则会出现读取字符串错误。原因在此
贴代码:能编译通过就能跑通。还有一个路径问题:
std::string app = “D:/cntk/Examples/Image/”;
我试了试1.5版本的CPU-ONLY的CNTK release版,里面的cntk/cntk里就有一个CPPEvalClient.exe,那个路径放到就不对,把CPPEvalClient.exe拷贝到D:\cntk\Examples\Image里才能正确运行。到了这一版(1.6版),才发现这个源码里是这么写的,在指定了app路径后,modelWorkingDirectory的路径居然是
modelWorkingDirectory = path + "/../../Examples/Image/MNIST/Data/";

app+/../../,也就是app的上两级目录再加后面的Example/Image/MNIST/Data,所以如果放到/cntk/cntk目录下,就找不到路径了。自己在命令行里指定路径时,也必须找Image的同级目录了。
#include "Eval.h" #ifdef _WIN32 #include "Windows.h" #endif #include #include #include #include using namespace Microsoft::MSR::CNTK; using namespace std; template using GetEvalProc = void(*)(IEvaluateModel**); typedef std::pair*> MapEntry; typedef std::map*> Layer; int main(int argc, char* argv[]) {argc = 0; std::string app = "D:/cntk/Examples/Image/"; std::string path; IEvaluateModel *model; #ifdef _WIN32 path = app.substr(0, app.rfind("\\")); const std::string modelWorkingDirectory = path + "/../../Examples/Image/MNIST/Data/"; #else // on Linux path = app.substr(0, app.rfind("/")); // This relative path assumes launching from CNTK's binary folder, e.g. build/release/bin/ const std::string modelWorkingDirectory = path + "/../../../Examples/Image/MNIST/Data/"; #endifGetEvalF(&model); const std::string modelFilePath = modelWorkingDirectory + "../Output/Models/01_OneHidden"; // Load model with desired outputs std::string networkConfiguration; // Uncomment the following line to re-define the outputs (include h1.z AND the output ol.z) // When specifying outputNodeNames in the configuration, it will REPLACE the list of output nodes // with the ones specified. //networkConfiguration += "outputNodeNames=\"h1.z:ol.z\"\n"; networkConfiguration += "modelPath=\"" + modelFilePath + "\""; model->CreateNetwork(networkConfiguration); std::map inDims; std::map outDims; model->GetNodeDimensions(inDims, NodeGroup::nodeInput); model->GetNodeDimensions(outDims, NodeGroup::nodeOutput); // Generate dummy input values in the appropriate structure and size auto inputLayerName = inDims.begin()->first; std::vector inputs; int count=0; for (int i = 0; i < inDims[inputLayerName]; i++) { inputs.push_back(static_cast(i % 255)); count++; } cout << count<< endl; std::vector outputs; Layer inputLayer; inputLayer.insert(MapEntry(inputLayerName, &inputs)); Layer outputLayer; auto outputLayerName = outDims.begin()->first; outputLayer.insert(MapEntry(outputLayerName, &outputs)); // We can call the evaluate method and get back the results (single layer)... model->Evaluate(inputLayer, outputLayer); // Output the results fprintf(stderr, "Layer '%ls' output:\n", outputLayerName.c_str()); for (auto& value : outputs) { fprintf(stderr, "%f\n", value); }system("pause"); return 0; }

运行结果:
神经网络|【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测
文章图片

数据输入时在input里,这源码里就用了一个循环随机初始化。自己做数据时,直接改代码传进来就可以了。

    推荐阅读