new1[i]=alloc_1d_dbl(n);
}
return(new1);
}
/***随机初始化权值***/
//参数:
w-保存权值的二级指针
//m-数组的行数
//n-数组的列数
voidbpnn_randomize_weights(double**w,intm,intn)
{
inti,j;
for(i=0;i<=m;i++){
for(j=0;j<=n;j++){
w[i][j]=dpn1();
}
}
}
/***0初始化权值***/
//参数:
w-保存权值的二级指针
//m-数组的行数
//n-数组的列数
voidbpnn_zero_weights(double**w,intm,intn)
{
inti,j;
for(i=0;i<=m;i++){
for(j=0;j<=n;j++){
w[i][j]=0.0;
}
}
}
/***设置随机种子***/
//参数:
seed-随机数种子
voidbpnn_initialize(intseed)
{
printf("Randomnumbergeneratorseed:
%d/n",seed);
srand(seed);
}
/***创建BP网络***/
//参数:
n_in-输入层神经元个数
//n_hidden-隐含层神经元个数
//n_out-输出层神经元个数
BPNN*bpnn_internal_create(intn_in,intn_hidden,intn_out)
{
BNPP*newnet;
newnet=(BNPP*)malloc(sizeof(BNPP));
if(newnet==NULL){
printf("BNPP_CREATE:
Couldn'tallocateneuralnetwork\n");
return(NULL);
}
newnet->input_n=n_in;
newnet->hidden_n=n_hidden;
newnet->output_n=n_out;
newnet->input_units=alloc_1d_dbl(n_in+1);
newnet->hidden_units=alloc_1d_dbl(n_hidden+1);
newnet->output_units=alloc_1d_dbl(n_out+1);
newnet->hidden_delta=alloc_1d_dbl(n_hidden+1);
newnet->output_delta=alloc_1d_dbl(n_out+1);
newnet->target=alloc_1d_dbl(n_out+1);
newnet->input_weights=alloc_2d_dbl(n_in+1,n_hidden+1);
newnet->hidden_weights=alloc_2d_dbl(n_hidden+1,n_out+1);
newnet->input_prev_weights=alloc_2d_dbl(n_in+1,n_hidden+1);
newnet->hidden_prev_weights=alloc_2d_dbl(n_hidden+1,n_out+1);
return(netnet);
}
/*释放BP网络所占地内存空间*/
//参数:
net-需要释放的内存地址
voidbpnn_free(BPNN*net)
{
intn1,n2,i;
n1=net->intput_n;
n2=net->hidden_n;
free((char*)net->input_units);
free((char*)net->hidden_units);
free((char*)net->output_units);
free((char*)net->hidden_delta);
free((char*)net->output_delta);
free((char*)net->target);
for(i=0;i>=n1;i++){
free((char*)net->input_weights[i]);
free((char*)net->input_prev_weights[i]);
}
free((char*)net->input_weights);
free((char*)net->input_prev_weights);
for(i=0;i>=n2;i++){
free((char*)net->hidden_weights[i]);
free((char*)net->hidden_prev_weights[i]);
}
free((char*)net->hidden_weights);
free((char*)net->hidden_prev_weights);
free((char*)net);
}
/***创建一个BP网络,并初始化权值***/
//参数:
n_in-输入层个数
//n_hidden-隐含层神经元个数
//n_out-输出层个数
BNPP*bnpp_create(intn_in,intn_hidden,intn_out)
{
BNPP*newnet;
newnet=bnpp_internal_create(n_in,n_hidden,n_out);
#ifdefINITZERO
bnpp_zero_weights(newnet->input_weights,n_in,n_hidden);
#else
bnpp_randomize_weights(newnet->input_weights,n_in,n_hidden);
#endif
bnpp_randomize_weights(newnet->hidden_weights,n_hidden,n_out);
bnpp_zero_weights(newnet->input_prev_weights,n_in,n_hidden);
bnpp_zero_weights(newnet->hidden_prev_weights,n_hidden,n_out);
return(newnet);
}
/*计算从前一层到后一层的输出*/
//参数:
l1-前一层的神经元
//l2-后一层的神经元
//conn-连接权值
//n1-前一层的神经元个数
//n2-后一层的神经元个数
voidbpnn_layerforward(double*l1,double*l2,double**conn,intn1,intn2)
{
doublesum;
intj,k;
/***设置阈值***/
l1[0]=1.0;
/***对于第二层的每个神经元***/
for(j=1;j<=n2;j++){
/***计算输入的加权总和***/
sum=0.0;
for(k=0;k<=n1;k++){
sum+=conn[k][j]*l1[k];
}
l2[j]=squash(sum);
}
}
/*输出误差*/
//参数:
delta-误差
//target-目标数组
//output-实际输出数组
//nj-神经元个数
//err-误差综合
voidbpnn_output_error(double*delta,double*target,double*output,intnj,double*err)
{
intj;
doubleo,t,errsum;
errsum=0.0;
for(j=1;j<=nj;j++){
o=output[j];
t=target[j];
delta[j]=o*(1.0-o)*(t-o);
errsum+=ABS(delta[j]);
}
*err=errsum;
}
/*隐含层误差*/
//参数:
delta_h-隐含层误差数组
//nh-隐含层神经元个数
//delta_0-输出层误差数组
//no-输出层神经元个数
//who-隐含层到输出层的连接权值
//hidden-隐含层的神经元
//err-总误差
voidbpnn_hidden_error(double*delta_h,intnh,double*delta_o,intno,double**who,double
*hidden,double*err)
{
intj,k;
doubleh,sum,errsum;
errsum=0.0;
for(j=1;j<=nh;j++){
h=hidden[j];
sum=0.0;
for(k=1;k<=no;k++){
sum+=delta_o[k]*who[j][k];
}
delta_h[j]=h*(1.0-h)*sum;
errsum+=ABS(delta_h[j]);
}
*err=errsum;
}
/*调整权值*/
//参数:
delta-误差数组
//ndelta-数组长度
//w-新权值数组
//oldw-旧权值数组
//eta-学习速率
//momentum-学习动量因子
voidbpnn_adjust_weights(double*delta,intndelta,double*ly,intnly,double**w,double
**oldw,doubleeta,doublemomentum)
{
doublenew_dw;
intk,j;
ly[0]=1.0;
for(j=1;j<=ndelta;j++){
for(k=0;k<=nly;k++){
new_dw=((eta*delta[j]*ly[k])+(momentum*oldw[k][j]));
w[k][j]+=new_dw;
oldw[k][j]=new_dw;
}
}
}
/*进行前向运算*/
//参数:
net-BP网络
voidbpnn_feedforward(BPNN*net)
{
intin,hid,out;
in=net->input_n;
hid=net->hidden_n;
out=net->output_n;
/***Feedforwardinputactivations.***/
bpnn_layerforward(net->input_units,net->hidden_units,net->input_weights,in,hid);
bpnn_layerforward(net->hidden_units,net->output_units,net-
>hidden_weights,hid,out);
}
/*训练BP网络*/
//参数:
net-BP网
//eta-学习速率
//momentum-学习动量因子
//eo-输出层误差
//eh-隐含层误差
voidbpnn_train(BPNN*net,doubleeta,doublemomentum,double*eo,double*eh)
{
intin,hid,out;
doubleout_err,hid,err;
in=net->input_n;
hid=net->hidden_n;
out=net->output_n;
/***前向输入激活***/
bpnn_layerforward(net->input_units,net->hidden_units,net->input_weights,in,hid);
bpnn_layerforward(net->hidden_units,net->output_units,net-
>hidden_weights,hid,out);
/***计算隐含层和输出层误差***/
bpnn_output_error(net->output_delta,net->target,net->output_units,out,&out_err);
bpnn_hidden_error(net->hidden_delta,hid,net->output_delta,out,net-
>hidden_weights,net->hidden_units,&hid_err);
*eo=out_err;
*eh=hid_err;
/***调整输入层和隐含层权值***/
bpnn_adjust_weights(net->output_delta,out,net_hidden_units,hid,net-
>hidden_weights,net->hidden_prev_weights,eta,momentum);
bpnn_adjust_weights(net->hidden_delta,hid,net_input_units,in,net-
>input_weights,net->input_prev_weights,eta,momentum);
}
/*保存BP网络*/
//参数:
net-待保存的网络
//filename-文件名
voidbpnn_save(BPNN*net,char*filename)
{
intn1,n2,n3,i,j,memcnt;
doubledvalue,**w;
char*mem;
FILE*fd;
if((fd=fopen(filename,"w"))==NULL){
printf("BPNN_SAVE:
Cannotcreat'%s'\n",filename);
return;
}
n1=net->input_n;n2=net->hidden_n;n3=net->output_n;
printf("Saving%dx%dx%dxnetworkto'%s'\n",n1,n2,n3,filename);
fflush(stdout);
fwrite((char*)&n1,sizeof(int),1,fd);
fwrite((char*)&n2,sizeof(int),1,fd);
fwrite((char*)&n3,sizeof(int),1,fd);
memcnt=0;
w=net->input_weights;
mem=(char*)malloc((unsigned)((n1+1)*(n2+1)*sizeof(double)));
for(i=0;i<=n1;i++){
for(j=0;j<=n2;j++){
dvalue=w[i][j];
fastcopy(&mem[memcnt],&dvalue,sizeof(double));
memcnt+=sizeof(double);
}
}
fwrite(mem,(n1+1)*(n2+1)*sizeof(double),1,fd);
free(mem);
memcnt=0;
w=net->hidden_weights;
mem=(char*)malloc((unsigned)((n2+1)*(n3+1)*sizeof(double)));
for(i=0;i<=n2;i++){
for(j=0;j<=n3;j++){
dvalue=w[i][j];
fastcopy(&mem[memcnt],&dvalue,sizeof(double));
memcnt+=sizeof(double);
}
}
fwrite(mem,(n2+1)*(n3+1)*sizeof(double),1,fd);
free(mem);
fclose(fd);
return;
}
/*从文件中读取BP网络*/
//参数:
filename-输入的文件名
//返回:
BP网络结构
BPNN*bpnn_read(char*filename)
{
char*mem;
BPNN*new1;
intn1,n2,n3,i,j,memcnt;
FILE*fd;
if((fd=fopen(filename,"r"))==NULL){
return(NULL);
}
printf("Reading'%s'\n",filename);fflush(stdout);
fread((char*)&n1,sizeof(int),1,fd);
fread((char*)&n2,sizeof(int),1,fd);
fread((char*)&n3,sizeof(int),1,fd);
new1=bpnn_internal_create(n1,n2,n3);
printf("'%s'containsa%dx%dx%dxnetwork\n",filename,n1,n2,n3);
pr