#include "BpNet.h"
using namespace std;
BpNet::BpNet()
{
srand((unsigned)time(NULL)); // 随机数种子
error = 100.f; // error初始值,极大值即可
// 初始化输入层
for (int i = 0; i < innode; i++)
{
inputLayer[i] = new inputNode();
for (int j = 0; j < hidenode; j++)
{
inputLayer[i]->weight.push_back(get_11Random());
inputLayer[i]->wDeltaSum.push_back(0.f);
}
}
// 初始化隐藏层
for (int i = 0; i < hidelayer; i++)
{
if (i == hidelayer - 1)
{
for (int j = 0; j < hidenode; j++)
{
hiddenLayer[i][j] = new hiddenNode();
hiddenLayer[i][j]->bias = get_11Random();
for (int k = 0; k < outnode; k++)
{
hiddenLayer[i][j]->weight.push_back(get_11Random());
hiddenLayer[i][j]->wDeltaSum.push_back(0.f);
}
}
}
else
{
for (int j = 0; j < hidenode; j++)
{
hiddenLayer[i][j] = new hiddenNode();
hiddenLayer[i][j]->bias = get_11Random();
for (int k = 0; k < hidenode; k++) { hiddenLayer[i][j]->weight.push_back(get_11Random()); }
}
}
}
// 初始化输出层
for (int i = 0; i < outnode; i++)
{
outputLayer[i] = new outputNode();
outputLayer[i]->bias = get_11Random();
}
}
void BpNet::forwardPropagationEpoc()
{
// forward propagation on hidden layer
for (int i = 0; i < hidelayer; i++)
{
if (i == 0)
{
for (int j = 0; j < hidenode; j++)
{
double sum = 0.f;
for (int k = 0; k < innode; k++)
{
sum += inputLayer[k]->value * inputLayer[k]->weight[j];
}
sum += hiddenLayer[i][j]->bias;
hiddenLayer[i][j]->value = sigmoid(sum);
}
}
else
{
for (int j = 0; j < hidenode; j++)
{
double sum = 0.f;
for (int k = 0; k < hidenode; k++)
{
sum += hiddenLayer[i - 1][k]->value * hiddenLayer[i - 1][k]->weight[j];
}
sum += hiddenLayer[i][j]->bias;
hiddenLayer[i][j]->value = sigmoid(sum);
}
}
}
// forward propagation on output layer
for (int i = 0; i < outnode; i++)
{
double sum = 0.f;
for (int j = 0; j < hidenode; j++)
{
sum += hiddenLayer[hidelayer - 1][j]->value * hiddenLayer[hidelayer - 1][j]->weight[i];
}
sum += outputLayer[i]->bias;
outputLayer[i]->value = sigmoid(sum);
}
}
void BpNet::backPropagationEpoc()
{
// backward propagation on output layer
// -- compute delta
for (int i = 0; i < outnode; i++)
{
double tmpe = fabs(outputLayer[i]->value - outputLayer[i]->rightout);
error += tmpe * tmpe / 2;
outputLayer[i]->delta
= (outputLayer[i]->value - outputLayer[i]->rightout)*(1 - outputLayer[i]->value)*outputLayer[i]->value;
}
// backward propagation on hidden layer
// -- compute delta
for (int i = hidelayer - 1; i >= 0; i--) // 反向计算
{
if (i == hidelayer - 1)
{
for (int j = 0; j < hidenode; j++)
{
double sum = 0.f;
for (int k = 0; k < outnode; k++) { sum += outputLayer[k]->delta * hiddenLayer[i][j]->weight[k]; }
hiddenLayer[i][j]->delta = sum * (1 - hiddenLayer[i][j]->value) * hiddenLayer[i][j]->value;
}
}
else
{
for (int j = 0; j < hidenode; j++)
{
double sum = 0.f;
for (int k = 0; k < hidenode; k++) { sum += hiddenLayer[i + 1][k]->delta * hiddenLayer[i][j]->weight[k]; }
hiddenLayer[i][j]->delta = sum * (1 - hiddenLayer[i][j]->value) * hiddenLayer[i][j]->value;
}
}
}
// backward propagation on input layer
// -- update weight delta sum
for (int i = 0; i < innode; i++)
{
for (int j = 0; j < hidenode; j++)
{
inputLayer[i]->wDeltaSum[j] += inputLayer[i]->value * hiddenLayer[0][j]->delta;
}
}
// backward propagation on hidden layer
// -- update weight delta sum & bias delta sum
for (int i = 0; i < hidelayer; i++)
{
if (i == hidelayer - 1)
{
for (int j = 0; j < hidenode; j++)
{
hiddenLayer[i][j]->bDeltaSum += hiddenLayer[i][j]->delta;
for (int k = 0; k < outnode; k++)
{
hiddenLayer[i][j]->wDeltaSum[k] += hiddenLayer[i][j]->value * outputLayer[k]->delta;
}
}
}
else
{
for (int j = 0; j < hidenode; j++)
{
hiddenLayer[i][j]->bDeltaSum += hiddenLayer[i][j]->delta;
for (int k = 0; k < hidenode; k++)
{
hiddenLayer[i][j]->wDeltaSum[k] += hiddenLayer[i][j]->value * hiddenLayer[i + 1][k]->delta;
}
}
}
}
// backward propagation on output layer
// -- update bias delta sum
for (int i = 0; i < outnode; i++) outputLayer[i]->bDeltaSum += outputLayer[i]->delta;
}
void BpNet::training(static vector<sample> sampleGroup, double threshold)
{
int sampleNum = sampleGroup.size();
while (error > threshold)
//for (int curTrainingTime = 0; curTrainingTime < trainingTime; curTrainingTime++)
{
cout << "training error: " << error << endl;
error = 0.f;
// initialize delta sum
for (int i = 0; i < innode; i++) inputLayer[i]->wDeltaSum.assign(inputLayer[i]->wDeltaSum.size(), 0.f);
for (int i = 0; i < hidelayer; i++) {
for (int j = 0; j < hidenode; j++)
{
hiddenLayer[i][j]->wDeltaSum.assign(hiddenLayer[i][j]->wDeltaSum.size(), 0.f);
hiddenLayer[i][j]->bDeltaSum = 0.f;
}
}
for (int i = 0; i < outnode; i++) outputLayer[i]->bDeltaSum = 0.f;
for (int iter = 0; iter < sampleNum; iter++)
{
setInput(sampleGroup[iter].in);
setOutput(sampleGroup[iter].out);
forwardPropagationEpoc();
backPropagationEpoc();
}
// backward propagation on input layer
// -- update weight
for (int i = 0; i < innode; i++)
{
for (int j = 0; j < hidenode; j++)
{
inputLayer[i]->weight[j] -= learningRate * inputLayer[i]->wDeltaSum[j] / sampleNum;
}
}
// backward propagation on hidden layer
// -- update weight & bias
for (int i = 0; i < hidelayer; i++)
{
if (i == hidelayer - 1)
{
for (int j = 0; j < hidenode; j++)
{
// bias
hiddenLayer[i][j]->bias -= learningRate * hiddenLayer[i][j]->bDeltaSum / sampleNum;
// weight
for (int k = 0; k < outnode; k++)
{
hiddenLayer[i][j]->weight[k] -= learningRate * hiddenLayer[i][j]->wDeltaSum[k] / sampleNum;
}
}
}
else
{
for (int j = 0; j < hidenode; j++)
{
// bias
hiddenLayer[i][j]->bias -= learningRate * hiddenLayer[i][j]->bDeltaSum / sampleNum;
// weight
for (int k = 0; k < hidenode; k++)
{
hiddenLayer[i][j]->weight[k] -= learningRate * hiddenLayer[i][j]->wDeltaSum[k] / sampleNum;
}
}
}
}
// backward propagation on output layer
// -- update bias
for (int i = 0; i < outnode; i++)
{
outputLayer[i]->bias -= learningRate * outputLayer[i]->bDeltaSum / sampleNum;
}
}
}
void BpNet::predict(vector<sample>& testGroup)
{
int testNum = testGroup.size();
for (int iter = 0; iter < testNum; iter++)
{
testGroup[iter].out.clear();
setInput(testGroup[iter].in);
// forward propagation on hidden layer
for (int i = 0; i < hidelayer; i++)
{
if (i == 0)
{
for (int j = 0; j < hidenode; j++)
{
double sum = 0.f;
for (int k = 0; k < innode; k++)
{
sum += inputLayer[k]->value * inputLayer[k]->weight[j];
}
sum += hiddenLayer[i][j]->bias;
hiddenLayer[i][j]->value = sigmoid(sum);
}
}
else
{
for (int j = 0; j < hidenode; j++)
{
double sum = 0.f;
for (int k = 0; k < hidenode; k++)
{
sum += hiddenLayer[i - 1][k]->value * hiddenLayer[i - 1][k]->weight[j];
}
sum += hiddenLayer[i][j]->bias;
hiddenLayer[i][j]->value = sigmoid(sum);
}
}
}
// forward propagation on output layer
for (int i = 0; i < outnode; i++)
{
double sum = 0.f;
for (int j = 0; j < hidenode; j++)
{
sum += hiddenLayer[hidelayer - 1][j]->value * hiddenLayer[hidelayer - 1][j]->weight[i];
}
sum += outputLayer[i]->bias
C++版 Bp神经网络数据拟合数据预测
需积分: 0 186 浏览量
更新于2023-04-29
5
收藏 3.75MB ZIP 举报
C++版本的BP神经网络是一种基于反向传播算法实现的神经网络模型,它可以被用于数据拟合和预测。BP神经网络由多个层次组成,包括输入层、隐藏层和输出层。通过不断地迭代训练,BP神经网络能够学习到复杂的非线性关系,从而能够适应各种不同的数据。
在C++中实现BP神经网络可以使用开源神经网络库,比如FANN(Fast Artificial Neural Network)。这个库提供了很多有用的函数和方法,可以方便地构建、训练和测试BP神经网络模型。
Android西红柿
- 粉丝: 1w+
- 资源: 14
最新资源
- 基于改进多目标粒子群的微电网优化调度模型 提出了一种经济与环保相协调的微电网优化调度模型,针对光伏电池、风机、微型燃气轮机、柴油发电机以及蓄电池组成的微电网系统的优化问题进行研究,在满足系统约束条件下
- 基于狼群优化算法的LSSVM回归预测GWO-LSSVM 为了提高最小二乘支持向量机(lssvm)的回归预测准确率,对lssvm中的惩罚参数和核惩罚参数利用灰狼优化算法进行优化 Matlab 代码
- 多目标遗传算法 分布式电源 选址定容 代码主要做的是一个分布式电源选址定容的问题,首先,构建了分布式电源选址定容问题的目标函数,包括网损最低以及运行成本最低,因此采用的是多目标模型,目标函数采用相
- 风光场景生成 场景削减 概率距离削减法 蒙特卡洛法 MATLAB:基于概率距离快速削减法的风光场景生成与削减方法 参考文档:《含风光水的电厂与配电公司协调调度模型》完全复现场景削减部分 仿真平台:MA
- PMSM永磁同步电机模型参考自适应法MRAS,MATLAB SIMULINK仿真软件,无速度传感器矢量控制,可以实现变转速控制,PI已调好
- 基于单片机的小车循迹避障 程序 仿真 原文都有 利用超声波检测,对前方的障碍物进行躲避,前方遇到障碍物小车掉头继续循迹行驶; 对小车循迹行驶的过程中的车速检测并显示在LCD1602上; 系统的主控模块
- 珍稀模型,可发paper 传统火电阻尼不足,VSG增加火电阻尼,参与一次调频特性优化,没有VSG,发电机调频阻尼不够
- matlab 改进灰狼算法 含分布式电源 配电网重构 考虑IEEE33节点系统使用基本环矩阵编码的智能优化算法在处理配电网重构问题中,通常使用无序的解空间,解空间中局部峰值较多,使得智能优化算法
- 昆仑通态与3台东元N310变频器通讯程序 实现昆仑通态触摸屏与3台东元N310变频器通讯,程序稳定可靠 器件:昆仑通态TPC7062KD触摸屏,东元N310变频器,附送接线说明和设
- MATLAB代码:综合能源 冷热电三联供 粒子群算法 多目标优化 参考文档:《基于多目标算法的冷热电联供型综合能源系统运行优化》 仿真平台:MATLAB 平台采用粒子群实现求解 优势:代码注释详实
- 工程师必备串口数据截取工具modbus命令分析串口数据分析 主要功能: ·支持监控COM端口类型:标准电脑端口,内核COM端口,USB转串口等; ·可以实时监控并采集串口数据; ·可以同时监控多个串
- 西门子1200模板 程序采用1215PLC,项目实现以下功能: A.三轴机械手联动取放料PTO脉冲定位控制台达B2伺服 B.台达伺服速度模式应用+扭矩模式应用实现收放卷 C.程序为结构化编程,每一功能
- 汇川H5U PLC 四轴标准程序案例+框架 (送触摸屏程序和各种H5U常用功能块) 支持总线和脉冲两种方式 已经稳定运用在各客户设备上包括: 枕式包装机、纸袋机、塑料机、攻丝机等等 包含飞剪、追剪、跟
- LabVIEW测试测量项目Demo数据库操作演示项目结构搭建源码
- 麻雀搜索算法(SSA)优化xgboost算法(优化树的个数、最大深度和学习率),也可定制其他智能优化算法进行优化 包括优化后的xgboost和未优化的xgboost进行对比 评价指标有R2
- 高压无感bldc方案,主控芯片apt32f1023 接口包括 高压无感bldc方案,主控芯片apt32f1023 接口包括启停控制,正反转控制,旋钮调速控制 资料包括原理图,pcb,程序