BP神经网络 c++实现
来源:互联网 发布:刀剑乱舞极化数据 编辑:程序博客网 时间:2024/05/17 13:10
#include <iostream>#include <cmath>#include "stdio.h"#include "stdlib.h"#include "time.h"using namespace std;#define innode 8 //输入结点数#define hidenode 4 //隐含结点数#define outnode 8 //输出结点数#define trainsample 8 //BP训练样本数class BpNet{public: void train(double p[trainsample][innode], double t[trainsample][outnode]);//Bp训练 double p[trainsample][innode]; //输入的样本 double t[trainsample][outnode]; //样本要输出的 double *recognize(double *p); //Bp识别 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 result[outnode]; // Bp输出};BpNet::BpNet(){ error=1.0; e=0.0; rate_w = 0.1; //权值学习率(输入层--隐含层) rate_w1 = 0.1; //权值学习率 (隐含层--输出层) rate_b1 = 0.1; //隐含层阀值学习率 rate_b2 = 0.1; //输出层阀值学习率}BpNet::~BpNet(){}//产生[low, high)之间的随机数double randval(double low, double high) { double val; val = ((double)(rand() % RAND_MAX)/(double)RAND_MAX) * (high - low) + low; return(val); }void winit(double w[], int n) //权值初始化{ for(int i=0; i<n; i++) w[i] = randval(-0.01, 0.01);}//初始化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++) //循环训练一次样品 { int i, j, k; for(i=0; i<innode; i++) x[i] = p[isamp][i]; //输入的样本 for(i=0; i<outnode; i++) yd[i] = t[isamp][i]; //希望输出的样本 //正向传播 //构造每个样品的输入和输出标准 for(j=0; j<hidenode; j++) { o1[j] = 0.0; for(i=0; i< innode; i++) o1[j] += w[i][j] * x[i]; //隐含层各单元输入激活值 x1[j] = 1.0 / (1.0 + exp(-o1[j] - b1[j])); //隐含层各单元的输出 } for(k=0; k<outnode; k++) { o2[k] = 0.0; for(int j=0; j<hidenode; j++) o2[k] += w1[j][k] * x1[j]; //输出层各单元输入激活值 x2[k] = 1.0 / (1.0 + exp(-o2[k] - b2[k])); //输出层各单元输出 } //误差反向传播 for(k=0; k<outnode; k++) //对于网络中每个输出单元,计算误差项,并更新权值 { qq[k] = (yd[k] - x2[k]) * x2[k] * (1-x2[k]); //希望输出与实际输出的偏差 for(j=0; j<hidenode; j++) w1[j][k] += rate_w1 * qq[k] * x1[j]; //更新隐含层和输出层之间的连接权 } for(j=0; j<hidenode; j++) //对于网络中每个隐藏单元,计算误差项,并更新权值 { pp[j] = 0.0; for(k=0; k<outnode; k++) 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] += rate_w * pp[j] * x[i]; //更新输入层和隐含层之间的连接权 } for(k=0; k<outnode; k++) { e += pow(yd[k] - x2[k], 2); //计算均方差 } error = e/2.0; for(k=0; k<outnode; k++) b2[k] += rate_b2 * qq[k]; //更新隐含层和输出层之间的阈值 for(j=0; j<hidenode; j++) b1[j] += rate_b1 * pp[j]; //更新输入层和隐含层之间的阈值 }}//识别double *BpNet::recognize(double *p){ double x[innode]; //输入向量 double x1[hidenode]; //隐含结点状态值 double x2[outnode]; //输出结点状态值 double o1[hidenode]; //隐含层激活值 double o2[hidenode]; //输出层激活值 int i, j, k; for(i=0; i<innode; i++) x[i] = p[i]; for(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.0 + exp(-o1[j] - b1[j])); //隐含层各单元输出 } for(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])); //输出层各单元输出 } for(k=0; k<outnode; k++) { result[k] = x2[k]; } return result;}//输入样本double X[trainsample][innode] = { {1,0,0,0,0,0,0,0}, {0,1,0,0,0,0,0,0}, {0,0,1,0,0,0,0,0}, {0,0,0,1,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,0,0,0,1,0,0}, {0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1}};int main(){ srand(time(NULL)); int i, j, k; BpNet bp; bp.init(); int times = 0; while(bp.error > 0.0001 && times < 5000) { bp.e = 0.0; times++; bp.train(X, X); } double m[innode] = {0,0,1,0,0,0,0,0}; bp.recognize(m); for(i=0; i<innode; ++i) cout << m[i]; cout << " is "; for(i=0; i<outnode; i++) printf("%d", (int)floor(bp.result[i] + 0.5)); cout << endl; return 0;}
当将隐藏结点数设置为:13,可以识别任意2个位置为1的二进制数
参考资料:
http://www.cnblogs.com/luxiaoxun/archive/2012/12/10/2811309.html
机器学习. Tom M.Mitchell
1 0
- bp神经网络c语言实现
- BP神经网络-- C语言实现
- BP神经网络C代码实现
- BP神经网络-- C语言实现
- 【C++】神经网络BP算法实现
- 神经网络BP算法(C程序实现)
- BP神经网络-- C语言实现 上
- c语言实现3层bp神经网络
- BP神经网络-- C语言实现 上
- BP神经网络-- C语言实现 下
- BP神经网络C程序
- BP神经网络+c代码
- BP神经网络算法实现
- BP神经网络算法实现
- java实现BP神经网络
- Matlab实现BP神经网络
- matlab实现BP神经网络
- BP神经网络Python实现
- 对仗(约瑟夫问题)
- VMware Workstation的简要介绍
- C 小技巧-换颜色
- JS学习(1)-JavaScript in HTML
- c++long和int的区别
- BP神经网络 c++实现
- 隔壁(贪心)
- 推荐子龙山人的emacs的教程
- IOS-—UICollectionView使用综述(二 )(基础篇--画廊展示图片,瀑布流展示图片)
- java 数据结构与算法
- ECharts图表组件之简单关系图:如何轻松实现另类站点地图且扩展节点属性实现点击节点页面跳转
- LeetCode------------palindrome-partitioning(回文)
- leetcode15&16_3Sum&4Sum
- HTTP2.0