BP神经网络算法(2)

 

//BpNet.h: interface for the Bp class.
// 2006.8.8 by 曾志军 版权所有  
//E-Mail:zengzhijun369@163.com
/**///
#include "stdafx.h"
#include 
"BpNet.h"
#include 
"math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

/**///
// Construction/Destruction
/**///

BpNet::BpNet()
{       
    error
=1.0;
    e
=0.0;
    
    rate_w
=0.05;  //权值学习率(输入层--隐含层)
    rate_w1=0.047//权值学习率 (隐含层--输出层)
    rate_b1=0.05//隐含层阀值学习率
    rate_b2=0.047//输出层阀值学习率
    error=1.0;
    e
=0.0;
    
    rate_w
=0.05;  //权值学习率(输入层--隐含层)
    rate_w1=0.047//权值学习率 (隐含层--输出层)
    rate_b1=0.05//隐含层阀值学习率
    rate_b2=0.047//输出层阀值学习率
}


BpNet::
~BpNet()
{
    
}


void winit(double w[],int sl)//权值初始化
{int i;
double randx();
for(i=0;i<sl;i++){
    
*(w+i)=0.2*randx();
}

}


double randx()//kqy error
{double d;
d
=(double) rand()/32767.0;
return d;
}


void BpNet::init()
{
    winit((
double*)w,innode*hidenode);
    winit((
double*)w1,hidenode*outnode);
    winit(b1,hidenode);
    winit(b2,outnode);
}



void BpNet::train(double p[trainsample][innode],double t[trainsample][outnode])
{
    
double pp[hidenode];//隐含结点的校正误差
    double qq[outnode];//希望输出值与实际输出值的偏差
    double yd[outnode];//希望输出值
    
    
double x[innode]; //输入向量
    double x1[hidenode];//隐含结点状态值
    double x2[outnode];//输出结点状态值
    double o1[hidenode];//隐含层激活值
    double o2[hidenode];//输出层激活值
    for(int isamp=0;isamp<trainsample;isamp++)//循环训练一次样品
    
        
for(int i=0;i<innode;i++)
            x[i]
=p[isamp][i];
        
for(i=0;i<outnode;i++)
            yd[i]
=t[isamp][i];
        
        
//构造每个样品的输入和输出标准
        for(int j=0;j<hidenode;j++)
        
{
            o1[j]
=0.0;
            
            
for(i=0;i<innode;i++)
                o1[j]
=o1[j]+w[i][j]*x[i];//隐含层各单元输入激活值
            x1[j]=1.0/(1+exp(-o1[j]-b1[j]));//隐含层各单元的输出kqy1
            
//    if(o1[j]+b1[j]>0) x1[j]=1;
            
//else x1[j]=0;
        }

        
        
for(int k=0;k<outnode;k++)
        
{
            o2[k]
=0.0;
            
            
for(j=0;j<hidenode;j++)
                o2[k]
=o2[k]+w1[j][k]*x1[j];//输出层各单元输入激活值
            x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//输出层各单元输出
            
//    if(o2[k]+b2[k]>0) x2[k]=1;
            
//    else x2[k]=0;
        }

        
        
for(k=0;k<outnode;k++)
        
{
            e
=0.0;
            qq[k]
=(yd[k]-x2[k])*x2[k]*(1.-x2[k]);//希望输出与实际输出的偏差
            e+=fabs(yd[k]-x2[k])*fabs(yd[k]-x2[k]);//计算均方差
            
            
for(j=0;j<hidenode;j++)
                w1[j][k]
=w1[j][k]+rate_w1*qq[k]*x1[j];//下一次的隐含层和输出层之间的新连接权
            e=sqrt(e);
            error
=e;
        
        }

        
        
for(j=0;j<hidenode;j++)
        
{
            pp[j]
=0.0;
            
for(k=0;k<outnode;k++)
                pp[j]
=pp[j]+qq[k]*w1[j][k];
            pp[j]
=pp[j]*x1[j]*(1-x1[j]);//隐含层的校正误差
            
            
for(i=0;i<innode;i++)
                w[i][j]
=w[i][j]+rate_w*pp[j]*x[i];//下一次的输入层和隐含层之间的新连接权
        }

        
        
for(k=0;k<outnode;k++)
            b2[k]
=b2[k]+rate_b2*qq[k];//下一次的隐含层和输出层之间的新阈值
        for(j=0;j<hidenode;j++)
            b1[j]
=b1[j]+rate_b1*pp[j];//下一次的输入层和隐含层之间的新阈值
        
    }
//end isamp样品循环
    
}

/**////end train/////

/////


double *BpNet::recognize(double *p)
{   
    
double x[innode]; //输入向量
    double x1[hidenode];//隐含结点状态值
    double x2[outnode];//输出结点状态值
    double o1[hidenode];//隐含层激活值
    double o2[hidenode];//输出层激活值

    
for(int i=0;i<innode;i++)
        x[i]
=p[i];
    
for(int j=0;j<hidenode;j++)
    
{
        o1[j]
=0.0;
        
        
for(int i=0;i<innode;i++)
            o1[j]
=o1[j]+w[i][j]*x[i];//隐含层各单元激活值
        x1[j]=1.0/(1.0+exp(-o1[j]-b1[j]));//隐含层各单元输出
        
//if(o1[j]+b1[j]>0) x1[j]=1;
        
//    else x1[j]=0;
    }

    
    
for(int k=0;k<outnode;k++)
    
{
        o2[k]
=0.0;
        
for(int j=0;j<hidenode;j++)
            o2[k]
=o2[k]+w1[j][k]*x1[j];//输出层各单元激活值
        x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//输出层各单元输出
        
//if(o2[k]+b2[k]>0) x2[k]=1;
        
//else x2[k]=0;
    }
 
    
    
for(k=0;k<outnode;k++)
    
{
        shuchu[k]
=x2[k];
    }
 
    
return shuchu;
}
/**/////end sim///

void BpNet::writetrain()
{//曾志军 for 2006.7
    AfxMessageBox("你还没有训练呢,训练后再写吧!请不要乱写,除非你认为这次训练是最好的,否则会覆盖我训练好的权值,那样你又要花时间训练!");
    AfxMessageBox(
"你认为这次训练结果是最好的,就存下来,下次就不要花时间训练了!",MB_YESNO,NULL);
    FILE 
*stream0;
    FILE 
*stream1;
    FILE 
*stream2;
    FILE 
*stream3;
    
int i,j;
    
/**/
    if(( stream0 = fopen("w.txt""w+" ))==NULL)
    
{
        AfxMessageBox(
"创建文件失败!");
    }

    
for(i=0;i<innode;i++)
    
{
        
for(j=0;j<hidenode;j++)
        
{
            
            fprintf(stream0, 
"%f\n", w[i][j]);
        }

        
    }

    fclose( stream0);
    
/**////
    if(( stream1 = fopen("w1.txt""w+" ))==NULL)
    
{
        AfxMessageBox(
"创建文件失败!");
    }

    
for(i=0;i<hidenode;i++)
    
{
        
for(j=0;j<outnode;j++)
        
{
            fprintf(stream1, 
"%f\n",w1[i][j]);
        }

        
    }

    fclose( stream1);
    
/**/////
    if(( stream2 = fopen("b1.txt""w+" ))==NULL)
    
{
        AfxMessageBox(
"创建文件失败!");
    }

        
for(i=0;i<hidenode;i++)
    
{
        fprintf(stream2, 
"%f\n",b1[i]);
        
        
    }

    fclose( stream2);
    
/**//
    if(( stream3 = fopen("b2.txt""w+" ))==NULL)
    
{
        AfxMessageBox(
"创建文件失败!");
    }

    
for(i=0;i<outnode;i++)
    
{
        fprintf(stream3, 
"%f\n",b2[i]);
        
        
    }

    fclose( stream3);
    
    
}



