-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathneuralNetwork.cpp
131 lines (98 loc) · 3.74 KB
/
neuralNetwork.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "neuralNetwork.h"
template <class T>
neuralNetwork<T>::neuralNetwork(unsigned const &inputNeurons, unsigned const &hiddenNeurons, unsigned const &outputNeurons, const std::string &funcName, const T &learningRate) {
this->neurons.push_back(inputNeurons);
this->neurons.push_back(hiddenNeurons);
this->neurons.push_back(outputNeurons);
this->weights.push_back(Matrix<T>(hiddenNeurons, inputNeurons));
this->weights.push_back(Matrix<T>(outputNeurons, hiddenNeurons));
// Init weights
this->weights[0].fillRand();
this->weights[1].fillRand();
this->biases.push_back(Matrix<T>(hiddenNeurons, 1));
this->biases.push_back(Matrix<T>(outputNeurons, 1));
// Init biases
this->biases[0].fillRand();
this->biases[1].fillRand();
this->actFunc = this->actFuncObj.getActivationFunction(funcName);
this->learningRate = learningRate;
this->numOfLayers = 3;
}
template <class T>
neuralNetwork<T>::neuralNetwork(const std::vector<unsigned> &neurons, const std::string &funcName, const T &learningRate) {
this->neurons = neurons;
for(unsigned i = 0; i < neurons.size() - 1; ++i) {
this->weights.push_back(Matrix<T>(neurons[i + 1], neurons[i]));
this->weights.back().fillRand();
this->biases.push_back(Matrix<T>(neurons[i + 1], 1));
this->biases.back().fillRand();
}
this->actFunc = this->actFuncObj.getActivationFunction(funcName);
this->learningRate = learningRate;
this->numOfLayers = neurons.size();
}
template <class T>
neuralNetwork<T>::neuralNetwork(const neuralNetwork<T> &cpy) {
this->neurons = cpy.neurons;
this->weights = cpy.weights;
this->biases = cpy.biases;
this->actFunc = cpy.actFunc;
this->actFuncObj = cpy.actFuncObj;
this->numOfLayers = cpy.numOfLayers;
this->learningRate = cpy.learningRate;
}
template <class T>
neuralNetwork<T>::~neuralNetwork() {
}
template <class T>
T neuralNetwork<T>::getLearningRate() {
return this->learningRate;
}
template <class T>
void neuralNetwork<T>::setLearningRate(T const &learningRate) {
this->learningRate = learningRate;
}
template <class T>
std::vector<T> neuralNetwork<T>::feedForward(const std::vector<T> &inputValues) {
if(inputValues.size() != this->neurons[0]) {
throw std::invalid_argument("the number of input values doesn't match the number of input nodes!");
}
Matrix<T> inputs = Matrix<T>::toColumnVector(inputValues);
for(unsigned i = 0; i < this->numOfLayers - 1; ++i) {
inputs = this->weights[i] * inputs + this->biases[i];
inputs.applyFunction(this->actFunc.func);
}
return Matrix<T>::toArray(inputs);
}
template <class T>
void neuralNetwork<T>::train(const std::vector<T> &inputValues, const std::vector<T> &targetValues) {
if(inputValues.size() != this->neurons[0]) {
throw std::invalid_argument("the number of input values doesn't match the number of input nodes!");
}
if(targetValues.size() != this->neurons.back()) {
throw std::invalid_argument("the number of target values doesn't match the number of output nodes!");
}
std::vector<Matrix<T>> matrices;
matrices.push_back(Matrix<T>::toColumnVector(inputValues));
for(unsigned i = 0; i < this->numOfLayers - 1; ++i) {
Matrix<T> temp = this->weights[i] * matrices.back() + this->biases[i];
temp.applyFunction(this->actFunc.func);
matrices.push_back(temp);
}
unsigned i = this->numOfLayers - 2;
Matrix<T> errors = Matrix<T>::toColumnVector(targetValues) - matrices.back();
while(true) {
Matrix<T> gradients = Matrix<T>::applyFunction(matrices[i + 1], this->actFunc.derivative_func);
gradients %= errors * this->learningRate;
this->weights[i] += gradients >> matrices[i];
this->biases[i] += gradients;
if(i == 0) {
break;
}
errors = this->weights[i] << errors;
--i;
}
}
template class neuralNetwork<float>;
template class neuralNetwork<double>;
template class neuralNetwork<long double>;