zoukankan      html  css  js  c++  java
  • 数据挖掘之人工神经网络BP算法

    /*
    人工神经网络BP算法思想: 神经网络一般分为3层(也可以多层),包括输入层,隐含层和输出层。通过有监督的学习拟合非线性函数。假如输入层有3个神经元,隐含层有5个神经元,输出层有1个神经元。有监督的学习是指既给了输入也给了输出再进行样本训练。可以把该神经网络看做3维向量的输入,一维的输出。每一层的神经元与相邻的一层的神经元全连接,同层的神经元不连接。
    比如样本A的输入是{1,2,3},输出是{1},样本B的输入是{2,1,3},输出是{2},当然还有其他的样本,先通过前向传播得到神经元实际的输出值,计算期望值(即样本给的输出值)与输出值得均方误差,如果误差非常小,就不需要调整,否则反向传播调整连接权值(调整涉及到数学中的一些微分的知识)。直到拟合程度比较好时结束训练。此时有一个新的样本输入,不知道输出值,可以通过此神经网络预测输出值。
    */
    #include<cstdio> #include<iostream> #include<cmath> #include<time.h> #include<fstream> #include<cstdlib> using namespace std; #define RANDOM rand()/32767.0 const int Layer_Max=5; /**神经网络层数**/ const double PI=3.1415927; /**圆周率**/ const int Layer_number[Layer_Max]={2,4,4,2,1} ; /**每层神经元个数**/ const int Neural_Max=4; /**每层最大神经元个数**/ const int InMax=21; /**样本输入个数**/ ofstream Out_W_File("All_W.txt",ios::out); ofstream Out_Error("Error.txt",ios::out); /**定义类BP**/ class BP{ public: BP(); void BP_Print(); /**打印权系数**/ double F(double x); /**激发函数**/ double Y(double x1,double x2); /**要逼近的函数**/ double NetWorkOut(int x1,int x2); /**网络输出,它的输入为第input个样本**/ void AllLayer_D(int x1,int x2); /**求所有神经元的输出误差微分**/ void Change_W(); /**改变权系数**/ void Train(); /**训练函数**/ void After_Train_Out(); double Cost(double out,double Exp); /**代价函数**/ private: double W[Layer_Max][Neural_Max][Neural_Max]; /**W[i][j][k]表示第i层第j个神经元连接到前一层第k个神经元**/ double Input_Net[2][InMax];/**表示第i个样本的输入x1,x2**/ double Out_Exp[InMax][InMax]; /**期望输出**/ double Layer_Node[Layer_Max][Neural_Max]; /**各神经元的输出**/ double D[Layer_Max][Neural_Max]; /**各神经元的误差微分**/ double Study_Speed; /**学习率**/ double e; }; BP::BP(){ srand(time(NULL)); for(int i=1;i<Layer_Max;i++){ for(int j=0;j<Layer_number[i];j++){ for(int k=0;k<Layer_number[i-1]+1;k++) W[i][j][k]=RANDOM; /**权系数**/ //Q[i][j]=RANDOM; /**初始化各神经元阈值**/ } } /**输入和输出归一化**/ for(int l=0;l<InMax;l++){ /**输入的x1,x2**/ Input_Net[0][l]=l*0.05; Input_Net[1][l]=1-l*0.05; } for(int i=0;i<InMax;i++){ for(int j=0;j<InMax;j++){ Out_Exp[i][j]=Y(Input_Net[0][i],Input_Net[1][j]); /**期望输出**/ Out_Exp[i][j]=Out_Exp[i][j]/3.000000; /**归一化**/ } } Study_Speed=0.5; /**初始化学习度**/ e=0.0001; /**误差限制**/ } double BP::F(double x){ return (1.0/(1+exp(-x))); } /**Sigmoid函数**/ double BP::Y(double x1,double x2){ double temp; temp=pow(x1-1,4)+2*pow(x2,2); return temp; } /**代价函数**/ double BP::Cost(double Out,double Exp){ return (pow(Out-Exp,2)); /** 计算(Ok-dk)^2 **/ } double BP::NetWorkOut(int x1,int x2){ int i,j,k; double N_node[Layer_Max][Neural_Max];/**表示 第i层 第j个神经元 的总输入**/ /**第0层的神经元为输入,不用权系数和阈值**/ N_node[0][0]=Input_Net[0][x1]; Layer_Node[0][0]=Input_Net[0][x1]; N_node[0][1]=Input_Net[1][x2]; Layer_Node[0][1]=Input_Net[1][x2]; for(i=1;i<Layer_Max;i++){ for(j=0;j<Layer_number[i];j++){ N_node[i][j]=0.0; for(k=0;k<Layer_number[i-1];k++){ N_node[i][j]+=Layer_Node[i-1][k]*W[i][j][k]; } N_node[i][j]=N_node[i][j]-W[i][j][k]; /**减掉阈值**/ Layer_Node[i][j]=F(N_node[i][j]); /**得到输出**/ } } return Layer_Node[Layer_Max-1][0]; /**最后一层的输出**/ } void BP::AllLayer_D(int x1,int x2){ int i,j,k; double temp; D[Layer_Max-1][0]=Layer_Node[Layer_Max-1][0]*(1-Layer_Node[Layer_Max-1][0]) *(Layer_Node[Layer_Max-1][0]-Out_Exp[x1][x2]);/** Ok*(1-Ok)*(Ok-dk) **/ for(i=Layer_Max-1;i>0;i--){ for(j=0;j<Layer_number[i-1];j++){ temp=0; for(k=0;k<Layer_number[i];k++) temp=temp+W[i][k][j]*D[i][k];/****/ D[i-1][j]=Layer_Node[i-1][j]*(1-Layer_Node[i-1][j])*temp; } } } void BP::Change_W(){ int i,j,k; for(i=1;i<Layer_Max;i++){ for(j=0;j<Layer_number[i];j++){ for(k=0;k<Layer_number[i-1];k++){ W[i][j][k]=W[i][j][k]-Study_Speed*D[i][j]*Layer_Node[i-1][k]; } W[i][j][k]=W[i][j][k]+Study_Speed*D[i][j]; /** 修改阈值,相当于-(-1)*Study_Speed*D[i][j] **/ } } } void BP::Train(){ int i,j; int ok=0; double Out; long int count=0; double err; ofstream Out_count("Out_count.txt",ios::out); /**权系数变化保存在文件里**/ ofstream outWFile1("W[2][0][0].txt",ios::out); ofstream outWFile2("W[2][1][1].txt",ios::out); ofstream outWFile3("W[1][0][0].txt",ios::out); ofstream outWFile4("W[1][1][0].txt",ios::out); ofstream outWFile5("W[3][0][1].txt",ios::out); while(ok<441){ /**训练21*21个样本,当所有的误差精度都满足要求才退出**/ count++; for(i=0,ok=0;i<InMax;i++){ for(j=0;j<InMax;j++){ Out=NetWorkOut(i,j); AllLayer_D(i,j); err=Cost(Out,Out_Exp[i][j]); /**计算误差**/ if(err<e) ok++; /**是否满足误差精度**/ else Change_W(); /**修改权系数**/ } } if(count%1000==0){ cout<<count<<" "<<err<<endl; Out_count<<count<<","; Out_Error<<err<<","; outWFile1<<W[2][0][0]<<","; outWFile2<<W[2][1][1]<<","; outWFile3<<W[1][0][0]<<","; outWFile4<<W[1][1][0]<<","; outWFile5<<W[3][0][1]<<","; for(int p=1;p<Layer_Max;p++){ for(int j=0;j<Layer_number[p];j++){ for(int k=0;k<Layer_number[p-1]+1;k++){ Out_W_File<<'W'<<'['<<p<<']' <<'['<<j<<']' <<'['<<k<<']' <<'='<<W[p][j][k]<<' '<<' '; } } } Out_W_File<<' '<<' '; } } cout<<err<<endl; } void BP::BP_Print(){ cout<<"训练后的权系数"<<endl; for(int i=1;i<Layer_Max;i++){ for(int j=0;j<Layer_number[i];j++){ for(int k=0;k<Layer_number[i-1]+1;k++) cout<<W[i][j][k]<<" "; cout<<endl; } } cout<<endl<<endl; } void BP::After_Train_Out(){ int i,j; ofstream Out_x1("Out_x1.txt",ios::out); ofstream Out_x2("Out_x2.txt",ios::out); ofstream Out_Net("Out_Net.txt",ios::out); ofstream Out_Exp("Out_Exp.txt",ios::out); ofstream W_End("W_End.txt",ios::out); ofstream Q_End("Q_End.txt",ios::out); ofstream Array("Array.txt",ios::out); ofstream Out_x11("x1.txt",ios::out); ofstream Out_x22("x2.txt",ios::out); ofstream Result1("result1.txt",ios::out); ofstream Out_x111("x11.txt",ios::out); ofstream Out_x222("x22.txt",ios::out); ofstream Result2("result2.txt",ios::out); for(i=0;i<InMax;i++){ for(j=0;j<InMax;j++){ Out_x11<<Input_Net[0][i]<<","; Out_x22<<Input_Net[1][j]<<","; Result1<<3*NetWorkOut(i,j)<<","; Out_x1<<Input_Net[0][i]<<","; Array<<Input_Net[0][i]<<" "; Out_x2<<Input_Net[1][j]<<","; Array<<Input_Net[1][j]<<" "; Out_Net<<3*NetWorkOut(i,j)<<","; Array<<Y(Input_Net[0][i],Input_Net[1][j])<<" "; Out_Exp<<Y(Input_Net[0][i],Input_Net[1][j])<<","; Array<<3*NetWorkOut(i,j)<<" "; Array<<' '; } Out_x1<<' '; Out_x2<<' '; Out_x11<<' '; Out_x22<<' '; Result1<<' '; } for(j=0;j<InMax;j++){ for(i=0;i<InMax;i++){ Out_x111<<Input_Net[0][i]<<","; Out_x222<<Input_Net[1][j]<<","; Result2<<3*NetWorkOut(i,j)<<","; } Out_x111<<' '; Out_x222<<' '; Result2<<' '; } for(i=0;i<Layer_Max;i++){ for(j=0;j<Layer_number[i];j++){ for(int k=0;k<Layer_number[i-1]+1;k++) W_End<<W[i][j][k]<<","; } } } int main(void){ /* BP B; B.Train(); B.BP_Print(); B.After_Train_Out(); */ return 0; }
  • 相关阅读:
    Chandy-Lamport_algorithm
    3 differences between Savepoints and Checkpoints in Apache Flink
    列数 行数 表数 限制
    数据收集、传输、元数据管理、作业流调度、海量数据查询引擎、数据可视化
    分析云负载均衡产品
    端口被占用通过域名的处理 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则
    JSON Web Token
    查看开启端口的应用
    If the parts of an organization (e.g., teams, departments, or subdivisions) do not closely reflect the essential parts of the product, or if the relationship between organizations do not reflect the r
    微服务架构的理论基础
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/6642086.html
Copyright © 2011-2022 走看看