您的位置:首页 > 理论基础 > 计算机网络

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

2016-08-25 12:30 351 查看
跳坑里爬了三天,爬不出来了。

VS2013新建CPP工程,把

\cntk\Examples\Evaluation\CPPEvalClient\CPPEvalClient.cpp

拷贝到工程里,在项目上右键->属性,分别设置

VC++目录:

包含目录->\cntk\Include

库目录->\cntk\cntk

链接器

输入->附加依赖项->EvalDll.lib





代码:

#include "stdafx.h"
#include "Eval.h"
#ifdef _WIN32
#include "Windows.h"
#endif

using namespace Microsoft::MSR::CNTK;
template<typename ElemType>
using GetEvalProc = void(*)(IEvaluateModel<ElemType>**);

typedef std::pair<std::wstring, std::vector<float>*> MapEntry;
typedef std::map<std::wstring, std::vector<float>*> Layer;
int main(int argc, char* argv[])
{
IEvaluateModel<float> *model;
GetEvalF(&model);
return 0;
}




GetEvalF在Eavl.h里的声明:

template <typename ElemType>
void EVAL_API GetEval(IEvaluateModel<ElemType>** peval);
extern "C" EVAL_API void GetEvalF(IEvaluateModel<float>** peval);
extern "C" EVAL_API void GetEvalD(IEvaluateModel<double>** 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.



PS.在解决这个问题的三天里,积累了很多解决问题的思路和方法,遇到了很多热心的网友,虽相隔千里,语种不同,但代码和关键字成了共同的语言,这是件很奇妙的事。查看dll依赖的Dependents.exe,lib和dll的原理,github上提问,读英文文档,预编译的 __declspec(dllimport)和 __declspec(dllexport)等知识。

正文

(接上边环境配置)

一定要将调试模式改为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<io.h>
#include <string.h>
#include <iostream>
#include <fstream>
using namespace Microsoft::MSR::CNTK;
using namespace std;

template<typename ElemType>
using GetEvalProc = void(*)(IEvaluateModel<ElemType>**);

typedef std::pair<std::wstring, std::vector<float>*> MapEntry;
typedef std::map<std::wstring, std::vector<float>*> Layer;

int main(int argc, char* argv[])
{

argc = 0;
std::string app = "D:/cntk/Examples/Image/";
std::string path;
IEvaluateModel<float> *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/";
#endif

GetEvalF(&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<std::wstring, size_t> inDims;
std::map<std::wstring, size_t> 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<float> inputs;
int count=0;
for (int i = 0; i < inDims[inputLayerName]; i++)
{
inputs.push_back(static_cast<float>(i % 255));
count++;
}
cout << count<< endl;

std::vector<float> 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;
}


运行结果:



数据输入时在input里,这源码里就用了一个循环随机初始化。自己做数据时,直接改代码传进来就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vs CNTK
相关文章推荐