void BpNet::readtrain()
{
    
//曾志军 for 2006.7
    AfxMessageBox("读入已训练好的权值,这样你就不要花时间训练了!",MB_YESNO,NULL);
    FILE 
*stream0;
    FILE 
*stream1;
    FILE 
*stream2;
    FILE 
*stream3;
    
int i,j;
    
/**//////
    if(( stream0 = fopen("w.txt""r" ))==NULL)
    
{
        AfxMessageBox(
"文件不存在,请先写入权值,再读!");
    }

    
    
float  wx[innode][hidenode];
    
for(i=0;i<innode;i++)
        
for(j=0;j<hidenode;j++)
        
{
            fscanf(stream0, 
"%f"&wx[i][j]);
            w[i][j]
=wx[i][j];
        }

    fclose( stream0);
    
/**////    
    if(( stream1 = fopen("w1.txt""r" ))==NULL)
        
{
            AfxMessageBox(
"文件不存在,请先写入权值,再读!");
        }

         
float  wx1[hidenode][outnode]; 
        
for(i=0;i<hidenode;i++)
        
{
            
for(j=0;j<outnode;j++)
            
{
                fscanf(stream1, 
"%f"&wx1[i][j]);
                w1[i][j]
=wx1[i][j];
            }

            
        }

        fclose( stream1);
        
        
/**////
        if(( stream2 = fopen("b1.txt""r" ))==NULL)
        
{
            AfxMessageBox(
"文件不存在,请先写入权值,再读!");
        }

        
float xb1[hidenode];    
        
for(i=0;i<hidenode;i++)
        
{
            fscanf(stream2, 
"%f",&xb1[i]);
            b1[i]
=xb1[i];
        }

        fclose( stream2);
        
/**///
        if(( stream3 = fopen("b2.txt""r" ))==NULL)
        
{
            AfxMessageBox(
"文件不存在,请先写入权值,再读!");
        }

        
float xb2[outnode];  
        
for(i=0;i<outnode;i++)
        
{
            fscanf(stream3, 
"%f",&xb2[i]);
            b2[i]
=xb2[i];
        }

        
        fclose( stream3);
        
/**//*CFile TheFile("w.txt",CFile::modeRead);
        CArchive ar(&TheFile,CArchive::load,40960);
        TheFile.SeekToBegin();
        int i,j;
        for(i=0;i<innode;i++)
        {
        for(j=0;j<hidenode;j++)
        {   
        ar>>w[i][j];
        
          }
          
            }
            ar.Close();
        TheFile.Close();
*/

        
}

//BpNet.h: interface for the Bp class.
// 2006.8.8 by 曾志军 版权所有  
//E-Mail:zengzhijun369@163.com
/**///

#if !defined(AFX_BPNET_H__3A171E41_1E8B_11D7_BA67_936006E9954B__INCLUDED_)
#define AFX_BPNET_H__3A171E41_1E8B_11D7_BA67_936006E9954B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#define  innode 5  //输入结点数
#define  hidenode 10//隐含结点数
#define  outnode 4 //输出结点数
#define  trainsample 500//BP训练样本为10个
class BpNet  
{
public:
    
void train(double p[trainsample][innode ],double t[trainsample][outnode]);//Bp训练
    
//double p[trainsample][innode]     //输入的样本
    
//double t[trainsample][outnode]//样本要输出的
    
//Bp训练前要调用readtemplate()
    double *recognize(double *p);//Bp识别
    
    
void writetrain();//写训练完的权值
    void readtrain();//读训练好的权值,这使的不用每次去训练了,只要把训练最好的权值存下来writetrain()就OK!
    
    BpNet();
    
virtual ~BpNet();


public:
    
void init();
    
double w[innode][hidenode];//隐含结点权值
    double w1[hidenode][outnode];//输出结点权值
    double b1[hidenode];//隐含结点阀值
    double b2[outnode];//输出结点阀值
    
    
double rate_w; //权值学习率(输入层-隐含层)
    double rate_w1;//权值学习率 (隐含层-输出层)
    double rate_b1;//隐含层阀值学习率
    double rate_b2;//输出层阀值学习率

    
    
double e;//误差计算
    double error;//允许的最大误差
    double shuchu[outnode];// Bp输出
    

}
;

#endif // !defined(AFX_BPNET_H__3A171E41_1E8B_11D7_BA67_936006E9954B__INCLUDED_)

全文参考:http://www.cnblogs.com/demon521/archive/2008/04/07/1140359.html

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值