fork(1) download
  1. #pragma once
  2.  
  3. #include "stdafx.h"
  4.  
  5. namespace ANN {
  6.  
  7. class Neuron;
  8. class Connection {
  9. public:
  10. Neuron * From;
  11. double Weight;
  12.  
  13. Connection(Neuron * From):From(From) {
  14. Weight = (2.0*(double)rand()/(double)RAND_MAX)-1.0;
  15. }
  16.  
  17. Connection(Neuron * From, double w):From(From) {
  18. Weight = w;
  19. }
  20.  
  21. void Randomize()
  22. {
  23. Weight = (2.0*(double)rand()/(double)RAND_MAX)-1.0;
  24. }
  25.  
  26. void AdjustWeight(double Delta) {
  27. Weight += Delta;
  28. // Weight = std::max(std::min(Weight, 1.0), -1.0);
  29. }
  30. };
  31.  
  32. class Neuron {
  33. public:
  34. Neuron()
  35. {
  36. Output = 0;
  37. Bias = false;
  38. }
  39. void CalcOutput(std::vector<Connection *> & Connections) {
  40. if (Bias) {
  41. } else {
  42. double Sum = 0;
  43. for (int i = 0; i < Connections.size(); i++) {
  44. Neuron & From = *Connections[i]->From;
  45. Sum += From.Output*Connections[i]->Weight;
  46. }
  47. Output = f(Sum);
  48. }
  49. }
  50. void SetBias()
  51. {
  52. Output = 1;
  53. Bias = true;
  54. }
  55. double f(double x) {
  56. return std::max(std::min(x, 1.0), 0.0);
  57. // return 0.5*((sqrt(fabs((x-0.5)/0.5))*(x>0.5?1.0:-1.0))+1.0);
  58. // return x>0.55?1.0:(x<0.45?0.0:0.5);
  59. // return x>0.0?1.0:-1.0;
  60. // return x>0.0?1.0:0.0;
  61. // return fabs(x)<0.2?0.0:(x>0.0?1.0:-1.0);
  62. // return 1.0 / (1.0 + (double) exp(-x));
  63. // return 1.0 / (1.0 + (double) pow(2.1, -x));
  64. }
  65. double Output;
  66. bool Bias;
  67. };
  68.  
  69. class Network {
  70. public:
  71. std::vector<Neuron *> Input, Output;
  72. std::vector<Neuron *> Hidden;
  73. std::vector<std::vector<Connection *> > InputToHidden, InputToOutput, HiddenToOutput;
  74.  
  75. double LearnConstant;
  76.  
  77. std::string DebugString()
  78. {
  79. std::ostringstream OStr;
  80. if (Hidden.size()>0)
  81. {
  82. OStr<<"(";
  83. for (unsigned int i=0; i<Hidden.size()-1; i++)
  84. OStr<<(floor(Hidden[i]->Output*100.0)/100.0)<<", ";
  85. OStr<<Hidden[Hidden.size()-1]->Output<<") ";
  86. }
  87. return OStr.str();
  88. }
  89.  
  90. std::string WeightsString(unsigned int k)
  91. {
  92. std::ostringstream OStr;
  93. if (Hidden.size()==0)
  94. {
  95. std::vector<std::vector<Connection *> > & Current = InputToOutput;
  96. OStr<<"(";
  97. for (unsigned int i=0; i<Current.size(); i++)
  98. {
  99. for (unsigned int j=0; j<Current[i].size(); j++)
  100. OStr<<(floor(Current[i][j]->Weight*100.0)/100.0)<<", ";
  101. OStr<<"; ";
  102. }
  103. OStr<<") ";
  104. return OStr.str();
  105. }
  106. for (unsigned int k=0; k<2; k++)
  107. {
  108. std::vector<std::vector<Connection *> > & Current = k==0?InputToHidden:HiddenToOutput;
  109. OStr<<"(";
  110. for (unsigned int i=0; i<Current.size(); i++)
  111. {
  112. for (unsigned int j=0; j<Current[i].size(); j++)
  113. OStr<<(floor(Current[i][j]->Weight*100.0)/100.0)<<", ";
  114. OStr<<"; ";
  115. }
  116. OStr<<") ";
  117. }
  118. return OStr.str();
  119. }
  120.  
  121. // InputAmount - The number of inputs the network expects.
  122. // HiddenAmount - The number of hidden Neurons in the hidden layer. Pass 0 for a Perceptron.
  123. // OutputAmount - The number of outputs the network will produce.
  124. // LearnConstant - A value between 0.0 and 1.0 to specify how fast/accurate the network learns.
  125. Network(unsigned int InputAmount, unsigned int HiddenAmount, unsigned int OutputAmount, double LearnConstant):LearnConstant(LearnConstant) {
  126. Input.resize(InputAmount+1);
  127. Output.resize(OutputAmount);
  128.  
  129. for (int i = 0; i < Input.size(); i++) {
  130. Input[i] = new Neuron();
  131. }
  132. if (HiddenAmount>0)
  133. {
  134. Hidden.resize(HiddenAmount+1);
  135. for (int i = 0; i < Hidden.size(); i++) {
  136. Hidden[i] = new Neuron();
  137. }
  138. Hidden[Hidden.size()-1]->SetBias();
  139. }
  140. Input[Input.size()-1]->SetBias();
  141.  
  142. for (int i = 0; i < Output.size(); i++) {
  143. Output[i] = new Neuron();
  144. }
  145.  
  146.  
  147. if (HiddenAmount>0)
  148. {
  149. InputToHidden.resize(Hidden.size());
  150. for (int i = 0; i < Hidden.size(); i++) {
  151. InputToHidden[i].resize(Input.size());
  152. for (int j = 0; j < Input.size(); j++) {
  153. InputToHidden[i][j] = new Connection (Input[j]);
  154. }
  155. }
  156.  
  157. HiddenToOutput.resize(Output.size());
  158. for (int i = 0; i < Output.size(); i++) {
  159. HiddenToOutput[i].resize(Hidden.size());
  160. for (int j = 0; j < Hidden.size(); j++) {
  161. HiddenToOutput[i][j] = new Connection (Hidden[j]);
  162. }
  163. }
  164. }
  165. else
  166. {
  167. InputToOutput.resize(Output.size());
  168. for (int i = 0; i < Output.size(); i++) {
  169. InputToOutput[i].resize(Input.size());
  170. for (int j = 0; j < Input.size(); j++) {
  171. InputToOutput[i][j] = new Connection (Input[j]);
  172. }
  173. }
  174. }
  175. }
  176.  
  177. void RandomizeWeights()
  178. {
  179. if (Hidden.size()>0)
  180. {
  181. for (int i = 0; i < Hidden.size(); i++) {
  182. for (int j = 0; j < Input.size(); j++) {
  183. InputToHidden[i][j]->Randomize();
  184. }
  185. }
  186.  
  187. for (int i = 0; i < Output.size(); i++) {
  188. for (int j = 0; j < Hidden.size(); j++) {
  189. HiddenToOutput[i][j]->Randomize();
  190. }
  191. }
  192. }
  193. else
  194. for (int i = 0; i < Output.size(); i++) {
  195. for (int j = 0; j < Input.size(); j++) {
  196. InputToOutput[i][j]->Randomize();
  197. }
  198. }
  199. }
  200.  
  201. void FeedForward(std::vector<double> & InputValues, std::vector<double> & OutputValues)
  202. {
  203. for (unsigned int i = 0; i < InputValues.size(); i++) {
  204. Input[i]->Output = InputValues[i];
  205. }
  206.  
  207. if (Hidden.size()>0)
  208. {
  209. for (int i = 0; i < Hidden.size()-1; i++) {
  210. Hidden[i]->CalcOutput(InputToHidden[i]);
  211. }
  212.  
  213. for (int i = 0; i < Output.size(); i++) {
  214. Output[i]->CalcOutput(HiddenToOutput[i]);
  215. }
  216. }
  217. else
  218. {
  219. for (int i = 0; i < Output.size(); i++) {
  220. Output[i]->CalcOutput(InputToOutput[i]);
  221. }
  222. }
  223.  
  224. for (int i = 0; i < Output.size(); i++) {
  225. OutputValues[i] = Output[i]->Output;
  226. }
  227. }
  228.  
  229. void Train(std::vector<double> & Delta)
  230. {
  231. Propagate (Delta, LearnConstant);
  232. }
  233.  
  234. double InverseF(double y) {
  235. return -log((1.0/y) - 1.0);
  236. }
  237.  
  238. void Propagate(std::vector<double> & Delta, double Constant)
  239. {
  240. if (Hidden.size()==0)
  241. {
  242. for (unsigned int i = 0; i < Output.size(); i++)
  243. {
  244. for (unsigned int j = 0; j < InputToOutput[i].size(); j++)
  245. {
  246. double DeltaOutput = Delta[i];
  247. double DeltaWeight = DeltaOutput;
  248. InputToOutput[i][j]->AdjustWeight (Input[j]->Output*DeltaWeight*Constant);
  249. }
  250. }
  251. return;
  252. }
  253. for (unsigned int i = 0; i < Output.size(); i++)
  254. {
  255. for (unsigned int j = 0; j < HiddenToOutput[i].size(); j++)
  256. {
  257. double DeltaOutput = Delta[i];
  258. double DeltaWeight = DeltaOutput;
  259. HiddenToOutput[i][j]->AdjustWeight (Hidden[j]->Output*DeltaWeight*Constant);
  260. }
  261. }
  262. for (unsigned int i = 0; i < Hidden.size(); i++)
  263. {
  264. double Sum = 0;
  265. for (unsigned int j = 0; j < Output.size(); j++)
  266. Sum+=HiddenToOutput[j][i]->Weight*Delta[j];
  267. double Output1 = Hidden[i]->Output;
  268. // double DeltaHidden = Output1 * (1.0 - Output1);
  269. double DeltaHidden = Output1;
  270. DeltaHidden *= Sum;
  271. for (unsigned int j = 0; j < Input.size(); j++)
  272. {
  273. float DeltaWeight = Input[j]->Output*DeltaHidden;
  274. InputToHidden[i][j]->AdjustWeight(Constant*DeltaWeight);
  275. }
  276. }
  277. }
  278. };
  279. }
  280.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty