Advertisement
riabcis

Untitled

Mar 18th, 2018
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.13 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.  
  10. struct Data {
  11.     std::vector<int> input;
  12.     std::vector<int> output;
  13. } data1;
  14.  
  15. struct Topology
  16. {
  17.     int L;
  18.     std::vector<int> l;
  19. } topolygy;
  20.  
  21. double f(double x);
  22. double f_deriv(double x);
  23. double gL(double a, double z, double t);
  24. 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);
  25. 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);
  26. double delta_w(double grad, double dw);
  27. int randint();
  28.  
  29. const double ETA = 0.1;
  30. const double ALPHA = 0.5;
  31.  
  32. class AnnBase {
  33. public:
  34.     virtual void prepare(Topology top) = 0;
  35.     virtual void init(Topology top, double w_arr_1[]) = 0;
  36.     virtual void train(Data data) = 0;
  37.     virtual void feedForward(Data data, double a, double b) = 0;
  38. };
  39.  
  40. class AnnSerialDBL : public AnnBase {
  41. public:
  42.     void prepare(Topology top);
  43.     void init(Topology top, double w_arr_1[]);
  44.     void train(Data data);
  45.     void feedForward(Data data,double a, double b);
  46. public:
  47.     int sum1;
  48.     int L;
  49.     int * l;
  50.     int * s;
  51.     double * a_arr;
  52.     double * z_arr;
  53.     int * W;
  54.     int * sw;
  55.     double * w_arr;
  56.     double * dw_arr;
  57.     double * t_arr;
  58. };
  59. using namespace std;
  60. int main()
  61. {
  62.     topolygy.L = 4;
  63.     topolygy.l.push_back(2);
  64.     topolygy.l.push_back(10);
  65.     topolygy.l.push_back(5);
  66.     topolygy.l.push_back(2);
  67.     topolygy.l.push_back(2);
  68.     AnnSerialDBL labas;
  69.     labas.prepare(topolygy);
  70.     labas.init(topolygy, NULL);
  71.  
  72.     for (int i = 0; i < topolygy.L; i++) {
  73.     //  cout << ": " << labas.W[i];
  74.     }
  75.     data1.input.push_back(1);
  76.     data1.output.push_back(2);
  77.     data1.input.push_back(1);
  78.     data1.output.push_back(2);
  79.  
  80.     for (int i = 0; i < 100; i++) {
  81.         int a = randint();
  82.         int b = randint();
  83.         data1.input[0] = a;
  84.         data1.input[1] = b;
  85.         if (a == b) {
  86.             data1.output[0] = 1;
  87.             data1.output[1] = 0;
  88.         }
  89.         else {
  90.             data1.output[0] = 0;
  91.             data1.output[1] = 1;
  92.         }
  93.  
  94.             labas.train(data1);
  95.     }
  96.  
  97.     int sum = 0;
  98.     int mult = 0;
  99.     for (int i = 0; i < labas.L; i++) {
  100.         sum += topolygy.l.at(i) + 1;
  101.     }
  102.     for (int i = 0; i < sum; i++) {
  103.     //  cout << labas.a_arr[i] << endl;
  104.     }
  105.  
  106.     for (int i = 0; i < 5;i++){
  107.     data1.input[0] = randint();;
  108.     data1.input[1] = randint();;
  109.     double t=1, y=0;
  110.     //cout << endl;
  111.     labas.feedForward(data1,t,y);
  112.  
  113.     cout << endl << "1: " << data1.input[0] << " 2: " << data1.input[1] << endl;
  114.     cout << endl << "1: " << data1.output[0] << " 2: " << data1.output[1] << endl<<endl;
  115.  
  116.  
  117.     }
  118.  
  119.  
  120.     int a;
  121.     cin >> a;
  122.  
  123.     return 0;
  124. }
  125.  
  126. int randint() {
  127.     double r = ((double)rand() / (RAND_MAX));
  128.     int a = 0;
  129.     if (r > 0.5) {
  130.         a = 1;
  131.     }
  132.     else
  133.     {
  134.         a = 0;
  135.     }
  136.     return a;
  137. }
  138.  
  139. void AnnSerialDBL::prepare(Topology top)
  140. {
  141.     l = new int[top.L];
  142.     s = new int[top.L];
  143.  
  144.     int sum = 0;
  145.     int mult = 0;
  146.     for (int i = 0; i < top.L; i++) {
  147.         sum += top.l.at(i) + 1;
  148.     }
  149.     sum1 = sum;
  150.     for (int i = 0; i < top.L - 1; i++) {
  151.         mult += (top.l.at(i) + 1)*top.l.at(i+1);
  152.     }
  153.     a_arr = new double[sum];
  154.     z_arr = new double[sum];
  155.  
  156.     W = new int[top.L];
  157.     sw = new int[top.L];
  158.  
  159.     w_arr = new double[mult];
  160.     dw_arr = new double[mult];
  161.  
  162.     t_arr = new double[top.l.at(top.L - 1)];
  163. }
  164.  
  165. void AnnSerialDBL::init(Topology top, double w_arr_1[] = NULL)
  166. {
  167.     L = top.L;
  168.     //Neuronu kiekiai sluoksnyje
  169.     for (int i = 0; i < top.L; i++) {
  170.         l[i] = top.l.at(i) + 1;
  171.     }
  172.  
  173.     //Sluoksniu pradzios indeksai
  174.     for (int i = 0; i < top.L; i++) {
  175.         s[i] = 0;
  176.         for (int j = i; j > 0; j--) {
  177.             s[i] += l[j - 1];
  178.         }
  179.     }
  180.  
  181.     //Bias neuronai
  182.     for (int i = 0; i < top.L - 1; i++) {
  183.         a_arr[s[i + 1] - 1] = 1;
  184.     }
  185.  
  186.     //Svoriu kiekiai l-ame sluoksnyje
  187.     for (int i = 0; i < top.L - 1; i++) {
  188.         W[i] = l[i] * (l[i + 1] - 1);
  189.         //cout << "Svoriu sk: " << W[i] << " Pradzios index: ";
  190.         sw[i] = 0;
  191.         if (i != 0) {
  192.             for (int j = 0; j < i; j++) {
  193.                 sw[i] += W[j];
  194.             }
  195.         }
  196.         if (w_arr_1 == NULL) {
  197.             for (int j = 0; j < W[i]; j++) {
  198.                 w_arr[sw[i] + j] = (double)rand() / double(RAND_MAX);
  199.                 //cout << w_arr[sw[i] + j]<< endl;
  200.                 dw_arr[sw[i] + j] = 0;
  201.             }
  202.         }
  203.         else {
  204.             w_arr = w_arr_1; //ar reikia pokycius issisaugoti irgi?
  205.         }
  206.  
  207.         //cout << sw[i] << " " << endl;
  208.     }
  209. }
  210.  
  211. void AnnSerialDBL::train(Data data)
  212. {
  213.     a_arr[0] = (double)data.input[0];
  214.     a_arr[1] = (double)data.input[1];
  215.  
  216.     for (int j = 0; j < sum1; j++) {
  217.         z_arr[j] = 0;
  218.     }
  219.  
  220.     //FFEEED FORWARD
  221.     for (int i = 0; i < L - 1; i++) {//per sluoksnius einu+
  222.         for (int j = 0; j < l[i]; j++) { //kiek neuronu sluoksnyje+
  223.             for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z+
  224.                 z_arr[s[i + 1] + k] += w_arr[sw[i] + k + j*l[i + 1]] * a_arr[s[i] + j];
  225.                 //cout << "w: "<< w_arr[sw[i] + k + j*l[i + 1]] << endl;
  226.                 //cout << "a: " << a_arr[s[i] + j] << endl;
  227.                 cout << "z reiksmes: " << z_arr[s[i+1] + k] << endl;
  228.                 cout << endl;
  229.             }
  230.         }
  231.         for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z
  232.             a_arr[s[i + 1] + k] = f(z_arr[s[i + 1] + k]);
  233.             cout << s[i + 1] + k << " a reiksmes: " << a_arr[s[i + 1] + k] << endl;
  234.         }
  235.     }
  236.  
  237.     t_arr[0] = (double)data.output[0];
  238.     t_arr[1] = (double)data.output[1];
  239.  
  240.     //back propogation:
  241.     for (int i = 0; i < L - 1; i++) {//per sluoksnius
  242.         for (int j = 0; j < l[i]; j++) {//per neuronus
  243.             for (int k = 0; k < l[i + 1] - 1; k++) {//per kito sluoksnio neuronus
  244.                 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]);
  245.                 w_arr[sw[i] + k] += dw_arr[sw[i] + k];
  246.             //  cout << w_arr[sw[i] + k] << " " << endl;
  247.             }
  248.         }
  249.     }
  250.  
  251. }
  252.  
  253. void AnnSerialDBL::feedForward(Data data, double a, double b)
  254. {
  255.     a_arr[0] = (double)data.input[0];
  256.     a_arr[1] = (double)data.input[1];
  257.     for (int j = 0; j < sum1; j++) {
  258.         z_arr[j] = 0;
  259.     }
  260.     //FFEEED FORWARD
  261.     for (int i = 0; i < L - 1; i++) {//per sluoksnius einu+
  262.         for (int j = 0; j < l[i]; j++) { //kiek neuronu sluoksnyje+
  263.             for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z+
  264.                 z_arr[s[i + 1] + k] += w_arr[sw[i] + k + j*l[i + 1]] * a_arr[s[i] + j];
  265.                 /*  cout << "w: "<< w_arr[sw[i] + k + j*l[i + 1]] << endl;
  266.                 cout << "a: " << a_arr[s[i] + j] << endl;
  267.                 cout << "z reiksmes: " << z_arr[s[i+1] + k] << endl;
  268.                 cout << endl;*/
  269.             }
  270.         }
  271.         for (int k = 0; k < l[i + 1] - 1; k++) {//per sekancio sluoksnio z
  272.             a_arr[s[i + 1] + k] = f(z_arr[s[i + 1] + k]);
  273.         //  cout << s[i + 1] + k << " a reiksmes: " << a_arr[s[i + 1] + k] << endl;
  274.         }
  275.     }
  276.     //cout << a_arr[s[L - 1]];
  277.     //cout << a_arr[s[L - 1]+1];
  278.     a = a_arr[s[L-1]];
  279.     b = a_arr[s[L-1]+1];
  280.     if (a < b) {
  281.         data.output[0] = 1;
  282.         data.output[0] = 0;
  283.     }
  284.     else {
  285.         data.output[1] = 0;
  286.         data.output[1] = 1;
  287.     }
  288. //data.output[0] = a_arr[s[L - 1]];
  289. //  data.output[1] = a_arr[s[L - 1] + 1];
  290. }
  291.  
  292. double f(double x) {
  293.     return 1 / (1 + exp(-x));
  294. }
  295.  
  296.  
  297. double f_deriv(double x) {
  298.     return exp(-x) / pow((1 + exp(-x)), 2);
  299. }
  300.  
  301. double gL(double a, double z, double t) {
  302.     double w = f_deriv(z) * (a - t);
  303.     //cout << "z: " << z << " a: " << a << " t: " << t << endl;
  304.     return w;
  305. }
  306.  
  307. 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) {
  308.     double w = f_deriv(z_arr[s[layer_id] + w_j]);
  309.     double sum = 0;
  310.     for (int i = 0; i < l[layer_id + 1] - 1; i++) {
  311.         if (layer_id + 2 == L) {
  312.             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]);
  313.         }
  314.         else {
  315.             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);
  316.         }
  317.     }
  318.     return w*sum;
  319. }
  320.  
  321. 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) {
  322.     double w = a_arr[s[layer_id] + w_i];
  323.     if (layer_id + 2 == L) {
  324.         w *= gL(a_arr[s[layer_id + 1] + w_j], z_arr[s[layer_id + 1] + w_j], t_arr[w_j]);
  325.     }
  326.     else {
  327.         w *= gl(layer_id + 1, w_i, w_j, a_arr, z_arr, t_arr, w_arr, s, sw, L, l);
  328.     }
  329.     //cout << L << endl;
  330.     //cout << w << " layer id:"<< layer_id <<endl;
  331.     return w;
  332. }
  333.  
  334. double delta_w(double grad, double dw) {
  335.     return -ETA*grad + ALPHA*dw;
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement