MATLAB引擎应用程序实例开发

本节通过引擎库函数调用MATLAB神经网络工具,来求解1.2.6中“BP3.c”两隐含层神经网络问题,以进一步说明MATLAB引擎应用开发过程。

1.训练函数简介

该两隐含层的神经网络问题求解,算法采用有动量的梯度下降法。在MATLAB神经网络工具箱中,提供了如下两种训练方法。

(1)先构建网络并设定训练用算法,然后再应用最基本的批处理训练函数train();

code.matlab
net=newff(PR,[s1,s2,..,sn],{TF1,TF2,…,TFn},BTF,BLF,PF);

PR 输入样本极值,一般由minmax()函数取得;

[si] 第i层神经元数;

Tfi 第i层传递函数,常用的有:’logsig’、’tansig’和’purelin’三种,默认值’ tansig’;

BTF 训练函数,常用的有:’traingd’、’traingdm’、’traingdx’、’trainrp’等,默认值’ traingdx’;

BLF 阀值和权重学习函数,默认值’ learngdm’;

PF 演示函数,默认值'mse';

code.matlab
[net,tr,Y,E,Pf,Af]=train(NET,P,T,Pi,Ai,VV,TV)或[net,tr]=train(NET,P,T)

参数:

NET 网络结构

P  网络输入,Ni×Ts的矩阵;

T  训练目标,Nt×Ts矩阵,默认值为[0]

Pi  初始输入延迟条件,默认值为[0]

Ai  初始延迟条件,默认值为[0]

VV 有效向量,默认值为[]

TV 检测向量,默认值为[]

其中:

Ni  输入向量数目(Ni =net.numInputs);

Nt 目标向量数目(Nt = net.numTargets);

Ts 总时步数

返回:

net 网络结构

tr 训练记录(回显及演示)

Y  网络输出

E  网络错误

Pf  输入延迟条件

Af  延迟条件

(2)直接用traingdm()函数训练

code.matlab
[net,tr,Ac,El] = traingdm(net,Pd,Tl,Ai,Q,TS,VV,TV)

参数与返回说明见方式(1)。

训练参数设置说明如表3-2。

表3-2 Traingdm训练参数设置说明

参 数 说明
net.trainParam.epochs 最大训练步数,默认值为10
net.trainParam.goal 训练要求精度,默认值为0
net.trainParam.lr 学习率,默认值为0.01
net.trainParam.max_fail 最大失败次数,默认值为5
net.trainParam.mc 动量因子,默认值为0.9
net.trainParam.min_grad 最小梯度要求,默认值为1e-10
net.trainParam.show 显示训练迭代过程,默认值为25,NaN不显示
net.trainParam.time 最大训练时间,默认值为inf

训练终止条件如下,只满足其中的一个条件,训练结束。

▪训练时步达预定值;

▪训练耗时达到预定值;

▪训练误差小于预定值;

▪下降梯度小于预定值;

▪训练失败次数达预定值。

2.引擎应用程序清单

该引擎应用程序的网络结构型及数学模型见2.6节。引擎应用程序清单如下。

code.c
/////////////  头文件
#include "engine.h"
#include "stdio.h"
#include "conio.h"
#include "string.h"
////////////////////// C程序
int main()
{
FILE *fp0,*fp1;
int i,j,s0,s1,s2,s3,n,n0,ts;
char *DataFile,*Fss,*Fout;
double lr,mc;
mxArray *S,*p,*t,*a,*Lr,*Mc,*Ts;
Engine *ep;
DataFile="J6.txt"; ///////////////////////////////////输入文件名
if((fp0=fopen(DataFile,"r"))==NULL){printf(" Can't open OutPutfile\n");exit(0);}
Fout=strdup(DataFile);Fss="-r.txt";strcat(Fout,Fss);
if((fp1=fopen(Fout,"w"))==NULL){printf(" Can't open OutPutfile\n");exit(0);}
S=mxCreateDoubleMATrix(1,3,mxREAL);
Lr=mxCreateDoubleMATrix(1,1,mxREAL);
Mc=mxCreateDoubleMATrix(1,1,mxREAL);
Ts=mxCreateDoubleMATrix(1,1,mxREAL);
fscanf(fp0,"%d%d%d%d%d%d%lf%lf%d",&n,&n0,&s0,&s1,&s2,&s3,&lr,&mc,&ts);
//////////////////将网络控制参数赋给mxArray矩阵:S
*(mxGetPr(S)+0)=(double)s1; *(mxGetPr(S)+1)=(double)s2;
*(mxGetPr(S)+2)=(double)s3; //*(mxGetPr(S)+3)=(double)s3;
*(mxGetPr(Lr))=(double)lr;  *(mxGetPr(Mc))=(double)mc;  *(mxGetPr(Ts))=(double)ts;
p=mxCreateDoubleMATrix(s0,n,mxREAL);
t=mxCreateDoubleMATrix(s0,n,mxREAL);
///////////////////输入样本与目标向量并赋给mxArray矩阵:p&t
for(j=0;j<n;j++){
	for(i=0;i<s0;i++)fscanf(fp0,"%lf",(mxGetPr(p)+j*s0+i));
	for(i=0;i<s3;i++)fscanf(fp0,"%lf",(mxGetPr(t)+j*s0+i));
}   n=n0;
//////////////////////////输入预测
fscanf(fp0,"%d",&n);a=mxCreateDoubleMATrix(s3,n,mxREAL);
for(j=0;j<n;j++)for(i=0;i<s0;i++)fscanf(fp0,"%lf",(mxGetPr(a)+j*s3+i));
//////////////打开引擎
if((ep=engOpen(NULL))==NULL){printf("\nCan't Open MATLAB engine\n");exit(0);}
///////////// 通过引擎库函数调用MATLAB命令
engPutVariable(ep,"ep_p&quot;,p);  ////将学习样本置入引擎空间
engPutVariable(ep,"ep_t&quot;,t);  ////将目标样本置入引擎空
engPutVariable(ep,"ep_a&quot;,a);  ////将预测样本置入引擎空间
engPutVariable(ep,"ep_S&quot;,S);  ////将相关网络参数置入引擎空间
engPutVariable(ep,"ep_Lr",Lr);
engPutVariable(ep,"ep_Mc",Mc);
engPutVariable(ep,"ep_Ts",Ts);
engEvalString(ep,"net=newff(minmax(ep_p),ep_S,{'logsig','logsig','purelin'},'traingdm');");
///构造BP网络
engEvalString(ep,"net.trainParam.show=200;&quot;);    ///回显一次所经过的计算时步
engEvalString(ep,"net.trainParam.lr=ep_Lr;&quot;);     ///学习率
engEvalString(ep,"net.trainParam.mc=ep_Mc;&quot;);    ///动量项
engEvalString(ep,"net.trainParam.epochs=ep_Ts;");  //预定时步
engEvalString(ep,"net.trainParam.goal=1e-5;&quot;);    ///训练要求精度
engEvalString(ep,"net.trainParam.time=inf;&quot;);      ///无训练时间限制
engEvalString(ep,"[net,tr]=train(net,ep_p,ep_t);");  ///训练网络
engEvalString(ep,"ep_b=sim(net,ep_a);&quot;);   /////////////样本预测
printf("\nPress anykey to plot\n"); getch(); ////////////作预测曲线
engEvalString(ep,"ep_x=(10.0).^ep_a; ep_y=(10.0).^ep_b;");
engEvalString(ep,"plot(ep_x,ep_y);");
engEvalString(ep,"xlabel('Date/d');");
engEvalString(ep,"ylabel('Displacement/mm');");
///////////////////////////////预测结果返回
printf("\nPress anykey to return and engClose \n"); getch();
for(i=0;i<n;i++)fprintf(fp1," %3d %12.4lf   %12.4lf  \n",
	i,*(mxGetPr(engGetVariable(ep,"ep_x"))+i),*(mxGetPr(engGetVariable(ep,"ep_y"))+i));
///////////  关闭引擎
if(engClose(ep)!=0){printf("\nCan't close MATLAB engine normally\n");exit(-1);}
printf("\n MATLAB engine is over\n");
////////// 将MATLAB引擎计算结果输出
////////// 释放内存
mxDestroyArray(p);  mxDestroyArray(t);   mxDestroyArray(a);   mxDestroyArray(S);
mxDestroyArray(Lr); mxDestroyArray(Mc);  mxDestroyArray(Ts);
fclose(fp0); fclose(fp1);    /// 关闭文件
return 0;}
/////////////////结束//////////////////////////////////////////////////////////////////////////////////