机器学习--BP神经网络的C++实现
来源:互联网 发布:c语言编写的交易程序 编辑:程序博客网 时间:2024/04/27 21:59
激活函数:Sigmoid
使用的是周志华老师的《机器学习》一书上的更新公式。
一共有三层,第一层是三维的,第二层是4维,输出层是1维。
#include <iostream>#include <cstdlib>#include <ctime>#include <cmath>using namespace std;#define innode 3 //输入结点数 #define outnode 1 //输出结点数 #define trainsample 8//BP训练样本数 #define INF 99999999 //定义无穷大//初始化权值void initialValue(double **weight1,double **weight2,double *bias1,double *bias2,int n1,int n2,int n3){ for(int i=0; i<n1; i++) { for(int j=0; j<n2; j++) { //用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,如果每次seed都设相同值,rand()所产生的随机数值每次就会一样 srand(time(NULL)); weight1[i][j]=rand()%100/(100.0); } } for(int i=0; i<n2; i++) { for(int j=0; j<n3; j++) { srand(time(NULL)); weight2[i][j]=rand()%100/(100.0); } } for(int i=0; i<n2; i++) { srand(time(NULL)); bias1[i]=rand()%100/(100.0); } for(int i=0; i<n3; i++) { srand(time(NULL)); bias2[i]=rand()%100/(100.0); }}double sigmoid(double x){ return 1/(1+exp(-x));}//计算样本实际输出void computeY(double **weight1,double **weight2,double *bias1,double *bias2,int n1,int n2,int n3,double X[innode],double predictY[outnode],double *hideY){ double sum=0; //计算隐层输出 for(int i=0; i<n2; i++) { for(int j=0; j<n1; j++) { sum += weight1[j][i]*X[j]; } sum=sigmoid(sum-bias1[i]); hideY[i]=sum; } sum=0; //计算最后一层输出 for(int i=0; i<n3; i++) { for(int j=0; j<n2; j++) { sum += weight2[j][i]*hideY[i]; } sum=sigmoid(sum-bias2[i]); predictY[i]=sum; }}//计算输出神经元的梯度void computeOutputDY(int n3,double predictY[outnode],double Y[outnode],double *outputDweight){ for(int i=0; i<n3; i++) { outputDweight[i]=predictY[i]*(1-predictY[i])*(Y[i]-predictY[i]); }}//计算隐藏神经元的梯度void computeHideDY(double **weight2,int n2,int n3,double *hideY,double *outputDweight,double *hideDweight){ for(int i=0; i<n2; i++) { double sum=0; for(int j=0; j<n3; j++) { sum+=weight2[i][j]*outputDweight[j]; } hideDweight[i]=hideY[i]*(1-hideY[i])*sum; }}//更新权值void updateWeight(double **weight1,double **weight2,double *bias1,double *bias2,int n1,int n2,int n3,double X[innode],double *hideY,double *outputDweight,double *hideDweight,double ratio){ for(int i=0; i<n1; i++) { for(int j=0; j<n2; j++) { weight1[i][j]+=ratio*hideDweight[j]*X[i]; } } for(int i=0; i<n2; i++) { for(int j=0; j<n3; j++) { weight2[i][j]+=ratio*outputDweight[j]*hideY[i]; } } for(int i=0; i<n2; i++) { bias1[i]-=ratio*hideDweight[i]; } for(int i=0; i<n3; i++) { bias2[i]-=ratio*outputDweight[i]; }}//计算均方误差double computeError(double predictY[outnode],double Y[outnode],int n){ double error=0.0; for(int i=0; i<n; i++) { error += ((predictY[i]-Y[i])*(predictY[i]-Y[i])); } return error;}int main(){ //三层神经网络,各层的维度 int n1=0,n2=0,n3=0; cout<<"输入各层的维度:"; cin>>n1>>n2>>n3; //输入层与隐层的连接权n1xn2,隐层与输出层的连接权n2xn3 double **weight1=new double*[n1]; for(int i=0;i<n1;i++) weight1[i]=new double[n2]; double **weight2=new double*[n2]; for(int i=0;i<n2;i++) weight2[i]=new double[n3]; //隐藏层的梯度项,输出层的梯度项 double *outputDweight = new double[n3]; double *hideDweight = new double[n2]; //隐层的偏置,输出层的偏置 double *bias1 = new double[n2]; double *bias2 = new double[n3]; //输入样本 n1=3,n3=1 double X[trainsample][innode]= {{0,0,0},{0,0,1},{0,1,0},{0,1,1},{1,0,0},{1,0,1},{1,1,0},{1,1,1}}; //期望输出样本 double Y[trainsample][outnode]={{0},{0.1429},{0.2857},{0.4286},{0.5714},{0.7143},{0.8571},{1.0000}}; //实际输出样本 double **predictY=new double*[trainsample]; for(int i=0;i<trainsample;i++) predictY[i]=new double[outnode]; //隐层输出样本 double *hideY=new double[n2]; //权值,偏置初始化 initialValue(weight1,weight2,bias1,bias2,n1,n2,n3); double error=INF; //学习率 double ratio=0.5; while(error>0.005) { error=0.0; for(int i=0; i<trainsample; i++) { //计算输出层的值 computeY(weight1,weight2,bias1,bias2,n1,n2,n3,X[i],predictY[i],hideY); //计算输出层的梯度项 computeOutputDY(n3,predictY[i],Y[i],outputDweight); //计算隐层的梯度项 computeHideDY(weight2,n2,n3,hideY,outputDweight,hideDweight); //更新权值 updateWeight(weight1,weight2,bias1,bias2,n1,n2,n3,X[i],hideY,outputDweight,hideDweight,ratio); //计算均方误差 error += computeError(predictY[i],Y[i],outnode); } error=0.5*error; } //输出网络的输出与实际输出的对应 for(int i=0; i<trainsample; i++) { for(int j=0; j<outnode; j++) { cout<<"predictY[i][j]::"<<predictY[i][j]<<"----"<<"Y[i][j]::"<<Y[i][j]<<endl; } } //释放空间 for(int i=0;i<n1;i++) { delete [] weight1[i]; } for(int i=0;i<n2;i++) { delete [] weight2[i]; } delete [] weight1; delete [] weight2; delete [] bias1; delete [] bias2;}
0 0
- 机器学习--BP神经网络的C++实现
- 机器学习与神经网络(四):BP神经网络的介绍和Python代码实现
- 机器学习之BP神经网络
- 机器学习BP神经网络,任意拓扑结构 (C++)
- 机器学习知识点(九)BP神经网络Java实现
- 机器学习02之BP神经网络图解及JAVA实现
- BP神经网络的学习以及实现
- BP神经网络的实现
- BP神经网络的实现
- BP神经网络的学习
- 神经网络学习笔记3:BP神经网络的实现及其应用
- BP神经网络和RNN神经网络的学习和实现。
- bp神经网络c语言实现
- BP神经网络-- C语言实现
- BP神经网络C代码实现
- BP神经网络-- C语言实现
- 【C++】神经网络BP算法实现
- 机器学习系列(6):BP神经网络
- Java 字符串的处理
- Solftmax解析
- linux find grep组合使用
- 学习中的思考与困惑
- Linux查找文件内容(grep)
- 机器学习--BP神经网络的C++实现
- 电脑常用技巧之关闭开机自启软件
- 如何使用CSS来编辑文本
- 数据库语言分类
- 动态爱心。
- Java堆内存Heap与非堆内存Non-Heap简介和设置
- spring事物的提交与回滚
- OSG-Win32窗口显示osg
- SAX详解