forked from jkrautter/clneural
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NeuralNetwork.cpp
121 lines (108 loc) · 3.22 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
/*
* NeuralNetwork.cpp
*
* Created on: Dec 10, 2015
* Author: jonas
*/
#include "Logger.h"
#include <cmath>
#include <fstream>
#include <sstream>
#include "NeuralNetwork.h"
namespace clneural {
NeuralNetwork::NeuralNetwork() {
}
NeuralNetwork::~NeuralNetwork() {
}
bool NeuralNetwork::addLayer(std::shared_ptr<NeuralNetworkLayer> layer) {
if ((first_layer == nullptr) && (last_layer == nullptr)) {
first_layer = layer;
last_layer = layer;
return true;
}
if (last_layer->getNumOutputs() != layer->getNumInputs()) {
Logger::writeLine("NeuralNetwork::addLayer(): Inputs not matching outputs for layer to be added.");
return false;
}
last_layer->setNextLayer(layer);
layer->setPreviousLayer(last_layer);
last_layer = layer;
return true;
}
std::vector<float> NeuralNetwork::getLastOutput() const {
if (last_layer == nullptr) {
return std::vector<float>();
}
return last_layer->getLastOutput();
}
void NeuralNetwork::processInput(const std::vector<float> &input) {
if (first_layer != nullptr) {
first_layer->processAndForwardInput(input);
}
}
float NeuralNetwork::trainNetwork(const std::vector<float> &input, const std::vector<float> &desired_output) {
if (first_layer == nullptr) {
return 0.0f;
}
processInput(input);
std::vector<float> out = getLastOutput();
std::vector<float> dif(out.size());
float dist = 0.0f;
for (unsigned int i = 0; i < out.size(); i++) {
dif[i] = desired_output[i] - out[i];
dist += dif[i]*dif[i];
}
last_layer->processAndForwardError(dif);
return sqrt(dist);
}
std::string NeuralNetwork::getStringRepresentation() const {
std::string repr;
std::shared_ptr<NeuralNetworkLayer> iterator = first_layer;
while (iterator != nullptr) {
repr += iterator->getStringRepresentation() + "\n";
iterator = iterator->getNextLayer();
}
return repr;
}
bool NeuralNetwork::parseStringRepresentation(std::string repr) {
bool res = true;
size_t lastpos = 0;
size_t newpos = repr.find_first_of('\n', 0);
while ((newpos != std::string::npos) && res) {
std::shared_ptr<NeuralNetworkLayer> templayer = NeuralNetworkLayer::createFromStringRepresentation(repr.substr(lastpos, newpos - lastpos));
if (templayer != nullptr) {
if (!addLayer(templayer)) {
Logger::writeLine("NeuralNetwork::parseStringRepresentation(): Unable to add layer in string representation.");
res = false;
}
} else {
Logger::writeLine("NeuralNetwork::parseStringRepresentation(): Unable to parse layer string representation.");
res = false;
}
lastpos = newpos + 1;
newpos = repr.find_first_of('\n', 0);
}
return res;
}
bool NeuralNetwork::saveToFile(std::string filename) const {
std::ofstream file(filename, std::ios::out | std::ios::trunc);
if (!file.is_open()) {
Logger::writeLine("NeuralNetwork::saveToFile(): Unable to open file: " + filename);
return false;
}
file << getStringRepresentation();
file.close();
return true;
}
bool NeuralNetwork::loadFromFile(std::string filename) {
std::ifstream file(filename, std::ios::in);
if (!file.is_open()) {
Logger::writeLine("NeuralNetwork::loadFromFile(): Unable to open file: " + filename);
return false;
}
std::stringstream content;
content << file.rdbuf();
parseStringRepresentation(content.str());
return true;
}
} /* namespace clneural */