BP神经网络的设计应注意以下几个问题:

1.  网络的层数。一般三层网络结构就可以逼近任何有理函数。增加网络层数虽然可以提高计算精度,减少误差,但也使得网络复杂化,增加网络训练时间。如果实在想增加层数,应优先增加隐含层的神经数。

2.  隐含层的神经单元数。网络训练精度的提高,可以通过采用一个隐含层而增加神经元数的方法获得。具体设计上可以使隐含层是输入层的2倍,然后再适当增加一点余量。

3.  初始权值选择。一般区随机权值是(-1, 1)的随机数。

4.  学习速率。学习速率决定每一次循环训练所产生的权值变化量。高的学习速率可能导致系统的不稳定性,但低的学习速率导致较长的训练时间,可能收敛变慢。一般取0.01~08。可以通过比较不同速率所得到误差选择合适的值。

5.  误差选取。在网络的训练过程中,误差的选取也应当通过对比训练后确定一个合适的值,也即相对于所需要的隐含层的节点数确定。

计算步骤和原理如下图:

测试数据如下:

114.6 1.1 0.71 85.0 346
132.4 0.97 0.54 73.0 410
103.5 0.96 0.66 67.0 385
179.3 0.88 0.59 89.0 446
92.7 1.15 0.44 154.0 300
115.0 0.74 0.65 252.0 453
163.6 0.85 0.58 220.0 495
139.5 0.70 0.59 217.0 478
76.7 0.95 0.51 162.0 341
42.1 1.08 0.47 110.0 326
77.8 1.19 0.57 91.0 364
100.6 0.82 0.59 83.0 456
55.3 0.96 0.4 69.0 300
152.1 1.04 0.49 77.0 433
81.0 1.08 0.54 96.0 336
29.8 0.83 0.49 120.0 289
248.6 0.79 0.5 147.0 483
64.9 0.59 0.5 147.0 483
95.7 1.02 0.48 160.0 384
89.9 0.96 0.39 105.0 314
121.8 0.83 0.60 140.0 401
78.5 0.89 0.44 94.0 280
90.0 0.95 0.43 89.0 301

代码如下:

#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"
#include "vector"
using namespace std;

#define noiseVar 0.01   //噪声强度(防止过度拟合)
#define errorVar  0.001  //误差设置 
#define alpha 0.35   //学习效率
#define loopNum 10000  //最大的循环次数
#define hideNum 10  //中间层隐节点数
#define dimNum 5  //维数
#define dimIn 4   //输入层维数
#define dimOut 1   //输出层维数
#define INF 99999

typedef vector<double> doubleVector;
doubleVector maxSamp;
doubleVector minSamp;

vector<doubleVector> getFileInf(char *File);  //获取训练样本
vector<doubleVector> Normalization(vector<doubleVector> sample);  //样本归一化
double getRandNum();  //获取随机数
void startTrain(vector<doubleVector> sample);  //开始训练
void useBP(vector<doubleVector> WX, vector<doubleVector> WY);  //使用BP神经网络

void main()
{
char *File = "BP.txt";
vector<doubleVector> sample;

sample = getFileInf(File);   //获取样本
sample = Normalization(sample);  //样本归一化

startTrain(sample);  //开始训练

}

//开始训练
void startTrain(vector<doubleVector> sample)
{
int i, j, k, l ,m ,n;
vector<doubleVector> WX;  //输入层与隐层间的权值
vector<doubleVector> WY;  //隐层间与输出层的权值
doubleVector ThreX;    //输入层与隐含层之间的阈值 
doubleVector ThreY;    //输出层与隐含层之间的阈值
doubleVector temp;

//获取随机权重(0.01~0.8)
srand(time(NULL));
//输入层与隐层间的权值
for(i=0; i<hideNum; i++)
{
temp.clear();
for(j=0; j<dimIn; j++)
temp.push_back(getRandNum());
WX.push_back(temp);
}

//隐层间与输出层的权值
for(i=0; i<dimOut; i++)
{
temp.clear();
for(j=0; j<hideNum; j++)
temp.push_back(getRandNum());
WY.push_back(temp);
}

//输入层与隐含层之间的阈值 
for(i=0; i<hideNum; i++)
ThreX.push_back(getRandNum());

//输出层与隐含层之间的阈值
for(i=0; i<dimOut; i++)
ThreY.push_back(getRandNum());

//开始循环训练
double sum;
doubleVector hideOut(hideNum);  //隐含层输出
doubleVector oOut(dimOut);   //输出层输出
double oldE, newE;   //希望输出与计算输出的偏方差的均方值
doubleVector outError;  //输出层的误差
doubleVector hideError;  //隐含层的误差
int flag = 0;

oldE = newE = 0;
for(i=0; i<loopNum; i++)
{
oldE = newE;
newE = 0;
for(j=0; j<sample.size(); j++)
{
outError.clear();
outError.clear();
hideOut.clear();
oOut.clear();
//隐含层各节点的输入、输出
for(k=0; k<hideNum; k++)
{
sum = 0;
for(l=0; l<dimIn; l++)
sum += sample[j][l]*WX[l][k];
hideOut.push_back(1/(1+exp(-(sum-ThreX[k]))));
}

//输出层各节点的输入、输出
for(k=0; k<dimOut; k++)
{
sum = 0;
for(l=0; l<hideNum; l++)
sum += hideOut[l]*WY[k][l];
oOut.push_back(1/(1+exp(-sum-ThreY[k])));
}

//计算希望输出与计算输出的偏方差的均方值
for(k=0; k<dimOut; k++)
newE += (sample[j][dimIn+k]-oOut[k])*(sample[j][dimIn+k]-oOut[k])/2.0;

//计算输出层各节点的误差
for(k=0; k<dimOut; k++)
outError.push_back((sample[j][dimIn+k]-oOut[k])*oOut[k]*(1-oOut[k]));

//计算隐含层各节点误差
for(k=0; k<hideNum; k++)
{
sum = 0;
for(l=0; l<dimOut; l++)
sum += outError[l]*WY[l][k];

hideError.push_back(sum*hideOut[k]*(1-hideOut[k]));
}

//修正输入层与隐含层权值
for(m=0; m<hideNum; m++)
for(n=0; n<dimIn; n++)
WX[m][n] = WX[m][n]+alpha*hideError[m]*sample[j][n];

//修正隐层间与输出层的权值
for(m=0; m<dimOut; m++)
for(n=0; n<hideNum; n++)
WY[m][n] = WY[m][n]+alpha*outError[m]*hideOut[n];

//修正输入层与隐含层阀值
for(m=0; m<hideNum; m++)
ThreX[m] = ThreX[m]-alpha*hideError[m];

//修正隐层间与输出层的阀值
for(m=0; m<dimOut; m++)
ThreX[m] = ThreY[m]-alpha*outError[m];

}

//误差判断
if(newE/sample.size()<errorVar)
{
printf("训练结束!\n训练次数为: %d  %lf\n", i, newE);
break;
}
}

printf("隐含层权值:\n");
for(i=0; i<hideNum; i++)
{
for(j=0; j<dimIn; j++)
printf("%lf  ", WX[i][j]);
printf("\n");
}

printf("\n");

printf("输出层权值:\n");
for(i=0; i<hideNum; i++)
{
for(j=0; j<dimOut; j++)
printf("%lf  ", WX[i][j]);
printf("\n");
}

useBP(WX, WY);

}

//使用BP神经网络
void useBP(vector<doubleVector> WX, vector<doubleVector> WY)
{
int i, j;

double Input[dimIn];
doubleVector hideOut;
doubleVector oOut;
double sum;

while(1)
{
hideOut.clear();
oOut.clear();

printf("\n输入数据:\n");
for(i=0; i<dimIn; i++)
scanf("%lf", &Input[i]);

//待测样本归一化
for(i=0; i<dimIn; i++)
Input[i] = (0.002+0.996*(Input[i]-minSamp[i]))/(maxSamp[i]-minSamp[i]);

//隐含层各节点的输入、输出
for(i=0; i<hideNum; i++)
{
sum = 0;
for(j=0; j<dimIn; j++)
sum += Input[j]+WX[j][i];
hideOut.push_back(1/(1+exp(-sum)));
}

//输出层各节点的输入、输出
for(i=0; i<dimOut; i++)
{
sum = 0;
for(j=0; j<hideNum; j++)
sum += hideOut[j]*WY[i][j];
oOut.push_back(1/(1+exp(-sum)));
}

for(i=0; i<oOut.size(); i++)
oOut[i] = (oOut[i]*(maxSamp[dimIn+i]-minSamp[dimIn+i])-0.02)/0.996+minSamp[dimIn+i];

printf("期望结果:\n");
for(i=0; i<oOut.size(); i++)
printf("%lf   ", oOut[i]);
printf("\n\n");

}

}

//样本归一化
vector<doubleVector> Normalization(vector<doubleVector> sample)
{
vector<doubleVector> dst;
int i, j;

doubleVector max(dimNum, 0);
doubleVector min(dimNum, INF);
doubleVector temp;

//寻找样本最大值和最小值
for(i=0; i<dimNum; i++)
for (j=0; j<sample.size(); j++)
{
if(max[i]<sample[j][i])
max[i] = sample[j][i];
if(min[i]>sample[j][i])
min[i] = sample[j][i];
}

minSamp = min;
maxSamp = max;

//样本归一化
for(i=0; i<sample.size(); i++)
{
temp.clear();
for(j=0; j<dimNum; j++)
temp.push_back((0.002+0.996*(sample[i][j]-min[j]))/(max[j]-min[j]));

dst.push_back(temp);
}

return dst;
}

//获取文件数据
vector<doubleVector> getFileInf(char *File)
{
int i=1;
vector<doubleVector> dst;
doubleVector temp;
double num;

FILE *fp;

fp = fopen(File, "r");

if(fp == NULL)
{
printf("Open file error!\n");
exit(0);
}

//读取文件的数据
while(fscanf(fp, "%lf", &num)!=EOF)
{
temp.push_back(num);
if(i%dimNum==0)
{
dst.push_back(temp);
temp.clear();
}
i++;
}

fclose(fp);

return dst;
}

