📄 mainapp.cpp
字号:
#include"bp_rbf.h"
//-0.1~0.1的随机函数
double randnumber()
{
//return (sin(rand())/10) ;
return (sin(rand()));
}
//求某个节点的输出值
double f(int node,int layer)
{
double sum=0;
for (int node2=0;node2<N[layer-1];node2++)
{
sum = sum + w[layer][node][node2] * u[layer-1][node2];
}
sum=1.0/(1+exp(0-sum));
return sum;
}
//用于非隐含层的 误差函数e[layer]
double gf(int layer,int node)
{
double sum=0;
for (int m=0; m<N[layer+1]; m++)
sum = sum + e[layer+1][m]
* u[layer+1][m] * (1-u[layer+1][m]) //误差传递作用函数的梯度
* w[layer+1][m][node];
return sum;
}
//求前馈
void feed_forward()//前馈输出值
{
for (int layer=1;layer<=2;layer++)
{
//对每一层进行计算
for(int node=0;node<N[layer];node++)
u[layer][node] = f(node,layer);
}
}
//求权值的梯度
void compute_gradient()
{
for (int layer=2;layer>0;layer--)
{
//先求e
for(int node=0;node<N[layer];node++)
{
if (layer==2)
e[2][node]=u[2][node]-output[node];
else
e[layer][node]=gf(layer,node);
}
for (int j=0;j<N[layer];j++)
{
for(int i=0;i<N[layer-1];i++)
{
g[layer][j][i] = e[layer][j] * u[layer][j]
* (1.0-u[layer][j]) * u[layer-1][i];
}
}
}
}
//权值更新
void update_weights()
{
for (int layer=1;layer<=2;layer++)
{
for (int j=0;j<N[layer];j++)
{
for(int i=0;i<N[layer-1];i++)
{
temp_w_1[layer][j][i] = w[layer][j][i];
w[layer][j][i] = w[layer][j][i]
- STUDY_SPEED*g[layer][j][i] //新的权变方向
+ ALPHA*delta_w[layer][j][i]; //前一次的权变方向
temp_w_2[layer][j][i] = w[layer][j][i];
delta_w[layer][j][i] = temp_w_2[layer][j][i] - temp_w_1[layer][j][i];
}
}
}
}
//误差
double erro()
{
double sum=0;
sum = pow(fabs(u[2][0]-output[0]),2)
+ pow(fabs(u[2][1]-output[1]),2)
+ pow(fabs(u[2][2]-output[2]),2);
return sum;
}
//初始化,装载样例
void initial(FILE *fp)
{
endsampls = false;
if(feof(fp))
{
endsampls = true;
rewind(fp);
k_k=(++k_k)%7;
if(!k_k)
fprintf(fpwucha,"\n");
fprintf(fpwucha,"%16f",wucha);
wucha = 0.0;
}
input[0]=1.0;
for(int i=1;i<N_BUF;i++)
fscanf(fp,"%f",input+i);
for(i=0;i<O_BUF;i++)
fscanf(fp,"%d",output+i);
// cout<<input[2]<<endl<<output[2]<<endl;
//至此读出一个样本的数据(input,output);
for (int m=0;m<N_BUF;m++)
u[0][m]=input[m];
}
void test()
{
FILE *fpt=NULL;
fpt=fopen("test.txt","r");
for (int i=0; i<= 7;i++)
{
double wucha0 = 0;
initial(fpt);
feed_forward();
wucha0 = erro();
wucha += wucha0;
//u[2][0]=floor(u[2][0]+0.5);
//u[2][1]=floor(u[2][1]+0.5);
//u[2][2]=floor(u[2][2]+0.5);
//cout <<u[2][0]<<" "<<u[2][1]<<" "<<u[2][2]<<endl;
if(!((output[0]==u[2][0])&&(output[1]==u[2][1])&&(output[2]==u[2][2])))
;
else
{
count++;
// cout<<output[0]<<output[1]<<output[2]<<endl;
}
cout << count << " wucha = " << wucha0 << endl;
}
cout << count << " avr_wucha = " << wucha / 100 << endl;
fclose(fpt);
}
//////////////RBF的东东///////////////////////////////////////////////////////////////////////
/////////////////////文件定位////////////////////////////////
void fseeking(FILE* fp,int row_no)
{
rewind(fp);
if (!row_no) return;
l: while((!feof(fp))&&(fgetc(fp)!='\n'))
{
file_time++;
};
//if(feof(fp)) return;
row_no--;
if (row_no)
goto l;
else
return;
}
////径向距离/////
void min_juli(int *set_number)//*j返回输入向量所在的聚类
{
// size_t size;
int jj=0;
double sum_max=1000.0;
double sum=0.0;
for(jj=0;jj<C_BUF;jj++)
{
for (int k=1;k<N_BUF;k++)
sum+=pow(fabs(input[k]-w[1][jj][k]),2);
if(sum<sum_max)
{
*set_number=jj;
sum_max=sum;
}
sum=0;
}
return;
}
//////////////////向量相加////////////
void add_vector(double sum_x[N_BUF],float input[N_BUF])
{
for (int i=1;i<N_BUF;i++)
sum_x[i]+=input[i];
}
void sub_vector(double sum_x[N_BUF],float input[N_BUF])
{
for (int i=1;i<N_BUF;i++)
sum_x[i]-=input[i];
}
void sub_vector(double sum_x[C_BUF],double input[C_BUF],int pp)
{
int ppp=0;
if (pp==N_BUF) ppp=1;
for (int i=ppp;i<pp;i++)
sum_x[i]-=input[i];
return;
}
double vector_width(double *sum_x)
{
double sum=0.0;
for (int i=1;i<N_BUF;i++)
sum+=sum_x[i]*sum_x[i];
return sum;
}
//////////////k均值算法//////////////////////
void k_means()
{
size_t size;
// double _min_change;
// double _min_max_change=0.0;
double min_change = 10.0;//连续两次迭代的变化
int set_number=0;//聚类序号
for (int i0=0;i0<max_layer;i0++)
{
for (int i1=0;i1<max_node;i1++)
for (int i2=0;i2<max_node;i2++)
w[i0][i1][i2]=randnumber();//初始化权值
}
for(int ii=1;ii<C_BUF;ii++)
theita[ii]=NULL;//指针初始化
fp=fopen("study.txt","r");
if (fp==NULL)
{
cout<<"cannot open file"<<endl;
exit(0);
}
int _i=0;
while (!feof(fp))
{
for(int _j=1;_j<N_BUF;_j++)
{
fscanf(fp,"%f",input+_j);
w[1][_i][_j]=input[_j];
}
while (!feof(fp)&&(fgetc(fp)!='\n'));
_i++;
}
rewind(fp);
int set_member_number=0;//某一个聚类中输入向量序号
while (min_change>EP2)//主循环
{
set_member_number=0;
while (!feof(fp))
{
//fseek(fp,(long)(set_member_number*EACH_LINE_OFFSET),0);
for(int i=1;i<N_BUF;i++)
fscanf(fp,"%f",input+i);//读出一个输入向量
while (!feof(fp)&&(fgetc(fp)!='\n'));
min_juli(&set_number); //返回一个距离最小的聚类序号
if(!theita[set_number])
{
theita[set_number]=(int*)malloc(sizeof(int));
size=_msize(theita[set_number]);
*(theita[set_number])=set_member_number;
size=_msize(theita[set_number]);
}
else
{
size=_msize(theita[set_number]);
theita[set_number]=(int*)realloc(theita[set_number],sizeof(int)+size);
*(theita[set_number]+size/4) = set_member_number;
}
set_member_number++;
}
//计算中心
for(int i=1;i<C_BUF;i++)
{
cout<<*(theita[i])<<"theita[]i "<<i<<endl;
if(theita[i])
{
int a = sizeof(int);
size=_msize(theita[i]);
int m=size/4;//该聚类中元素个数
double sum_x[N_BUF];
for(int s=0;s<N_BUF;s++)
sum_x[s]=0.0;
for (int mm=0;mm<m;mm++)
{
fseeking(fp,(*(theita[i]+mm)));
for (int k1=1;k1<N_BUF;k1++)
fscanf(fp,"%f",input+k1);
while((!feof(fp))&&(fgetc(fp)!='\n'));
add_vector(sum_x,input);
}
for(int k=1;k<N_BUF;k++)
{
temp_w_1[1][i][k]=w[1][i][k];
w[1][i][k]=sum_x[k]/m;
}
sub_vector(temp_w_1[1][i],w[1][i],N_BUF);
min_change=vector_width(temp_w_1[1][i]);
}
else
{
for(int k=1;k<N_BUF;k++)
w[1][i][k]=0;
}
}
rewind(fp);
if(min_change>EP2)//迭代没有结束,则放弃此次聚类集合
{
for(int i_free=0;i_free<C_BUF;i_free++)
free(theita[i_free]);
for(int ii=0;ii<C_BUF;ii++)
theita[ii]=NULL;//指针初始化
}
}//主循环结束
//计算核函数的形状参数
for(int ss=0;ss<C_BUF;ss++)//高斯因子初始化
gaosi_yinzi[ss]=0.0;
for(int j=1;j<C_BUF;j++)//开始计算
{
if(theita[j])
{
size=_msize(theita[j]);
int m=size/4;//该聚类中元素个数
double sum_x[N_BUF];
for(int s=0;s<N_BUF;s++)
sum_x[s]=w[1][j][s];
for (int mm=0;mm<m;mm++)
{
fseeking(fp,*(theita[j]+mm));
for (int kk=1;kk<N_BUF;kk++)
fscanf(fp,"%f",input+kk);
while((!feof(fp))&&(fgetc(fp)!='\n'));
sub_vector(sum_x,input);
gaosi_yinzi[j]+=vector_width(sum_x);
}
gaosi_yinzi[j]/=m;
}
}
fclose(fp);
}
/////////////////////////计算隐藏层输出/////////////
void compute_u1()
{
double x[N_BUF];
for(int j=1;j<C_BUF;j++)
{
for (int xx=1;xx<N_BUF;xx++)
x[xx]=input[xx];
sub_vector(x,w[1][j],N_BUF);
if (gaosi_yinzi[j])
u[1][j]=exp((0.0-vector_width(x))/(2.0*gaosi_yinzi[j]));
else
u[1][j]=0;
}
u[1][0]=1;
return;
}
////////////////////////////训练第二层权值/////////////////////////
void lms()
{
double ee[C_BUF];
double e_e;
count=0;
for (int j=0;j<O_BUF;j++)
{
u[2][j]=0.0;
for(int jj=0;jj<C_BUF;jj++)
u[2][j]=u[2][j]+w[2][j][jj]*u[1][jj];
u[2][j]=1.0/(1+exp(0-u[2][j]));
e_e=u[2][j]-output[j];
for (int k=0;k<C_BUF;k++)
{
temp_w_1[2][j][k]=w[2][j][k];
ee[k]=e_e*u[1][k]*STUDY_SPEED;
w[2][j][k]=w[2][j][k]-ee[k]+ALPHA*delta_w[2][j][k];
temp_w_2[2][j][k]=w[2][j][k];
delta_w[2][j][k]=temp_w_2[2][j][k]-temp_w_1[2][j][k];
}
// ee[k]=e_e*u[1][k]*STUDY_SPEED;
//sub_vector(w[2][j],ee,C_BUF);
}
}
void rbf_test()
{
FILE * fp_test=NULL;
fp_test=fopen("test.txt","r");
if(!fp_test)
{
cout<<"cannot open file"<<endl;
exit(0);
}
while (!feof(fp_test))
{
for(int i=1;i<N_BUF;i++)
fscanf(fp_test,"%f",input+i);
for(int j=0;j<O_BUF;j++)
fscanf(fp_test,"%d",output+j);
compute_u1();
for(int j_j=0;j_j<O_BUF;j_j++)
{
u[2][j_j]=0.0;
for(int jj=0;jj<C_BUF;jj++)
u[2][j_j]=u[2][j_j]+w[2][j_j][jj]*u[1][jj];
u[2][j_j]=1.0/(1+exp(0-u[2][j_j]));
}
u[2][0]=floor(u[2][0]+0.5);
u[2][1]=floor(u[2][1]+0.5);
u[2][2]=floor(u[2][2]+0.5);
cout<<u[2][0]<<" "<<u[2][1]<<" "<<u[2][2]<<endl;
if(!((output[0]==u[2][0])&&(output[1]==u[2][1])&&(output[2]==u[2][2])))
;
else
{
count++;
}
}
fclose(fp_test);
}
void trainBp()
{
//BP 算法部分
// FILE * fpw=NULL;
// if (!(fpw=fopen("权值.txt","r")))
//{
//对权值初始化为-0.1~0.1之间的随机数
for (int i0=0;i0<max_layer;i0++)
{
for (int i1=0;i1<max_node;i1++)
{
for (int i2=0;i2<max_node;i2++)
w[i0][i1][i2]=randnumber();
}
}
//}
//else //读取权值
{
// for ( int i0=0;i0<max_layer;i0++)
// for ( int i1=0;i1<max_node;i1++)
// for ( int i2=0;i2<max_node;i2++)
// {
// fseek(fpw,11L,1);
// fscanf(fpw,"%f",&w[i0][i1][i2]);
// }
// fclose(fpw);
}
fpwucha = fopen("bp结果\\误差变化序列.txt","w");
if (!fpwucha)
{
cout<<"cannot open file"<<endl;
exit(0);
}
////////////////////////////
//打开训练文件
fp=fopen("study.txt","r");
if (fp==NULL)
{
cout<<"cannot open file"<<endl;
exit(0);
}
printf("正在训练,请稍等.......");
//开始时钟
clock_t t1 = clock();
if (t1 == clock_t(-1))
{
cerr<<"sorry ,no clock\n";
exit(1);
}
//EP误差阈值0.02
while (wucha > EP || endsampls == false)
{
initial(fp); //初始化,装载样例
feed_forward();
compute_gradient();
update_weights();
//每一次样本集的误差和,对样本集循环训练,
wucha += erro();
//if( endsampls == true)
if(bp_test_time % 200 == 0)
cout<<"\r"<<" 误差= "<< wucha << " times = " << bp_test_time<< endl;
bp_test_time++;
}
//结束时钟
clock_t t2=clock();
if (t2==clock_t(-1))
{
cerr<<"sorry ,no clock\n";
exit(1);
}
cout<<"\r"<<" 训练结束! "<<endl;
cout<<"训练时间为"<<" "
<<double(t2-t1)/CLOCKS_PER_SEC
<<"seconds"<<"(这个时间包括了读写文件时间)"<<endl;
cout<<"训练轮数为 "<<bp_test_time<<endl;
fclose(fp);
fclose(fpwucha);
//测试样例
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -