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

Matlab离线训练好的神经网络在Visual Studio中调用

2016-10-07 19:25 856 查看
本文将Matlab训练好的神经网络参数导出,在Visual Studio中导入,对数据重新计算。本文的方法可以用于C++调用离线训练好的神经网络。作为神经网络学习之路的一个小小记录

欢迎到我的博客查看更完整的内容

Matlab训练神经网络

首先在Matlab中训练神经网络,本文使用了Matlab的神经网络工具箱中的
House Pricing
示例模型。

在Matlab命令行界面中键入
nnstart
进入神经网络工具箱,导入数据,默认隐含层有10个神经元,一路next到这里,导出矩阵参数的神经网络匹配函数



得到
myNeuralNetworkFunction
函数,例如下面这个:



可见里面有很多的数据矩阵,那些就是神经网络的权值和偏置参数

写一小段代码,用于测试生成的神经网络,例如:

i=1:15;
predict = myNeuralNetworkFunction(houseInputs(:,i))
result = houseTargets(i);
plot(predict,'b');hold on;
plot(result,'g');


该代码用了生成的神经网络重新计算前15组输入数据,并与真实结果
plot
在同一幅图像中,可见该神经网络还是比较令人满意的



导出Matlab的神经网络参数

上文生成的神经网络函数中包含了很多的网络权值和偏移参数,下面将这些参数矩阵导出供Visual Studio读取

myNeuralNetworkFunction
退出的地方放置一个断点,让程序跑到这里停止,方便导出数据



将结构体中的矩阵分别复制出来

x1_xoffset = x1_step1.xoffset
x1_gain = x1_step1.gain
%...方法类似,在此不赘述


将矩阵保存到文件中

save('x1_gain.txt','x1_gain','-ascii')
save('x1_xoffset.txt','x1_xoffset','-ascii')
%...方法类似,不赘述


注意保存的时候要使用
-ascii
参数


可见,Matlab的工作目录中生成了一系列的文件,里面就是响应的矩阵数据,将他们复制到Visual Studio工程目录中



此处我新建了一个
data
文件夹以免混乱

Visual Studio工程中调用参数

参考本博客文章Visual Studio使用Armadillo线性代数运算库添加
Armadillo
线性代数库,新建工程,编写代码

注意:貌似LAPACK和BLAS库有点问题,因此到Armadillo的
config.hpp
中注释掉

#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS


这两句,调试阶段,牺牲一点速度吧

代码中矩阵的初始化使用
load
方法读取文件,如下:

layer1.bias.load("data\\b1.txt", raw_ascii);
layer1.weight.load("data\\IW1_1.txt", raw_ascii);


测试代码

OffLineNeuralNet.hpp

#pragma once
#ifndef _OFFLINE_NEURAL_
#define _OFFLINE_NEURAL_

#include "stdafx.h"
#include <armadillo>

using namespace arma;
using namespace std;

enum Method method;

class Setting
{
public:
mat xoffset;
mat gain;
mat ymin;
};

class Layer
{
public:
mat bias;
mat weight;
};

mat mapminmax_apply(mat x, Setting setting)
{
mat y;
mat temp = x;
y = x - setting.xoffset;
y = y % setting.gain;

temp.fill(setting.ymin(0, 0));
y = y + temp;
return y;
}

mat tansig_apply(mat n)
{
mat a;
a = 2 / (1 + exp(-2 * n)) - 1;
return a;
}

mat mapminmax_reverse(mat y, Setting setting)
{
mat x;
mat temp = y;

temp.fill(setting.ymin(0, 0));
x = y - temp;

temp.fill(setting.gain(0, 0));
x = x / temp;

temp.fill(setting.xoffset(0, 0));
x = x + setting.xoffset;
return x;
}

#endif // !_OFFLINE_NEURAL_


main.cpp

// HousePrizeModel.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <armadillo>
#include "OffLineNeuralNet.h"

#define TOTAL_TEST 15

using namespace arma;

const mat x1_ymin = { -1 };
const mat y1_ymin = { -1 };
const mat y1_gain = { 0.0444444444444444 };
const mat y1_xoffset = { 5 };
const mat layer2_b = { 0.91848175916311114 };

int main()
{

Setting x1_step1, y1_step1;
Layer layer1, layer2;

x1_step1.xoffset.load("data\\x1_xoffset.txt", raw_ascii);
x1_step1.gain.load("data\\x1_gain.txt", raw_ascii);
x1_step1.ymin = x1_ymin;

y1_step1.ymin = y1_ymin;
y1_step1.gain = y1_gain;
y1_step1.xoffset = y1_xoffset;

layer1.bias.load("data\\b1.txt", raw_ascii); layer1.weight.load("data\\IW1_1.txt", raw_ascii);

layer2.bias = layer2_b;
layer2.weight.load("data\\LW2_1.txt", raw_ascii);

mat houseInputs;
vec result(TOTAL_TEST);
houseInputs.load("data\\houseInputs.txt", raw_ascii);

for (int i = 0; i < TOTAL_TEST; i++)
{
mat x1 = houseInputs.col(i);

mat xp1 = mapminmax_apply(x1, x1_step1);
mat a1 = tansig_apply(layer1.bias + layer1.weight * xp1);
mat a2 = layer2.bias + layer2.weight*a1;

double result_temp = mapminmax_reverse(a2, y1_step1)(0);
result.at(i) = result_temp;

}

result.print("Target = ");

system("pause");

return 0;
}



同样测试了数据集的前15组数据,结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息