Advertisement
riabcis

Untitled

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