人工智能BP神经网络一直不收敛哪里出错了
予介 2017-06-10 10:31:09 #include<iostream>
#include<stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#define N 100
using namespace std;
//产生(-1,1)之间的随机数函数
double generaterandom()
{
double w;
w=(double)((rand() % 101) * 0.01f*2-1);
return w;
}
double fdao(double x)
{
double dao;
double m=1/(1+exp(-x));
dao=m*(1-m);
return dao;
}
int main()
{
int n,t,q,i,j,m,mm,nn,l,k,ll,Q,flag=0;
double w1[N][N]={0},w2[N][N]={0};//两组w和b需要初始化,增加了隐含层的一组
double d,dao,b1[N]={0},b2[N]={0};
t=0;
//初置精度控制参数e,学习率a,精度控制为d=e+1;
int T=1000;double e=0.1;double a=0.01;
d=e+1;
double e1[N]={0};
double a2[N][N]={0};
double a1[N][N]={0};
double E2[N][N]={0};
double E1[N][N]={0};
double ss[15][2]={1.78,1.14,1.96,1.18,1.86,1.20,1.72,1.24,2,1.26,2,1.28,1.96,1.3,1.74,1.36,1.64,1.38,1.82,1.38,1.9,1.38,1.70,1.40,1.82,1.48,1.82,1.54,2.08,1.56};
double yy[15][1]={0.9,0.9,0.9,0.1,0.9,0.9,0.9,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1};
n=2;m=1;l=30;Q=15;
/* cout<<"请键入输入个数:"<<endl;
cin>>n;
cout<<"请键入输出个数:"<<endl;
cin>>m;
cout<<"请键入隐含层的神经元个数:"<<endl;
cin>>l;
cout<<"请键入样本个数:"<<endl;
cin>>Q;*/
//初始化权矩阵w1,阈值向量b1(产生-1—1之间的随机数进行w和b的初始化)
for(ll=0;ll<l;ll++)
{
for(nn=0;nn<n;nn++)
{
w1[ll][nn] = (double)((rand() % 101) * 0.01f*2-1);
}
b1[ll]=(double)((rand() % 101) * 0.01f*2-1);
}
//初始化权矩阵w2,阈值向量b2
for(mm=0;mm<m;mm++)
{
for(ll=0;ll<l;ll++)
{
w2[mm][ll] = (double)((rand() % 101) * 0.01f*2-1);
}
b2[mm]=(double)((rand() % 101) * 0.01f*2-1);
}
for(a=0.01;a<=0.8;a+0.1)
{
while(d >= e && t<T )
{
d=0;
for(i=0;i<l;i++)
{
e1[i]=0;
}
for(q=0;q<Q;q++)//使用样本的组数
{
for(i=0;i<l;i++)//第i个隐含层的神经元的计算:根据两个输入计算出第i个神经元对应的一个输出a1
{
a1[q][i]=0;
for(j=0;j<n;j++)
{
a1[q][i]+=w1[i][j]*ss[q][j];
}
a1[q][i]+=b1[i];//计算输出a1[q][i]值:即第q组样本的第i个隐含层的输出值
a1[q][i]=1/(1+exp(-a1[q][i]));//响应函数为logsig函数
}
for(k=0;k<m;k++)//a1作为隐含层的输入,对第k个输出神经元进行计算:根据a1的各个输入计算出第k个输出神经元对应的一个输出值a2
{
a2[q][k]=0;
for(j=0;j<l;j++)
{
a2[q][k]+=w2[k][j]*a1[q][j];
}
a2[q][k]+=b2[k];//计算输出a2[q][i]值:即第q组样本的第i个输出层的输出值即Oi
// a2[q][k]=1/(1+exp(-a2[q][k]));//最好别用同一个函数,可能会收敛慢
d=d+(yy[q][k]-a2[q][k])*(yy[q][k]-a2[q][k]); //计算累计误差
}
//根据隐含层的误差效能修正W1、B1
//el的计算
for(k=0;k<m;k++)
{ //dao=fdao(a2[q][k]);
//E2[q][k]=(yy[q][k]-a2[q][k])*dao;//误差效能E2[q][i]
E2[q][k]=yy[q][k]-a2[q][k];
}
for(i=0;i<l;i++)
{
e1[i]=0;
for(k=0;k<m;k++)
{
e1[i]+=E2[q][k]*w2[k][i];
}
}
//根据输出层的误差效能修正W2、B2;
for(k=0;k<m;k++)
{
for(i=0;i<l;i++)
{
w2[k][i]=w2[k][i]+a*E2[q][k]*a1[q][i];
}
b2[k]=b2[k]+a*E2[q][k];
}
//计算El的值
for(i=0;i<l;i++)
{
dao=fdao(a1[q][i]);
E1[q][i]=e1[i]*dao;
}
//修正w1,b1
for(i=0;i<l;i++)
{
for(j=0;j<n;j++)
{
w1[i][j]=w1[i][j]+a*E1[q][i]*ss[q][j];
}
b1[i]=b1[i]+a*E1[q][i];
}
}
t++;
}
/*for(mm=0;mm<m;mm++)
{
cout<<"训练后的权值为:"<<endl;
for(nn=0;nn<n;nn++)
{
printf("%0.2f\t",w[mm][nn]);
}
cout<<endl;
cout<<"训练后的阈值为:"<<endl;
printf("%0.2f\n",b[mm]);
}*/
if(t<T)
{
cout<<"训练了:"<<t<<"次达到精度"<<endl;
flag=1;
break;
}
if(flag==1)break;
}
return 0;
}
程序运行调整学习率和次数依旧不收敛!!求解