riabcis

Untitled

Mar 24th, 2018
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.04 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(5);
  159.     topolygy.l.push_back(6);
  160.     topolygy.l.push_back(7);
  161.     topolygy.l.push_back(2);
  162.     AnnSerialDBL labas;
  163.     labas.prepare(topolygy);
  164.     labas.init(topolygy, NULL);
  165.  
  166.  
  167.     //****temp
  168.     int sum = 0;
  169.     for (int i = 0; i < labas.L; i++) {
  170.         sum += topolygy.l.at(i) + 1;
  171.     }
  172.     //temp***
  173.  
  174.  
  175.     XOR xo;
  176.     xo.generate(60000);
  177.     for (int i = 0; i < xo.getNumberOfSamples(); i++) {
  178.         labas.train(xo.getInput(i), xo.getOutput(i));
  179.     }
  180.  
  181.  
  182.     //****temp
  183.     for (int i = 0; i < sum; i++) {
  184.     //  cout << labas.a_arr[i] << endl;
  185.     }
  186.     //******temp
  187.  
  188.  
  189.     //Checking results(all combinations 0 and 1)
  190.     for (double i = 0; i < 2;i++){
  191.         for (double j = 0; j < 2; j++) {
  192.             double input[] = {i ,j };
  193.             double output[] = { 0,0 };
  194.             labas.feedForward(input, output);
  195.  
  196.             cout << endl << "input : " << input[0] << "   " << input[1] << endl;
  197.             cout << endl << "output: " << output[0] << "   " << output[1] << endl<<endl;
  198.             cout << "---------------------------------------------------" << endl;
  199.         }
  200.     }
  201.  
  202.     //Checking results(all combinations 0 and 1)
  203.     for (double i = 0; i < 1; i++) {
  204.         double input[] = { randint()*1.0, randint()*1.0 };
  205.         double output[] = { 0,0 };
  206.         labas.feedForward(input, output);
  207.  
  208.         cout << endl << "input : " << input[0] << "   " << input[1] << endl;
  209.         cout << endl << "output: " << output[0] << "   " << output[1] << endl << endl;
  210.         cout << "---------------------------------------------------" << endl;
  211.     }
  212.  
  213.     labas.destroy();
  214.  
  215.     int a;
  216.     cout << kiek;
  217.     cin >> a;
  218.  
  219.     return 0;
  220. }
  221.  
  222. //returns random int, either 0 or 1
  223. int randint() {
  224.     double r = ((double)rand() / (RAND_MAX));
  225.     int a = 0;
  226.     if (r > 0.5) {
  227.         a = 1;
  228.     }
  229.     else
  230.     {
  231.         a = 0;
  232.     }
  233.     return a;
  234. }
  235.  
  236. void AnnSerialDBL::prepare(Topology top)
  237. {
  238.     l = new int[top.L];
  239.     s = new int[top.L];
  240.  
  241.     int sum = 0;
  242.     int mult = 0;
  243.     for (int i = 0; i < top.L; i++) {
  244.         sum += top.l.at(i) + 1;
  245.     }
  246.     sum1 = sum;
  247.     for (int i = 0; i < top.L - 1; i++) {
  248.         mult += (top.l.at(i) + 1)*top.l.at(i+1);
  249.     }
  250.     a_arr = new double[sum];
  251.     z_arr = new double[sum];
  252.  
  253.     W = new int[top.L];
  254.     sw = new int[top.L];
  255.  
  256.     w_arr = new double[mult];
  257.     dw_arr = new double[mult];
  258.  
  259.     t_arr = new double[top.l.at(top.L - 1)];
  260. }
  261.  
  262. void AnnSerialDBL::init(Topology top, double w_arr_1[] = NULL)
  263. {
  264.     L = top.L;
  265.     //Neuronu kiekiai sluoksnyje
  266.     for (int i = 0; i < top.L; i++) {
  267.         l[i] = top.l.at(i) + 1;
  268.     }
  269.  
  270.     //Sluoksniu pradzios indeksai
  271.     for (int i = 0; i < top.L; i++) {
  272.         s[i] = 0;
  273.         for (int j = i; j > 0; j--) {
  274.             s[i] += l[j - 1];
  275.         }
  276.     }
  277.  
  278.     //Bias neuronai
  279.     for (int i = 0; i < top.L - 1; i++) {
  280.         a_arr[s[i + 1] - 1] = 1;
  281.     }
  282.  
  283.     //Svoriu kiekiai l-ame sluoksnyje
  284.     for (int i = 0; i < top.L - 1; i++) {
  285.         W[i] = l[i] * (l[i + 1] - 1);
  286.         //cout << "Svoriu sk: " << W[i] << " Pradzios index: ";
  287.         sw[i] = 0;
  288.         if (i != 0) {
  289.             for (int j = 0; j < i; j++) {
  290.                 sw[i] += W[j];
  291.             }
  292.         }
  293.         if (w_arr_1 == NULL) {
  294.             for (int j = 0; j < W[i]; j++) {
  295.                 w_arr[sw[i] + j] = (double)rand() / double(RAND_MAX);
  296.                 //cout << w_arr[sw[i] + j]<< endl;
  297.                 dw_arr[sw[i] + j] = 0;
  298.             }
  299.         }
  300.         else {
  301.             w_arr = w_arr_1; //ar reikia pokycius issisaugoti irgi?
  302.         }
  303.  
  304.         //cout << sw[i] << " " << endl;
  305.     }
  306. }
  307.  
  308. void AnnSerialDBL::train(double *a,double *b)
  309. {
  310.     a_arr[0] = a[0];
  311.     a_arr[1] = a[1];
  312.  
  313.     for (int j = 0; j < sum1; j++) {
  314.         z_arr[j] = 0;
  315.     }
  316.  
  317.     //FFEEED FORWARD
  318.     for (int i = 0; i < L - 1; i++) {//per sluoksnius einu+
  319.         for (int j = 0; j < l[i]; j++) { //kiek neuronu sluoksnyje+
  320.             for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z+
  321.                 z_arr[s[i + 1] + k] += w_arr[sw[i] + k + j*(l[i + 1] - 1)] * a_arr[s[i] + j];
  322.                 //cout << " w: "<< w_arr[sw[i] + k + j*(l[i + 1]-1)] << endl;
  323.                 //cout << "a: " << a_arr[s[i] + j] << endl;
  324.                 //cout << "z reiksmes: " << z_arr[s[i+1] + k] << endl;
  325.                 //cout << endl;
  326.                 kiek++;//temp
  327.             }
  328.         }
  329.         for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z
  330.             a_arr[s[i + 1] + k] = f(z_arr[s[i + 1] + k]);
  331.         //  cout << s[i + 1] + k << " a reiksmes: " << a_arr[s[i + 1] + k] << endl;
  332.         }
  333.     }
  334.  
  335.     t_arr[0] = b[0];
  336.     t_arr[1] = b[1];
  337.  
  338.     //back propogation:
  339.     for (int i = L-2; i >=0; i--) {//per sluoksnius
  340.         for (int j = 0; j < l[i]; j++) {//per neuronus
  341.             for (int k = 0; k < l[i + 1] - 1; k++) {//per kito sluoksnio neuronus
  342.                 dw_arr[sw[i] + k+j*(l[i + 1] - 1)] = delta_w(w_gradient(i, j, k, a_arr, z_arr, t_arr, w_arr, s,sw, L, l), dw_arr[sw[i] + k+ j*(l[i + 1] - 1)]);
  343.                 w_arr[sw[i] + k+ j*(l[i + 1] - 1)] += dw_arr[sw[i] + k+ j*(l[i + 1] - 1)];
  344.             //  cout << w_arr[sw[i] + k] << " " << endl;
  345.             }
  346.         }
  347.     }
  348.  
  349. }
  350.  
  351. void AnnSerialDBL::feedForward(double *a, double *b)
  352. {
  353.     a_arr[0] = a[0];
  354.     a_arr[1] = a[1];
  355.  
  356.     for (int j = 0; j < sum1; j++) {
  357.         z_arr[j] = 0;
  358.     }
  359.     //FFEEED FORWARD
  360.     for (int i = 0; i < L - 1; i++) {//per sluoksnius einu+
  361.         for (int j = 0; j < l[i]; j++) { //kiek neuronu sluoksnyje+
  362.             for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z+
  363.                 z_arr[s[i + 1] + k] += w_arr[sw[i] + k + j*(l[i + 1] - 1)] * a_arr[s[i] + j];
  364.             //  cout << "w: "<< w_arr[sw[i] + k + j*(l[i + 1] - 1)] << endl;
  365.             //  cout << "a: " << a_arr[s[i] + j] << endl;
  366.             //  cout << "z reiksmes: " << z_arr[s[i+1] + k] << endl;
  367.             //  cout << endl;
  368.             }
  369.         }
  370.         for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z
  371.             a_arr[s[i + 1] + k] = f(z_arr[s[i + 1] + k]);
  372.         //  cout << s[i + 1] + k << " a reiksmes: " << a_arr[s[i + 1] + k] << endl;
  373.         }
  374.     }
  375.  
  376.     //cout << a_arr[s[L - 1]];
  377.     //cout << a_arr[s[L - 1]+1];
  378.     if (a_arr[s[L - 1]] > a_arr[s[L - 1] + 1]) {
  379.         b[0] = 1;
  380.         b[1] = 0;
  381.     }
  382.     else {
  383.         b[0] = 0;
  384.         b[1] = 1;
  385.     }
  386. }
  387.  
  388. void AnnSerialDBL::destroy()
  389. {
  390.     delete l;
  391.     l = NULL;
  392.     delete s;
  393.     s = NULL;
  394.  
  395.     delete a_arr;
  396.     a_arr = NULL;
  397.     delete z_arr;
  398.     z_arr = NULL;
  399.  
  400.     delete W;
  401.     W = NULL;
  402.     delete sw;
  403.     sw = NULL;
  404.  
  405.     delete w_arr;
  406.     w_arr = NULL;
  407.     delete dw_arr;
  408.     dw_arr = NULL;
  409.  
  410.     delete t_arr;
  411.     t_arr = NULL;
  412. }
  413.  
  414. double f(double x) {
  415.     double y = 1+exp(-x);
  416.     //temp*********************
  417.     if (y == 0) {
  418.         cout << "Error 1";
  419.     }
  420.         if ((y-1) == 0) {
  421.             //cout << "Error 2";
  422.         }
  423.     //temp**********************
  424.     return 1 / y;
  425. }
  426.  
  427.  
  428. double f_deriv(double x) {
  429.     //Temp**********
  430.     double y = pow((1 + exp(-x)), 2);
  431.     double z = exp(-x);
  432.     if (y == 0) {
  433.         cout << "Error 3";
  434.     }
  435.     if (z == 0) {
  436.         cout << "Error 4";
  437.     }
  438.     //temp**********************
  439.     return exp(-x) / pow((1 + exp(-x)), 2);
  440. }
  441.  
  442. double gL(double a, double z, double t) {
  443.     double w = f_deriv(z) * (a - t);
  444.     //cout << "z: " << z << " a: " << a << " t: " << t << endl;
  445.     return w;
  446. }
  447.  
  448. 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) {
  449.     double w = f_deriv(z_arr[s[layer_id] + w_j]);
  450.     double sum = 0;
  451.     for (int i = 0; i < l[layer_id + 1] - 1; i++) {
  452.         if (layer_id + 2 == L) {
  453.             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]);
  454.         }
  455.         else {
  456.             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);
  457.         }
  458.     }
  459.     return w*sum;
  460. }
  461.  
  462. 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) {
  463.     double w = a_arr[s[layer_id] + w_i];
  464.     if (layer_id + 2 == L) {
  465.         w *= gL(a_arr[s[layer_id + 1] + w_j], z_arr[s[layer_id + 1] + w_j], t_arr[w_j]);
  466.     }
  467.     else {
  468.         w *= gl(layer_id + 1, w_i, w_j, a_arr, z_arr, t_arr, w_arr, s, sw, L, l);
  469.     }
  470.     //cout << L << endl;
  471.     //cout << w << " layer id:"<< layer_id <<endl;
  472.     return w;
  473. }
  474.  
  475. double delta_w(double grad, double dw) {
  476.     return (-ETA)*grad + ALPHA*dw;
  477. }
Add Comment
Please, Sign In to add comment