整个过程大概可以分成这么几步:
- 首先你要在matlab中写一个完整的神经网络
- 获取样本
- 样本导入
- 神经网络建模
- 神经网络训练
- 神经网络测试(优化建模)
- 然后你要在matlab中重写一个神经网络,第二个神经网络的特殊之处是
- 首先这个神经网络必须写成函数,具体有几个细节
- 把第一个神经网络的训练结果net网络保存成mat文件
- 把相关需要用的但无法直接写入代码的数据也保存成mat文件(比如数据归一化的参数)
- 然后在函数中把上面几个mat文件导入,基本上就是一个完整的神经网络模型了
- 再加上一个神经网络计算语句,并把结果返回,这个函数就完成了
- 然后把这个matlab神经网络函数进行打包,打包的结果是一个jar包
- 这块的打包需要注意几个问题
- 配置几个环境变量
- jdk的版本不能太高,它是与Matlab版本相对应的,目前我的这个matlab2015对应的是jdk7,8都不可以
- 这块的打包需要注意几个问题
- 然后把这个jar包连同另一个jar包一块导入Andorid工程,并添加为外部依赖
- 最后在Android工程中写一个专门调用这个Jar包接口代码的函数,传入输入变量,返回计算结果
- 结束开始运行测试,你会发现它报错了,是的,这样做是不行的,但是在java工程中是可以运行的
- 为什么不行?
- 有什么其他解决办法?
1.在matlab中写一个完整的神经网络
1.1.获取样本就不说了
1.2.样本导入
如何导入数据呢,一般matlab中有通用的数据存储格式,那就是Mat格式,但是我并不知道怎么编写这个格式
在我发现有办法可以把txt中的数据导入进去之后我就选定它了,因为这种格式也非常方便我用android输出,也就是说它是一种比较通用的信息交换格式
具体的操作方法非常简单:
- 你在txt中按这种格式保存数据:每行用回车隔开,每列用空格隔开
- 然后你在matlab中load这个文件,就能得到一个数据的矩阵了
代码如下:
alldata = load(‘alldata.txt‘); alldata = alldata(:,:); |
1.3. 1.4. 1.5. 这几个过程照着代码修改还是比较简单的(虽然我当时读得有点困难。。。),稍微提这么几点:
- (直接把matlab30个例子的源码包放到工作路径,复制里边的代码比较方便)
- 输出数据需要进行一下矩阵转换
- 归一化处理数据就是多走一步流程,很简单(虽然不知道原理)
- 使用newff工具函数来构建神经网络,使用matlab内部的工具箱(其实就是库函数)来建模、训练和计算,不需要自己写逻辑代码
- 参数配置不是特别懂
- 最后出图的时候好好修改调一调,不难
- 中间各种矩阵的变换感觉不是很习惯,可以参看一下工作空间里的变量状态,或者一步步打印一些变量的结果来看
clc; clear; %导入300组数据 alldata = load(‘alldata.txt‘); alldata = alldata(:,:); %输入输出数据 input = alldata(:,2:33); outputtemp = alldata(:,1); %输出数据需要处理一下 output = zeros(300,2);%预先分配内存 for i=1:300 switch outputtemp(i) case 0 output(i,:) = [1 0];%意思是如果数据结果是0,则输出层的状态是[1 0],或者用第一个输出节点表示 case 1 %能直接识别带小数位的数据 output(i,:) = [0 1]; end end %从中随机抽取280组数据作为训练数据,20组数据作为预测数据 k = rand(1,300); [m,n] = sort(k); input_train = input(n(1:280),:)‘; output_train = output(n(1:280),:)‘; input_test = input(n(281:300),:)‘; output_test = output(n(281:300),:)‘; %输入输出数据进行归一化处理 [inputn,inputps] = mapminmax(input_train); [outputn,outputps] = mapminmax(output_train); %网络结构构建32-6-2 net=newff(inputn,outputn,6); %网络参数配置(迭代次数,学习率,目标) net.trainParam.epochs=100; net.trainParam.lr=0.1; net.trainParam.goal=0.0004; %网络训练 net=train(net,inputn,outputn); %BP网络预测 %预测数据归一化 inputn_test=mapminmax(‘apply‘,input_test,inputps); %网络预测输出 an=sim(net,inputn_test); %网络输出反归一化 BPoutput=mapminmax(‘reverse‘,an,outputps); %结果分析 figure(1) plot(BPoutput,‘:og‘) hold on plot(output_test,‘-*‘); legend(‘预测输出‘,‘期望输出‘) title(‘BP网络预测输出‘,‘fontsize‘,12) ylabel(‘函数输出‘,‘fontsize‘,12) xlabel(‘样本‘,‘fontsize‘,12) %预测误差 error=BPoutput-output_test; figure(2) plot(error,‘-*‘) title(‘BP网络预测误差‘,‘fontsize‘,12) ylabel(‘误差‘,‘fontsize‘,12) xlabel(‘样本‘,‘fontsize‘,12) figure(3) plot((output_test-BPoutput)./BPoutput,‘-*‘); title(‘神经网络预测误差百分比‘) errorsum = sum(abs(error)) |
2.在matlab中重写这个神经网络,为导出jar包做准备
2.1.首先这个神经网络必须写成函数
在matlab写一个函数的过程是这样的
- 在工作空间中右键新建函数,重命名后打开,就是这样
- matlab中的函数有点特殊,在这里一起趁热讲了
- 整个函数有一头一尾两句固定的声明,头是以function开始,然后是:返回值 = 函数名(函数参数),尾是end,虽然一开始看得不适应,但是习惯还是很好理解的,跟其他的语言差不多
- 返回值可以没有,那就是直接 函数名(函数参数)
- 返回值可以有多个,参数也可以有多个,他们的形式是这样:function [x,y,z]=sphere(theta,phi,rho)
- 注意Matlab中不会对函数类型进行声明,所以很多时候你在写函数的时候一开始就要对输入参数进行一个检查
- 然后下面接着是官方注释,第一句是摘要,之后是详细说明,这些东西会在预览的时候显示
- 接下来就是函数体了,你可以做各种事情,逻辑语句、调用其他函数
- 最后在end之前你需要定义返回值,matlab在这块有点特殊,你不用显示地指定return哪个变量,因为你第一句声明里有返回值变量,所以只要你的函数内容中有这个变量,那么最后执行到end的时候就会自动返回这个变量这时候的状态
- -----调用函数------
- 调用函数的形式跟函数声明的第一句是一毛一样的:[输出参数表]=函数名(输入参数表)
- 调用函数时,输入和输出参数的顺序应与函数定义时的一致,数目一定不能多于函数定于中的,可能可以少于
- 为什么可以少于,因为在函数内部可以通过nargin()和nargout()获取函数被调用时用户指定的输入、输出参数个数。所以如果这个函数里边有针对不同的少于输入少于输出的情况进行if else的话,就可以自动适应
- 整个函数有一头一尾两句固定的声明,头是以function开始,然后是:返回值 = 函数名(函数参数),尾是end,虽然一开始看得不适应,但是习惯还是很好理解的,跟其他的语言差不多
- 那么在这里,我的输出是一个int,输入是一个行矩阵,或者说一个数组,我的函数开头就这么写了:
function output = annforecastthi(input_test)
2.2.然后为了不在这个函数里对神经网络进行训练(因为matlab的设定就是无法把训练函数导出成Jar包),需要把先前神经网络中训练好的net保存成mat文件再在这里直接导出
- 把先前神经网络中训练好的net保存成mat文件 非常简单。直接在运算结束后再工作空间中右键net变量,保存为mat文件就可以了
- 然后导入的时候稍微有点麻烦
- 其实load mat文件有两种方式,一种是命令行方式,一种是函数方式。我查了一下两种方式功能上没什么区别,但是推荐在函数里用函数方式,而命令行方式的形式还会简单很多
- 以导入一个结构体(归一化参数)为例:
- 命令行方式 :load anninputps inputps;
- 函数方式:
- 而导入net数据的时候还要麻烦一些:
- 命令行方式:load annnet net;
- 函数方式:(后边还要加一句把结构体转型成网络格式)
- 这里需要导入三个mat文件,一个net和两个归一化参数(后边要用来反归一化)
2.3.最后返回计算结果,第二个神经网络模型也是神经网络计算函数就完成了
output=find(BPoutput(:,1)==max(BPoutput(:,1)));
整个函数是这样:
function output = annforecastthi(input_test) %ANNFORECAST % 输入长度为32的行矩阵,输出为1或2 A = load(‘annnet.mat‘); B = fieldnames(A); net = A.(B{1}); net = network(net); C = load(‘anninputps.mat‘); D = fieldnames(C); inputps = C.(D{1}); E = load(‘annoutputps.mat‘); F = fieldnames(E); outputps = E.(F{1}); %BP网络预测 %预测数据归一化 inputn_test=mapminmax(‘apply‘,input_test‘,inputps); %网络预测输出 an=sim(net,inputn_test); %网络输出反归一化 BPoutput=mapminmax(‘reverse‘,an,outputps); %结果分析 %根据网络输出找出数据属于哪类 output=find(BPoutput(:,1)==max(BPoutput(:,1))); end |
---待续