-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBPNN.cpp
106 lines (94 loc) · 3.32 KB
/
BPNN.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "BPNN.h"
#include <random>
BP_neural_networks::BP_neural_networks(std::vector<int> &numNodes)
{
mNumLayers=numNodes.size();
mNumNodes=numNodes;
mNodeValue.resize(mNumLayers);
mWeights.resize(mNumLayers);
mErr.resize(mNumLayers);
for(int i=0; i<mNumLayers; ++i){
mNodeValue[i].resize(numNodes[i]);
mWeights[i].resize(numNodes[i]);
mErr[i].resize(numNodes[i]);
for(int j=0; j<numNodes[i]; ++j){
if(i < mNumLayers - 1) {
mWeights[i][j].resize(numNodes[i+1]);
std::fill(mWeights[i][j].begin(),mWeights[i][j].end(),.3);
}
}
}
}
void BP_neural_networks::train(std::vector<double> &input, std::vector<double> &output)
{
//std::copy(input.begin(),input.end(),mNodeValue[0]);
for(int i=0; i<mNumNodes[0]; ++i){
mNodeValue[0][i] = input[i];
}
for(int i=0; i<mNumLayers-1; ++i){
for(int j=0; j<mNumNodes[i+1]; ++j){
// Calculate the nodes' values on the next layer, following the i'th layer
double sum = .0;
for(int k=0; k<mNumNodes[i]; ++k){
sum += mNodeValue[i][k]*mWeights[i][k][j];
}
mNodeValue[i+1][j] = sigmoid(sum);
}
}
for(int j=0; j<mNumNodes[mNumLayers-1]; ++j){
double e = output[j] - mNodeValue[mNumLayers-1][j];
mErr[mNumLayers-1][j] =
mNodeValue[mNumLayers-1][j] * (1.0 - mNodeValue[mNumLayers-1][j]) * e;
for(int k=0; k<mNumNodes[mNumLayers-2]; ++k){
mWeights[mNumLayers-2][k][j] +=
1.0 * mErr[mNumLayers-1][j] * mNodeValue[mNumLayers-2][k];
}
}
for(int i=mNumLayers-1; i>1; --i){
for(int j=0; j<mNumNodes[i-1]; ++j){
double g=0;
for(int k=0; k<mNumNodes[i]; ++k){
g += mWeights[i-1][j][k] * mErr[i][k];
}
mErr[i-1][j] = mNodeValue[i-1][j] * (1.0 - mNodeValue[i-1][j]) * g;
for(int k=0; k<mNumNodes[i-2]; ++k){
mWeights[i-2][k][j] += 1.0 * mErr[i-1][j] * mNodeValue[i-2][k];
}
}
}
}
void BP_neural_networks::getResult(std::vector<double>& input, std::vector<double>& output)
{
//std::copy(input.begin(),input.end(),mNodeValue[0]);
for(int i=0; i<mNumNodes[0]; ++i){
mNodeValue[0][i] = input[i];
}
for(int i=0; i<mNumLayers-1; ++i){
for(int j=0; j<mNumNodes[i+1]; ++j){
// Calculate the nodes' values on the next layer, following the i'th layer
double sum=.0;
for(int k=0; k<mNumNodes[i]; ++k){
sum += mNodeValue[i][k]*mWeights[i][k][j];
}
mNodeValue[i+1][j] = sigmoid(sum);
}
}
//std::copy(mNodeValue[mNumLayers-1].begin(), mNodeValue[mNumLayers-1].end(),output);
for(int i=0; i<mNumNodes[mNumLayers-1]; ++i){
output[i] = mNodeValue[mNumLayers-1][i];
}
}
void BP_neural_networks::initialWeights()
{
std::random_device rd;
std::mt19937 gen(rd());
for(int i=0; i<mNumLayers-1; ++i){
for(int j=0; j<mNumNodes[i]; j++){
for(int k=0; k<mNumNodes[i+1]; ++k){
double ub = 1.0 / std::pow(mNumNodes[i],.5);
std::uniform_real_distribution<double> dis(-ub,ub);
mWeights[i][j][k]=dis(gen);
}
}
}
}