Advertisement
riabcis

Untitled

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