c matlab神经网络,C/C++实现BP神经网络

标签:

头文件pch.h

#ifndef PCH_H

#define PCH_H

#include

#include

#include

#include

#include

#include

#endif //PCH_H

主函数main.cpp

//作者cclplus

//初稿2018/05/01

//如果你认为有必要打赏我,我的支付宝号是707101557@qq.com

#include "pch.h"

using namespace std;

const double pi = atan(1.0) * 4;

//BP神经网络结构

struct BPNN {

int sample_count;//样本数量

int input_count;//输入向量的维数

int output_count;//输出向量的维数

int hidden_count;//实际使用隐层神经元数量

double study_rate;//学习速率

double precision;//精度控制参数

int loop_count;//循环次数

vector> v;//隐含层权矩阵

vector> w;//输出层权矩阵

};

BPNN CREATE_BPNN(int sc, int ic, int oc, int hc, double sr, double p, int lc);//创建一个BP神经网络

double rand_normal();//返回一个double类型的随机数

double sigmoid(double net) {

return 1.0 / (1 + exp(-net));

}

double purelin(double net) {

return 1.0 / (1 + exp(-net));

}

BPNN train_bp(vector> x, vector> y, BPNN bp);//训练

void use_bp(BPNN bp, vector> inoput);//使用BP神经网络进行前向传导运算

int main() {

//样本数目

int sample_count = 100;

//输入向量维数

int input_count = 1;

//输出向量维数

int output_count = 1;

//实际使用隐层神经元数目

int hidden_count = 4;

//学习速率

double study_rate = 0.02;

//精度控制参数

double precision = 0.001;

//循环次数

int loop_count = 10000;

int i;

double temp, temp1;

//训练样本

vector> x;

vector> y;

vector> input;

x.resize(sample_count);

for (i = 0; i < sample_count; i++) {

x[i].resize(input_count);

}

y.resize(sample_count);

for (i = 0; i < sample_count; i++) {

y[i].resize(output_count);

}

input.resize(sample_count);

for (i = 0; i < sample_count; i++) {

input[i].resize(input_count);

}

//自定义输入与输出

for (i = 0; i < sample_count; i++) {

temp = (double)i;

temp1 = (double)sample_count;

x[i][0] = pi / temp1 * temp;

input[i][0] = pi / temp1 * temp;

y[i][0] = 1.0*sin(x[i][0]);

}

BPNN bp;

bp = CREATE_BPNN(sample_count, input_count, output_count, hidden_count, study_rate, precision, loop_count);

bp = train_bp(x, y, bp);

use_bp(bp, input);

return 0;

}

//使用BP神经网络进行前向传导运算

void use_bp(BPNN bp, vector> input) {

//设置临时变量

double temp;

int i, j, k;

vector O1;

O1.resize(bp.hidden_count);

vector> output;

output.resize(100);

for (i = 0; i < 100; i++) {

output[i].resize(bp.output_count);

}

for (i = 0; i < 100; i++) {

for (j = 0; j < bp.hidden_count; j++) {

temp = 0;

for (k = 0; k < bp.input_count; k++) {

temp = temp + input[i][k] * bp.v[k][j];

}

O1[j] = sigmoid(temp);

}

for (j = 0; j < bp.output_count; j++) {

temp = 0;

for (k = 0; k < bp.hidden_count; k++) {

temp = temp + O1[k] * bp.w[k][j];

}

output[i][j] = sigmoid(temp);

}

}

for (i = 0; i < 100; i++) {

for (j = 0; j < bp.output_count; j++) {

printf("%f ", output[i][j]);

}

}

printf("\n结束\n");

}

//训练一个BP神经网络

BPNN train_bp(vector> x, vector> y, BPNN bp) {

double f, a;

int hc, sc, lc, ic, oc;

f = bp.precision;//精度控制参数

a = bp.study_rate;//学习速率

hc = bp.hidden_count;//隐含层数

sc = bp.sample_count;//训练样本总数

lc = bp.loop_count;//循环次数

ic = bp.input_count;//输入维度

oc = bp.output_count;//输出维度

//修改量矩阵

vector chg_h;//隐层

chg_h.resize(hc);

vector chg_o;//输出层

chg_o.resize(oc);

vector O1;

O1.resize(hc);

vector O2;

O2.resize(oc);

//临时变量

double temp;

int i, j, m, n;

double mse;//均方误差

double e;//误差

e = f + 1;//保证循环顺利执行

for (n = 0; (e > f) && (n < lc); n++) {//n代表循环次数

e = 0;

mse = 0;

//全部样本均加入神经网络的训练

for (i = 0; i < sc; i++) {

//计算隐层输出向量

for (m = 0; m < hc; m++) {

temp = 0;

for (j = 0; j < ic; j++) {

temp = temp + x[i][j] * bp.v[j][m];

}

O1[m] = sigmoid(temp);

}

//计算输出值

for (m = 0; m < oc; m++) {

temp = 0;

for (j = 0; j < hc; j++) {

temp = temp + O1[j] * bp.w[j][m];

}

O2[m] = purelin(temp);

}

//计算输出层的权重修改

for (j = 0; j < oc; j++) {

chg_o[j] = O2[j] * (1 - O2[j])*(y[i][j] - O2[j]);

}

//计算隐层的权重修改

for (j = 0; j < hc; j++) {

temp = 0;

for (m = 0; m < oc; m++) {

temp = temp + bp.w[j][m] * chg_o[m];

}

chg_h[j] = temp * O1[j] * (1 - O1[j]);

}

//计算误差和均方根误差

for (j = 0; j < oc; j++) {

e = e + (y[i][j] - O2[j])*(y[i][j] - O2[j]);

mse = mse + y[i][j] * y[i][j];

}

//对权值矩阵做出修改

for (j = 0; j < hc; j++) {

for (m = 0; m < oc; m++) {

bp.w[j][m] = bp.w[j][m] + a * O1[j] * chg_o[m];

}

}

for (j = 0; j < ic; j++) {

for (m = 0; m < hc; m++) {

bp.v[j][m] = bp.v[j][m] + a * x[i][j] * chg_h[m];

}

}

}

//每循环一百次输出一次误差

if (n % 100 == 0) {

mse = e / mse;

printf("误差 :%f\n", e);

printf("均方根误差 :%f\n", mse);

printf("当前循环次数:%d\n", n);

}

}

//循环结束,输出最终信息

printf("循环总次数:%d\n", n);

printf("调整后的隐层权值矩阵:\n");

for (i = 0; i < ic; i++) {

for (j = 0; j < hc; j++) {

printf("%f ", bp.v[i][j]);

}

printf("\n");

}

printf("调整后的输出层权值矩阵:\n");

for (i = 0; i < hc; i++) {

for (j = 0; j < oc; j++) {

printf("%f ", bp.w[i][j]);

}

printf("\n");

}

printf("神经网络训练结束:\n");

printf("最终误差:%f\n", e);

return bp;

}

//创建一个BP神经网络

BPNN CREATE_BPNN(int sc, int ic, int oc, int hc, double sr, double p, int lc) {

BPNN bp;

bp.sample_count = sc;

bp.input_count = ic;

bp.output_count = oc;

bp.hidden_count = hc;

bp.study_rate = sr;

bp.precision = p;

bp.loop_count = lc;

int i, j;

bp.v.resize(ic);//隐含层的权值矩阵,共有input_count行,hidden_count列

for (i = 0; i < ic; i++) {

bp.v[i].resize(hc);

}

//数据的初始化

for (i = 0; i < ic; i++) {

for (j = 0; j < hc; j++) {

bp.v[i][j] = rand_normal();

}

}

bp.w.resize(hc);//输出层的权值矩阵,共有hidden_count行,output_count列

for (i = 0; i < hc; i++) {

bp.w[i].resize(oc);

}

for (i = 0; i < hc; i++) {

for (j = 0; j < oc; j++) {

bp.w[i][j] = rand_normal();

}

}

return bp;

}

//返回一个double类型的随机数,这么做的目的是破坏神经网络结构的对称性

//基本原理,参见独立同分布的中心极限定理

double rand_normal() {

int i;

const int normal_count = 200;//样本数目采用200个

double ccl_num;

double ccl_s;

double ccl_ar[normal_count];

ccl_num = 0;

for (i = 0; i < normal_count; i++) {

ccl_ar[i] = rand() % 1000 / (double)1001;

ccl_num += ccl_ar[i];

}

ccl_num -= (normal_count / 2);//减去0-1均匀分布的均值

ccl_s = 1.0*normal_count / 12.0;//0-1分布的方差为1/12

ccl_s = sqrt(ccl_s);

ccl_num /= ccl_s;//此时ccl_num接近标准正态分布的一个子集

ccl_num /= 100;//变为正态分布(0,0.01)的一个子集,论文中有给出证明过程

cout << " 随机值" << ccl_num << endl;

return ccl_num;

}

标签:

来源: https://blog.csdn.net/m0_37772174/article/details/85214373

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值