//获取随机数
double getRandNum()
{
double num;

num = rand()%RAND_MAX;
num = 0.8*num/RAND_MAX;

return num;
}

BP神经网络+c代码相关推荐

  1. gwo算法matlab源代码,智能优化算法应用:基于GWO优化BP神经网络 - 附代码

    智能优化算法应用:基于GWO优化BP神经网络 - 附代码 智能优化算法应用:基于GWO优化BP神经网络 - 附代码 智能优化算法应用:基于GWO优化BP神经网络 文章目录智能优化算法应用:基于GWO优 ...

  2. BP神经网络python代码详细解答(来自原文翻译)

    翻译如下 ** <font color=black size=6.5> 在 SCRATCH采用python 上实现一种神经网络 **         注: Scratch是一款由麻省理工学 ...

  3. C++实现的BP神经网络(代码与详解)

    前言:本文为原创 若有错误欢迎评论! 描述部分 什么是BP神经网络 这个百度比较多就不赘述了 在看到我的文章前一定也看了不少了! 开篇先说几点 本文参考了博客"https://blog.cs ...

  4. 机器学习系列2 BP神经网络+代码实现

    神经网络简单的说,就是用一种层次化的方式将一堆简单的函数在顶层堆叠在一起,形成一个复杂的非线性函数,以此表达输入与输出之间的关系. 本文结构: 1.介绍构成神经网络的基本单元:神经元 2.介绍三层神经 ...

  5. 深度学习-BP神经网络(python3代码实现)

    BP神经网络 哈尔滨工程大学-537 一.试验数据 在试验开始前必定要先导入所需要的python库,%matplotlib inline是为了使绘制的图形能够显示在浏览器上. import numpy ...

  6. bp神经网络matlab代码_基于Matlab的BP神经网络识别26个英文字母

    一.设计思想 字符识别在现代日常生活的应用越来越广泛,比如车辆牌照自动识别系统,手写识别系统,办公自动化等等.本文采用BP网络对26个英文字母进行识别.首先将待识别的26个字母中的每一个字母都通过长和 ...

  7. BP神经网络python代码实现#超详细-小白快速入门

    注释为当前行的注释或者是下一行的注释. import numpy as np#科学计算的基础包# 定义sigmoid函数及其求导,deriv=False时进行前向传播的运算,deriv=True进行反 ...

  8. BP神经网络预测回归MATLAB代码(代码完整可直接用,注释详细,可供学习)

    BP神经网络预测回归MATLAB代码(代码完整可直接用,注释详细,可供学习) 一.前言 二.代码部分 2.1 初始化 2.2 读取数据 2.3 设置训练集和测试集 2.4 数据归一化 2.5 求解最佳 ...

  9. python bp神经网络代码实现预测,用Python实现BP神经网络(附代码)

    用Python实现出来的机器学习算法都是什么样子呢? 前两期线性回归及逻辑回归项目已发布(见文末链接),今天来讲讲BP神经网络. BP神经网络 全部代码 https://github.com/lawl ...

最新文章

  1. php session函数
  2. AngularJS学习篇(十六)
  3. Python多线程小例子
  4. windows电脑版便签工具哪款好用?
  5. Redhat下载地址
  6. 【防火墙_策略路由】
  7. 专业能力和表达能力,你觉得哪个更重要?
  8. php学好要多久,零基础php自学要多久
  9. JavaCV音视频开发宝典:JavaCV实现mp3音频直播FM在线电台服务,无需流媒体服务,浏览器原生audio标签直接播放mp3,支持rtsp/rtmp/flv/hls/本地音视频源直接转码到mp3
  10. 数据结构常见问题系列(二)
  11. html文件引用.vue 文件的方式
  12. [英语语法]句法之定语从句
  13. 干货满满的 GopherChina2021 北京大会 PPT is coming
  14. 客户流失预测_如何不预测和防止客户流失
  15. 新房子没网络,怎么用光猫和路由器上网
  16. WR | 西湖大学鞠峰组微纳塑料污染对人工湿地菌群与脱氮功能的影响
  17. 【操作系统】操作系统极速入门
  18. NGUI的动态字体dynamicFont的制作
  19. 极客时间-算法训练营-第二周
  20. 集合--List接口

热门文章

  1. 【B站商品搜索】快速了解平台商品需求,全方位解读爆款商品数据!
  2. 一级计算机照片咋拍,如何拍出锐利照片?你需要掌握的10条技巧
  3. torch一些老忘记的函数
  4. x3300M4,X3500M4网卡驱动下载
  5. 网络管理与维护(二)网络用户设置管理
  6. Filter 什么是滤镜?
  7. JAVA软件开发本科B组7:错误票据
  8. 读书笔记:精益数据分析 第17-20章
  9. Oracle ORA-00947: 没有足够的值
  10. 程序员最终的归宿:跑滴滴、送外卖?