设为首页 加入收藏

TOP

BP神经网络 c++实现(一)
2017-06-14 10:22:50 】 浏览:364
Tags:神经网络 实现

BP神经网络 c++实现
BP神经网络是通过反向传播来逐渐修正层之间的权值和每个节点的阈值,可以通过学习率避免走入局部最优解。

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          using namespace std; #define LAYER 3 //三层神经网络 #define NUM 10 //每层的最多节点数 #define A 30.0 #define B 10.0 //A和B是S型函数的参数 #define ITERS 10000 //最大训练次数 #define LR 0.0013 //学习率 #define ERROR 0.1 //单个样本允许的误差 struct Data { vector
         
           x; //输入数据 vector
          
            y; //输出数据 }; class BP{ public: void GetData(const vector
           
            ); void Train(); vector
            
              ForeCast(const vector
             
              ); private: void InitNetWork(); //初始化网络 void GetNums(); //获取输入、输出和隐含层节点数 void ForwardTransfer(); //正向传播子过程 void ReverseTransfer(int); //逆向传播子过程 void CalcDelta(int); //计算w和b的调整量 void UpdateNetWork(); //更新权值和阀值 double GetError(int); //计算单个样本的误差 double GetAccu(); //计算所有样本的精度 double Sigmoid(const double); //计算Sigmoid的值 private: int in_num; //输入层节点数 int ou_num; //输出层节点数 int hd_num; //隐含层节点数 vector
              
                data; //输入输出数据 double w[LAYER][NUM][NUM]; //BP网络的权值 double b[LAYER][NUM]; //BP网络节点的阀值 double x[LAYER][NUM]; //每个神经元的值经S型函数转化后的输出值,输入层就为原值 double d[LAYER][NUM]; //记录delta学习规则中delta的值 }; //获取训练所有样本数据 void BP::GetData(const vector
               
                 _data) { data = _data; } //开始进行训练 void BP::Train() { printf("Begin to train BP NetWork!\n"); GetNums(); InitNetWork(); int num = data.size(); for(int iter = 0; iter <= ITERS; iter++) { for(int cnt = 0; cnt < num; cnt++) { //第一层输入节点赋值 for(int i = 0; i < in_num; i++) x[0][i] = data[cnt].x[i]; while(1) { ForwardTransfer(); if(GetError(cnt) < ERROR) //如果误差比较小,则针对单个样本跳出循环 break; ReverseTransfer(cnt); } } printf("This is the %d th trainning NetWork !\n", iter); double accu = GetAccu(); printf("All Samples Accuracy is %lf\n", accu); } printf("The BP NetWork train End!\n"); } //根据训练好的网络来预测输出值 vector
                
                  BP::ForeCast(const vector
                 
                   data) { int n = data.size(); assert(n == in_num); for(int i = 0; i < in_num; i++) x[0][i] = data[i]; ForwardTransfer(); vector
                  
                    v; for(int i = 0; i < ou_num; i++) v.push_back(x[2][i]); return v; } //获取网络节点数 void BP::GetNums() { in_num = data[0].x.size(); //获取输入层节点数 ou_num = data[0].y.size(); //获取输出层节点数 hd_num = (int)sqrt((in_num + ou_num) * 1.0) + 5; //获取隐含层节点数 if(hd_num > NUM) hd_num = NUM; //隐含层数目不能超过最大设置 } //初始化网络 void BP::InitNetWork() { memset(w, 0, sizeof(w)); //初始化权值和阈值为0,也可以初始化随机值 memset(b, 0, sizeof(b)); } //工作信号正向传递子过程 void BP::ForwardTransfer() { //计算隐含层各个节点的输出值 for(int j = 0; j < hd_num; j++) { double t = 0; for(int i = 0; i < in_num; i++) t += w[1][i][j] * x[0][i]; t += b[1][j]; x[1][j] = Sigmoid(t); } //计算输出层各节点的输出值 for(int j = 0; j < ou_num; j++) { double t = 0; for(int i = 0; i < hd_num; i++) t += w[2][i][j] * x[1][i]; t += b[2][j]; x[2][j] = Sigmoid(t); } } //计算单个样本的误差 double BP::GetError(int cnt) { double ans = 0; for(int i = 0; i < ou_num; i++) ans += 0.5 * (x[2][i] - data[cnt].y[i]) * (x[2][i] - data[cnt].y[i]); return ans; } //误差信号反向传递子过程 void BP::ReverseTransfer(int cnt) { CalcDelta(cnt);//计算调整量 UpdateNetWork();//根据调整量调节权值和阈值 } //计算所有样本的精度 double BP::GetAccu() { double ans = 0; int num = data.size(); for(int i = 0; i < num; i++) { int m = data[i].x.size(); for(int j = 0; j < m; j++) x[0][j] = data[i].x[j]; ForwardTransfer(); ans += fabs(x[2][0] - data[i].y[0]) <= 0.5 ? 1 : 0; } return ans / num; } //计算调整量 void BP::CalcDelta(int cnt) { //计算输出层的delta值 for(int i = 0; i < ou_num; i++) d[2][i] = (x[2][i] - data[cnt].y[i]) * x[2][i] * (A - x[2][i]) / (A * B); //计算隐含层的delta值 for(int i = 0; i < hd_num; i++)
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇BP神经网络 下一篇C++ vector容器

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目