本节通过引擎库函数调用MATLAB神经网络工具,来求解1.2.6中“BP3.c”两隐含层神经网络问题,以进一步说明MATLAB引擎应用开发过程。
1.训练函数简介
该两隐含层的神经网络问题求解,算法采用有动量的梯度下降法。在MATLAB神经网络工具箱中,提供了如下两种训练方法。
(1)先构建网络并设定训练用算法,然后再应用最基本的批处理训练函数train();
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';
[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()函数训练
[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节。引擎应用程序清单如下。
///////////// 头文件
#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",p); ////将学习样本置入引擎空间
engPutVariable(ep,"ep_t",t); ////将目标样本置入引擎空
engPutVariable(ep,"ep_a",a); ////将预测样本置入引擎空间
engPutVariable(ep,"ep_S",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;"); ///回显一次所经过的计算时步
engEvalString(ep,"net.trainParam.lr=ep_Lr;"); ///学习率
engEvalString(ep,"net.trainParam.mc=ep_Mc;"); ///动量项
engEvalString(ep,"net.trainParam.epochs=ep_Ts;"); //预定时步
engEvalString(ep,"net.trainParam.goal=1e-5;"); ///训练要求精度
engEvalString(ep,"net.trainParam.time=inf;"); ///无训练时间限制
engEvalString(ep,"[net,tr]=train(net,ep_p,ep_t);"); ///训练网络
engEvalString(ep,"ep_b=sim(net,ep_a);"); /////////////样本预测
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;}
/////////////////结束//////////////////////////////////////////////////////////////////////////////////