Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef NN_H
- #define NN_H
- #pragma once
- #include <cmath>
- using namespace std;
- namespace nn
- {
- class connection
- {
- public:
- double weight;
- double deltaWeight;
- void deltainit() { deltaWeight = 0.0; }
- void init() { weight = rand() / double(RAND_MAX); deltainit(); }
- connection(double w, double d) { weight = w; deltaWeight = d; }
- connection(double w) { weight = w; deltainit(); }
- connection() { init(); }
- ~connection() { }
- };
- class neuron;
- class layer
- {
- public:
- vector<neuron> neuron;
- layer() { }
- ~layer() { }
- };
- class neuron
- {
- public:
- int index;
- vector<connection> connections;
- double outputvalue;
- double eta;
- double alpha;
- double gradient;
- void feedForward(layer *prevLayer)
- {
- double sum = 0.0;
- for (int n = 0; n < prevLayer->neuron.size(); ++n) {
- sum += prevLayer->neuron[n].outputvalue * prevLayer->neuron[n].connections[index].weight;
- }
- outputvalue = tanh(sum);
- }
- void OutputGradients(double targetVal)
- {
- double delta = targetVal - outputvalue;
- gradient = delta * (1.0 - outputvalue * outputvalue);
- }
- void HiddenGradients(layer *nextlayer)
- {
- double sum = 0.0;
- for (int n = 0; n < nextlayer->neuron.size() - 1; ++n) {
- sum += connections[n].weight * nextlayer->neuron[n].gradient;
- }
- gradient = sum * (1.0 - outputvalue * outputvalue);
- }
- void updateInputWeights(layer *in)
- {
- double olddelta = 0.0;
- for (int n = 0; n < in->neuron.size(); ++n) {
- olddelta = in->neuron[n].connections[index].deltaWeight;
- in->neuron[n].connections[index].deltaWeight = eta * in->neuron[n].outputvalue * gradient + alpha * olddelta;
- in->neuron[n].connections[index].weight += in->neuron[n].connections[index].deltaWeight;
- }
- }
- void init()
- {
- outputvalue = 0.0;
- eta = 0.15;
- alpha = 0.5;
- gradient = rand() / double(RAND_MAX);
- }
- neuron( int NeuronIndex, int Connections )
- {
- for (int a = 0; a < Connections; a++) connections.push_back(connection());
- index = NeuronIndex;
- init();
- }
- neuron() {
- init();
- }
- ~neuron(){
- }
- };
- class network
- {
- public:
- vector<layer> layers;
- double error;
- double error_avarage;
- double error_smoothing_factor;
- void results(vector<double> *in)
- {
- in->clear();
- for (int n = 0; n < layers.back().neuron.size() - 1; ++n) {
- in->push_back(layers.back().neuron[n].outputvalue);
- }
- }
- void learn(vector<double> *in)
- {
- int n, a;
- error = 0.0;
- for (unsigned n = 0; n < layers.back().neuron.size() - 1; ++n) {
- double delta = (*in)[n] - layers.back().neuron[n].outputvalue;
- error += delta * delta;
- }
- error /= layers.back().neuron.size() - 1;
- error = sqrt(error);
- error_avarage = (error_avarage * error_smoothing_factor + error) / (error_smoothing_factor + 1.0);
- for (n = 0; n < layers.back().neuron.size() - 1; ++n) {
- layers.back().neuron[n].OutputGradients((*in)[n]);
- }
- for (a = layers.size() - 2; a > 0; --a) {
- for (n = 0; n < layers[a].neuron.size(); ++n) {
- layers[a].neuron[n].HiddenGradients(&layers[a + 1]);
- }
- }
- for (a = layers.size() - 1; a > 0; --a) {
- for (n = 0; n < layers[a].neuron.size() - 1; n++) {
- layers[a].neuron[n].updateInputWeights(&layers[a - 1]);
- }
- }
- }
- void feed(vector<double> *in)
- {
- int n;
- for (n = 0; n < layers[0].neuron.size(); n++){
- layers[0].neuron[n].outputvalue = (*in)[n];
- }
- for (int a = 1; a < layers.size(); a++) {
- for (n = 0; n < layers[a].neuron.size(); n++) layers[a].neuron[n].feedForward( &layers[a - 1] );
- }
- }
- void init(vector<int> *layers_and_neurons)
- {
- int n;
- // error = 0.0;
- // error_avarage = 0.0;
- error_smoothing_factor = 100.0;
- for (int a = 0; a < layers_and_neurons->size() - 1; a++)
- {
- layers.push_back(layer());
- for (n = 0; n <= (*layers_and_neurons)[a]; n++) {
- layers.back().neuron.push_back(neuron(n, (*layers_and_neurons)[a + 1]));
- }
- layers.back().neuron.back().outputvalue = 1.0;
- }
- layers.push_back(layer());
- for (n = 0; n <= layers_and_neurons->back(); n++) {
- layers.back().neuron.push_back(neuron(n, 0));
- }
- layers.back().neuron.back().outputvalue = 1.0;
- }
- network()
- {
- }
- ~network()
- {
- }
- };
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment