Advertisement
riabcis

Untitled

Apr 5th, 2018
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.57 KB | None | 0 0
  1. // Ann.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. # include <cmath>
  6. #include <math.h>
  7. #include <vector>
  8. #include <iostream>
  9. #include <iomanip>
  10. #include <fstream>
  11. #include <string>
  12. using namespace std;
  13. //Generating random number: either 0 or 1, uniform distribution, for XOR operation. Can remove later if using data from files.
  14. int randint();
  15. double f(double x);
  16. double f_deriv(double x);
  17. double gL(double a, double z, double t);
  18. double w_gradient(int layer_id, int w_i, int w_j, double *a_arr, int *s, double *gll);
  19. double delta_w(double grad, double dw);
  20. void calc_gjl(double *a_arr, double *z_arr, double *t_arr, double *w_arr, int *s, int *sw, int L, int *l, double *gll);
  21. const double ETA = 0.1;
  22. const double ALPHA = 0.15;
  23.  
  24. struct Sample
  25. {
  26.     double input[2];
  27.     double output[2];
  28.     //temp*******
  29.     string ToString() {
  30.         string str;
  31.         str = "input: " + to_string(input[0]) + " " + to_string(input[1]) + " output: " + to_string(output[0]) + " " + to_string(output[1]) + "\n";
  32.         return str;
  33.     }
  34. };
  35. class Data
  36. {
  37. public:
  38.     int getNumberOfInputs() { return inputs; }
  39.     int getNumberOfOutputs() { return outputs; }
  40.  
  41.     double *getInput(int index);
  42.  
  43.     double *getOutput(int index);
  44.  
  45.     int getNumberOfSamples() { return samples; }
  46.  
  47.     void addSample(Sample sample)
  48.     {
  49.         data.push_back(sample);
  50.         samples++;
  51.         //cout << sample.ToString();
  52.     }
  53.  
  54.     void setSizes(int input_size, int output_size)
  55.     {
  56.         inputs = input_size;
  57.         outputs = output_size;
  58.     }
  59.  
  60. protected:
  61.     std::vector<Sample> data;
  62.     int inputs;
  63.     int outputs;
  64.     int samples = 0;
  65. };
  66.  
  67. class XOR : public Data
  68. {
  69. public:
  70.     void generate(int n);
  71.  
  72.     XOR()
  73.     {
  74.         inputs = 2;
  75.         outputs = 2;
  76.         samples = 0;
  77.     }
  78.     void printInputs(int index);
  79.  
  80.     void printOutputs(int index);
  81. };
  82.  
  83. struct Topology
  84. {
  85.     std::vector<int> l;//kiekiai sluoksnyje
  86. } topolygy;
  87.  
  88. class AnnBase {
  89. public:
  90.     virtual void prepare(Topology top) = 0;
  91.     virtual void init(Topology top, double w_arr_1[]) = 0;
  92.     virtual void train(double *a, double *b) = 0;
  93.     virtual void feedForward(double *a, double *b) = 0;
  94.     virtual void destroy() = 0;
  95. private:
  96.     virtual void calc_feedForward() = 0;
  97. };
  98.  
  99. class AnnSerialDBL : public AnnBase {
  100. public:
  101.     void prepare(Topology top);
  102.     void init(Topology top, double w_arr_1[]);
  103.     void train(double *a, double *b);
  104.     void feedForward(double *a, double *b);
  105.     void destroy();
  106. private:
  107.     void calc_feedForward();
  108. public:
  109.     int z_count;//temp var to keep the length of z, so z could be reset for calcs.
  110.     int inputs;
  111.     int outputs;
  112.     int L;
  113.     int * l;
  114.     int * s;
  115.     double * a_arr;
  116.     double * z_arr;
  117.     int * W;
  118.     int * sw;
  119.     double * w_arr;
  120.     double * dw_arr;
  121.     double * t_arr;
  122.     double * gjl;
  123. };
  124. int main()
  125. {
  126.     topolygy.l.push_back(2);
  127.     topolygy.l.push_back(5);
  128.     topolygy.l.push_back(4);
  129.     //topolygy.l.push_back(7);
  130.     topolygy.l.push_back(2);
  131.     AnnSerialDBL SerialDBL;
  132.     SerialDBL.prepare(topolygy);
  133.     SerialDBL.init(topolygy, NULL);
  134.  
  135.     XOR xo;
  136.     xo.generate(40000);
  137.     for (int i = 0; i < xo.getNumberOfSamples(); i++) {
  138.         SerialDBL.train(xo.getInput(i), xo.getOutput(i));
  139.     }
  140.  
  141.     //Checking results(all combinations 0 and 1)
  142.     for (double i = 0; i < 2; i++) {
  143.         for (double j = 0; j < 2; j++) {
  144.             double input[] = { i ,j };
  145.             double output[] = { 0,0 };
  146.             SerialDBL.feedForward(input, output);
  147.  
  148.             cout << endl << "input : " << input[0] << "   " << input[1] << endl;
  149.             cout << endl << "output: " << output[0] << "   " << output[1] << endl << endl;
  150.             cout << "---------------------------------------------------" << endl;
  151.         }
  152.     }
  153.  
  154.     //Checking results(all combinations 0 and 1)
  155.     for (double i = 0; i < 0; i++) {
  156.         double input[] = { randint()*1.0, randint()*1.0 };
  157.         double output[] = { 0,0 };
  158.         SerialDBL.feedForward(input, output);
  159.  
  160.         cout << endl << "input : " << input[0] << "   " << input[1] << endl;
  161.         cout << endl << "output: " << output[0] << "   " << output[1] << endl << endl;
  162.         cout << "---------------------------------------------------" << endl;
  163.     }
  164.  
  165.     SerialDBL.destroy();
  166.  
  167.     int a;
  168.     cin >> a;
  169.  
  170.     return 0;
  171. }
  172.  
  173. //returns random int, either 0 or 1
  174. int randint() {
  175.     double r = ((double)rand() / (RAND_MAX));
  176.     int a = 0;
  177.     if (r > 0.5) {
  178.         a = 1;
  179.     }
  180.     else
  181.     {
  182.         a = 0;
  183.     }
  184.     return a;
  185. }
  186.  
  187. double f(double x) {
  188.     double y = 1 + exp(-x);
  189.     //temp*********************
  190.     if (y == 0) {
  191.         cout << "Error 1";
  192.     }
  193.     if ((y - 1) == 0) {
  194.         //cout << "Error 2";
  195.     }
  196.     //temp**********************
  197.     return 1 / y;
  198. }
  199.  
  200. double f_deriv(double x) {
  201.     //Temp**********
  202.     double y = pow((1 + exp(-x)), 2);
  203.     double z = exp(-x);
  204.     if (y == 0) {
  205.         cout << "Error 3";
  206.     }
  207.     if (z == 0) {
  208.     //  cout << "Error 4";
  209.     }
  210.     //temp**********************
  211.     return exp(-x) / pow((1 + exp(-x)), 2);
  212. }
  213.  
  214. double gL(double a, double z, double t) {
  215.     double w = f_deriv(z) * (a - t);
  216.     //cout << "z: " << z << " a: " << a << " t: " << t << endl;
  217.     return w;
  218. }
  219.  
  220. double w_gradient(int layer_id, int w_i, int w_j, double *a_arr, int *s, double *gll) {
  221.     return a_arr[s[layer_id] + w_i] * gll[s[layer_id+1] + w_j];
  222. }
  223.  
  224. double delta_w(double grad, double dw) {
  225.     return (-ETA)*grad + ALPHA*dw;
  226. }
  227.  
  228. void calc_gjl(double *a_arr, double *z_arr, double *t_arr, double *w_arr, int *s, int *sw, int L, int *l, double *gll)
  229. {
  230.     for (int i = L-2; i >= 0; i--) {
  231.         for (int j = 0; j < l[i + 1] - 1; j++) {
  232.             if (L - 2 == i) {
  233.                 gll[s[i + 1] + j] = gL(a_arr[s[i + 1] + j], z_arr[s[i + 1] + j], t_arr[j]);
  234.             }
  235.             else {
  236.                 gll[s[i + 1] + j] = f_deriv(z_arr[s[i + 1] + j]);
  237.                 double sum = 0;
  238.                 for (int k = 0; k < l[i+2]-1; k++) {
  239.                     sum += w_arr[sw[i + 1] + k*(l[i + 2] - 1) + j] * gll[s[i + 2] + j];
  240.                 }
  241.                 gll[s[i + 1] + j] *= sum;
  242.             }
  243.         }
  244.     }
  245. }
  246.  
  247. //*********
  248. double * Data::getInput(int index)
  249. {
  250.     double *input = data[index].input;
  251.     return input;
  252. }
  253.  
  254. double * Data::getOutput(int index)
  255. {
  256.     double *output = data[index].output;
  257.     return output;
  258. }
  259.  
  260. //****************
  261. void XOR::generate(int n)
  262. {
  263.     for (int i = 0; i < n / 4; i++)
  264.     {
  265.         //double input1 = randint();
  266.         //double input2 = randint();
  267.         for (double j = 0; j < 2; j++) {
  268.             for (double k = 0; k < 2; k++) {
  269.                 double output1 = j == k;
  270.                 double output2 = j != k;
  271.                 addSample({ { j, k },{ output1, output2 } });
  272.             }
  273.         }
  274.  
  275.     }
  276. }
  277.  
  278. void XOR::printInputs(int index)
  279. {
  280.     cout << index << " index inputs: " << endl;
  281.     for (int i = 0; i < inputs; i++)
  282.     {
  283.         cout << getInput(index)[i] << " ";
  284.     }
  285.     cout << endl;
  286. }
  287.  
  288. void XOR::printOutputs(int index)
  289. {
  290.     cout << index << " index outputs: " << endl;
  291.     for (int i = 0; i < outputs; i++)
  292.     {
  293.         cout << fixed << setprecision(2) << data[index].output[i] << " ";
  294.     }
  295.     cout << endl;
  296. }
  297.  
  298. //****************
  299. void AnnSerialDBL::prepare(Topology top)
  300. {
  301.     inputs = top.l.at(0);
  302.     outputs = top.l.at(top.l.size() - 1);
  303.  
  304.     l = new int[top.l.size()];
  305.     s = new int[top.l.size()];
  306.  
  307.     int sum = 0;
  308.     int mult = 0;
  309.     for (int i = 0; i < top.l.size(); i++) {
  310.         sum += top.l.at(i) + 1;
  311.     }
  312.     z_count = sum;
  313.     for (int i = 0; i < top.l.size() - 1; i++) {
  314.         mult += (top.l.at(i) + 1)*top.l.at(i + 1);
  315.     }
  316.     a_arr = new double[sum];
  317.     z_arr = new double[sum];
  318.  
  319.     W = new int[top.l.size()];
  320.     sw = new int[top.l.size()];
  321.  
  322.     w_arr = new double[mult];
  323.     dw_arr = new double[mult];
  324.  
  325.     t_arr = new double[top.l.at(top.l.size() - 1)];
  326.  
  327.     gjl = new double[sum];
  328. }
  329.  
  330. void AnnSerialDBL::init(Topology top, double w_arr_1[] = NULL)
  331. {
  332.     L = top.l.size();
  333.     //Neuronu kiekiai sluoksnyje
  334.     for (int i = 0; i < top.l.size(); i++) {
  335.         l[i] = top.l.at(i) + 1;
  336.     }
  337.  
  338.     //Sluoksniu pradzios indeksai
  339.     for (int i = 0; i < top.l.size(); i++) {
  340.         s[i] = 0;
  341.         for (int j = i; j > 0; j--) {
  342.             s[i] += l[j - 1];
  343.         }
  344.     }
  345.  
  346.     //Bias neuronai
  347.     for (int i = 0; i < top.l.size() - 1; i++) {
  348.         a_arr[s[i + 1] - 1] = 1;
  349.     }
  350.  
  351.     //Svoriu kiekiai l-ame sluoksnyje
  352.     for (int i = 0; i < top.l.size() - 1; i++) {
  353.         W[i] = l[i] * (l[i + 1] - 1);
  354.         //cout << "Svoriu sk: " << W[i] << " Pradzios index: ";
  355.         sw[i] = 0;
  356.         if (i != 0) {
  357.             for (int j = 0; j < i; j++) {
  358.                 sw[i] += W[j];
  359.             }
  360.         }
  361.         if (w_arr_1 == NULL) {
  362.             for (int j = 0; j < W[i]; j++) {
  363.                 w_arr[sw[i] + j] = (double)rand() / double(RAND_MAX);
  364.                 //cout << w_arr[sw[i] + j]<< endl;
  365.                 dw_arr[sw[i] + j] = 0;
  366.             }
  367.         }
  368.         else {
  369.             w_arr = w_arr_1; //ar reikia pokycius issisaugoti irgi?
  370.         }
  371.  
  372.         //cout << sw[i] << " " << endl;
  373.     }
  374. }
  375.  
  376. void AnnSerialDBL::train(double *a, double *b)
  377. {
  378.     for (int i = 0; i < inputs; i++) {
  379.         a_arr[i] = a[i];
  380.     }
  381.  
  382.     for (int j = 0; j < z_count; j++) {
  383.         z_arr[j] = 0;
  384.     }
  385.  
  386.     calc_feedForward();
  387.  
  388.     for (int i = 0; i < outputs; i++) {
  389.         t_arr[i] = b[i];
  390.     }
  391.     calc_gjl(a_arr, z_arr, t_arr, w_arr, s, sw, L,l, gjl);
  392.  
  393.     //back propogation:
  394.     for (int i = L - 2; i >= 0; i--) {//per sluoksnius
  395.         for (int j = 0; j < l[i]; j++) {//per neuronus
  396.             for (int k = 0; k < l[i + 1] - 1; k++) {//per kito sluoksnio neuronus
  397.                 dw_arr[sw[i] + k + j*(l[i + 1] - 1)] = delta_w(w_gradient(i, j, k, a_arr, s,gjl), dw_arr[sw[i] + k + j*(l[i + 1] - 1)]);
  398.                 w_arr[sw[i] + k + j*(l[i + 1] - 1)] += dw_arr[sw[i] + k + j*(l[i + 1] - 1)];
  399.             }
  400.         }
  401.     }
  402. }
  403.  
  404. void AnnSerialDBL::feedForward(double *a, double *b)
  405. {
  406.     for (int i = 0; i < inputs; i++) {
  407.         a_arr[i] = a[i];
  408.     }
  409.  
  410.     for (int j = 0; j < z_count; j++) {
  411.         z_arr[j] = 0;
  412.     }
  413.  
  414.     calc_feedForward();
  415.  
  416.     double max = 0;
  417.     int index = 0;
  418.  
  419.     for (int i = 0; i<outputs; i++) {
  420.         cout << " a reiksmes: " << a_arr[s[L - 1] + i] << endl;
  421.         if (max < a_arr[s[L - 1] + i]) {
  422.             max = a_arr[s[L - 1] + i];
  423.             index = i;
  424.         }
  425.     }
  426.     for (int i = 0; i < outputs; i++) {
  427.         if (i == index) {
  428.             b[i] = 1;
  429.         }
  430.         else {
  431.             b[i] = 0;
  432.         }
  433.     }
  434. }
  435.  
  436. void AnnSerialDBL::calc_feedForward()
  437. {
  438.     for (int i = 0; i < L - 1; i++) {//per sluoksnius einu+
  439.         for (int j = 0; j < l[i]; j++) { //kiek neuronu sluoksnyje+
  440.             for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z+
  441.                 z_arr[s[i + 1] + k] += w_arr[sw[i] + k + j*(l[i + 1] - 1)] * a_arr[s[i] + j];
  442.                 //  cout << "w: "<< w_arr[sw[i] + k + j*(l[i + 1] - 1)] << endl;
  443.                 //  cout << "a: " << a_arr[s[i] + j] << endl;
  444.                 //  cout << "z reiksmes: " << z_arr[s[i+1] + k] << endl;
  445.                 //  cout << endl;
  446.             }
  447.         }
  448.         for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z
  449.             a_arr[s[i + 1] + k] = f(z_arr[s[i + 1] + k]);
  450.             //  cout << s[i + 1] + k << " a reiksmes: " << a_arr[s[i + 1] + k] << endl;
  451.         }
  452.     }
  453. }
  454.  
  455. void AnnSerialDBL::destroy()
  456. {
  457.     delete[] l;
  458.     l = NULL;
  459.     delete[] s;
  460.     s = NULL;
  461.  
  462.     delete[] a_arr;
  463.     a_arr = NULL;
  464.     delete[] z_arr;
  465.     z_arr = NULL;
  466.  
  467.     delete[] W;
  468.     W = NULL;
  469.     delete[] sw;
  470.     sw = NULL;
  471.  
  472.     delete[] w_arr;
  473.     w_arr = NULL;
  474.     delete[] dw_arr;
  475.     dw_arr = NULL;
  476.  
  477.     delete[] t_arr;
  478.     t_arr = NULL;
  479.  
  480.     delete[] gjl;
  481.     gjl = NULL;
  482. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement