⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bp.txt

📁 神经网络bp算法
💻 TXT
字号:
#include "stdafx.h"
#include <string>
#include <cmath>
#include<ctime>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int N = 8;                                             //样本数量
const int d = 4;                                             //样本特征维数
const int nH = 3;                                           //隐含层元素个数,包括阙值
const int c = 1;                                             //每个样本的目标值都是1维的
const double error_limit = 0.01;                           //迭代结束的误差
const double rate = 0.05;                                    //学习率                      
const double momentum = 0.9;                           //冲量大小   
//
class weight{
    public:                                                    
double samples[N][d];                               //N个样本的d维特征空间
double weight_HI[nH][d];                            //输入层到隐含层权值
double weight_OH[c][nH];                            //隐含层到输出层权值
double old_weight_HI[nH][d];                     //前一时刻输入层和隐含层权重的变化率
double old_weight_OH[c][nH];                   //前一时刻输出层和隐含层权重的变化率  
double dweight_HI[nH][d];                            //输入层和隐含层权重的变化率
double dweight_OH[c][nH];                           //隐含层和输出层权重的变化率
double old_dweight_HI[nH][d];                       //输入层和隐含层上一次权重的变化率
double old_dweight_OH[c][nH];                       //隐含层和输出层上一次权重的变化率
double sensitity_k[c];                              //隐含层敏感度
double sensitity_j[nH];                             //输出层敏感度
double x[d];                                        //随机选择的样本
double y[nH];                                   //类的定义中,只能声明不能实例化,也就是不能有分配内存空间的变量
double z[c];                                    //在新的权值(weight_HI和weight_OH)下输出层的输出值
double net_j[nH];                                   //隐含层净值                               
double net_k[c];                                    //输出层层净值 
double t[N][c];                                     //N个样本的标准输出值
double t_now[c];                                    //当前样本的标准输出值
double error;                                       //准则函数误差变化率
//构造函数
weight(double s[N][d],double st[N][c]) {  
  for(int k = 0;k < c;k++) {
   sensitity_k[k] = 0;
  }
  for(int j = 0;j < nH;j++) {
   sensitity_j[j] = 0;
  }
  for(int n = 0;n < N;n++)
   for(int i = 0;i < d;i++) {
    samples[n] = s[n];
   }
  for(int n = 0;n < N;n++)
   for(int k = 0;k < c;k++) {
    t[n][k] = st[n][k];
   }
  
}

//输入层到隐含层权值初始化
    void ini_weight_HI(double wHI[nH][d]) {                  
  for(int j = 0;j < nH;j++)
   for(int i = 0;i < d;i++) {
    weight_HI[j] = wHI[j];
    old_weight_HI[j] = wHI[j]; 
   } 
}
//隐含层到输出层权值初始化
    void ini_weight_OH(double wOH[c][nH]) {                   
  for(int k = 0;k < c;k++)
   for(int j = 0;j < nH;j++) {
    weight_OH[k][j] = wOH[k][j];
                old_weight_OH[k][j] = wOH[k][j];
   } 
}

//输入层到隐含层权值初始化
    void ini_dweight_HI() {                                   
  for(int j = 0;j < nH;j++)
   for(int i = 0;i < d;i++) {
    dweight_HI[j] = 0;
   } 
}

//隐含层到输出层权值初始化
void ini_dweight_OH() {                                 
  for(int k = 0;k < c;k++)
   for(int j = 0;j < nH;j++) {
    dweight_OH[k][j] = 0;
   } 
}

//输入层到隐含层权值初始化
void ini_old_dweight_HI() {                              
  for(int j = 0;j < nH;j++)
   for(int i = 0;i < d;i++) {
    old_dweight_HI[j] = 0;
   } 
}

//隐含层到输出层权值初始化
void ini_old_dweight_OH() {                             
  for(int k = 0;k < c;k++)
   for(int j = 0;j < nH;j++) {
    old_dweight_OH[k][j] = 0;
   } 
}

//获取当前样本标准输出值
void obtain_t_now(double t[c]) {                        //获取当前样本标准输出值
  for(int k = 0;k < c;k++) {
   t_now[k] = t[k];
  }
}

//获取当前随机选择的样本
void obtain_x(double tem_x[d]) {                                //获取当前随机选择的样本
  for(int i = 0;i < d;i++) {
   x = tem_x;
  }
}

//计算y[j]以及net_j[j]
void obtain_y() {                               
  y[0] = 1;
  //
  for(int j = 1;j < nH;j++) { 
   //净值初始为零
   net_j[j] = 0;
   //计算净值
   for(int i = 0;i < d;i++) {
    net_j[j] += weight_HI[j] * x;
   }
   //计算净值输出
   y[j] = 1 / ( 1 + exp(-net_j[j]) );
  }
}
//计算z[k]
void obtain_z() {                               
  for(int k = 0;k < c;k++) {  
   //
   net_k[k] = 0;
   //
   for(int j = 0;j < nH;j++) {
    net_k[k] += weight_OH[k][j] * y[j];
   }
   z[k] = 1 / ( 1 + exp(-net_k[k]) );
  }                                               
}
//计算校正后输入层到隐含层的权值
void obtain_new_weight_HI(double rate) {           
  for(int j = 0;j < nH;j++) {                     
   //
   sensitity_j[j] = 0;                          
   //
   for(int k = 0;k < c;k++) {                  
    sensitity_j[j] += y[j] * (1- y[j]) * weight_OH[k][j] * sensitity_k[k];
   }
   //
   for(int i = 0;i < d;i++){
    //
    dweight_HI[j] = rate * sensitity_j[j] * x;
    //
    weight_HI[j] = weight_HI[j] + (momentum * dweight_HI[j] + (1 - momentum) * old_dweight_HI[j]);
    //
    old_dweight_HI[j] = dweight_HI[j];
   }
  } 
}
//计算校正后隐含层到输出层的权值
void obtain_new_weight_OH(double rate) {             
  for(int k = 0;k < c;k++) {
   //
            sensitity_k[k] = (t_now[k] - z[k]) * z[k] * (1 - z[k]);
   //
   for(int j = 0;j < nH;j++){
    //
    dweight_OH[k][j] = rate * sensitity_k[k] * y[j];
    //
    weight_OH[k][j] = weight_OH[k][j] + (momentum * dweight_OH[k][j] + (1 - momentum) * old_dweight_OH[k][j]);
    //
                old_dweight_OH[k][j] = dweight_OH[k][j];
   }
  }
}
//判断迭代是否结束
int if_over() {                                     
  error = 0;
  for(int n = 0;n < N;n++) {
   obtain_x(samples[n]);
   obtain_t_now(t[n]);
      obtain_y();
      obtain_z();
   for(int k = 0;k < c;k++) { 
    error += fabs( 0.5 * pow( z[k] - t_now[k],2 ) );
   }  
  }
  if( (error) < error_limit ) return 1;
  else return 0;        
}
};                                                                                               //分号;最容易误事 !
//
int main(){
//
double samples[N][d] = { {1,0,0,1},{1,0,0,0},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1} };  //最基本的数组初始化也忘了 !
double t[N][c] = {0.1,0.9,0.1,0.9,0.1,0.9,0.9,0.1};    
double test[8][4] = { {1,0,0,0},{1,1,1,1},{1,0.0,0.0,0.2},{1,0.0,0.0,0.8},{1,0.0,0.2,0.0},{1,0.0,0.8,0.0},{1,0.0,0.2,0.2},{1,0.0,0.8,0.8} };    
//
weight w_obj(samples,t);                                                             
w_obj.ini_dweight_HI();
w_obj.ini_dweight_OH();
w_obj.ini_old_dweight_HI();
w_obj.ini_old_dweight_OH();
//
srand((unsigned)time(0));                                                   
//随机初始化权值weight_OH
double random_weight_OH[c][nH]; 
for(int k = 0;k < c;k++)
  for(int j = 0;j < nH;j++) {
   random_weight_OH[k][j] = (double)( rand() % 100 ) / 100 - 0.5;             
  }                                                                              
w_obj.ini_weight_OH(random_weight_OH);                   
//随机初始化权值weight_HI
double random_weight_HI[nH][d]; 
for(int j = 0;j < nH;j++)
  for(int i = 0;i < d;i++) {
   random_weight_HI[j] = (double)( rand() % 100 ) / 100 - 0.5;
  }
//
w_obj.ini_weight_HI(random_weight_HI);
  w_obj.obtain_x(samples[n]);
  w_obj.obtain_t_now(t[n]);
  w_obj.obtain_y();
  w_obj.obtain_z();
}
//
cout<<"Begin"<<endl;
int count = 0;
int num;
int if_over = 0;
while( !if_over ) {
  num = rand() % N;
  w_obj.obtain_x(samples[num]);
  w_obj.obtain_t_now(t[num]);
  w_obj.obtain_y();
  w_obj.obtain_z();
  w_obj.obtain_new_weight_OH(rate);
  w_obj.obtain_new_weight_HI(rate);
  if_over = w_obj.if_over(); 
  count++;             //保存迭代次数
}
  getchar();
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -