NetworkGraph.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <?php
  2. /**
  3. * Artificial Neural Network - Version 2.2
  4. *
  5. * For updates and changes visit the project page at http://ann.thwien.de/
  6. *
  7. *
  8. *
  9. * <b>LICENCE</b>
  10. *
  11. * The BSD 2-Clause License
  12. *
  13. * http://opensource.org/licenses/bsd-license.php
  14. *
  15. * Copyright (c) 2007 - 2012, Thomas Wien
  16. * All rights reserved.
  17. *
  18. * Redistribution and use in source and binary forms, with or without
  19. * modification, are permitted provided that the following conditions
  20. * are met:
  21. *
  22. * 1. Redistributions of source code must retain the above copyright
  23. * notice, this list of conditions and the following disclaimer.
  24. *
  25. * 2. Redistributions in binary form must reproduce the above copyright
  26. * notice, this list of conditions and the following disclaimer in the
  27. * documentation and/or other materials provided with the distribution.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  31. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  32. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  33. * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  34. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  35. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  37. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  39. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGE.
  41. *
  42. * @author Thomas Wien <info_at_thwien_dot_de>
  43. * @version ANN Version 2.2 by Thomas Wien
  44. * @copyright Copyright (c) 2007-2012 by Thomas Wien
  45. * @package ANN
  46. */
  47. namespace ANN;
  48. /**
  49. * @package ANN
  50. * @access public
  51. */
  52. class NetworkGraph
  53. {
  54. /**#@+
  55. * @ignore
  56. */
  57. /**
  58. * @var integer
  59. */
  60. protected $intNumberInputs;
  61. /**
  62. * @var integer
  63. */
  64. protected $intNumberHiddenLayers;
  65. /**
  66. * @var integer
  67. */
  68. protected $intNumberNeuronsOfHiddenLayer;
  69. /**
  70. * @var integer
  71. */
  72. protected $intNumberOfOutputs;
  73. /**
  74. * @var resource
  75. */
  76. protected $handleImage;
  77. /**
  78. * @var resource
  79. */
  80. protected $handleColorNeuronInput;
  81. /**
  82. * @var resource
  83. */
  84. protected $handleColorNeuronHidden;
  85. /**
  86. * @var resource
  87. */
  88. protected $handleColorNeuronOutput;
  89. /**
  90. * @var resource
  91. */
  92. protected $handleColorNeuronBorder;
  93. /**
  94. * @var resource
  95. */
  96. protected $handleColorBackground;
  97. /**
  98. * @var resource
  99. */
  100. protected $handleColorConnection;
  101. /**
  102. * @var integer
  103. */
  104. protected $intMaxNeuronsPerLayer;
  105. /**
  106. * @var integer
  107. */
  108. protected $intLayerDistance = 250;
  109. /**
  110. * @var integer
  111. */
  112. protected $intNeuronDistance = 50;
  113. /**#@-*/
  114. /**
  115. * @param Network $objNetwork
  116. * @uses createImage()
  117. * @uses drawNetwork()
  118. * @uses Network::getNumberHiddenLayers()
  119. * @uses Network::getNumberInputs()
  120. * @uses Network::getNumberHiddens()
  121. * @uses Network::getNumberOutputs()
  122. */
  123. public function __construct(Network $objNetwork)
  124. {
  125. $this->intNumberInputs = $objNetwork->getNumberInputs();
  126. $this->intNumberHiddenLayers = $objNetwork->getNumberHiddenLayers();
  127. $this->intNumberNeuronsOfHiddenLayer = $objNetwork->getNumberHiddens();
  128. $this->intNumberOfOutputs = $objNetwork->getNumberOutputs();
  129. $this->intMaxNeuronsPerLayer = max($this->intNumberInputs, $this->intNumberNeuronsOfHiddenLayer, $this->intNumberOfOutputs);
  130. $this->createImage();
  131. $this->drawNetwork();
  132. }
  133. /**
  134. * @uses drawConnections()
  135. * @uses drawHiddenNeurons()
  136. * @uses drawInputNeurons()
  137. * @uses drawOutputNeurons()
  138. */
  139. protected function drawNetwork()
  140. {
  141. $this->drawConnections();
  142. $this->drawInputNeurons();
  143. $this->drawHiddenNeurons();
  144. $this->drawOutputNeurons();
  145. }
  146. /**
  147. * @uses drawConnectionsHiddenOutput()
  148. * @uses drawConnectionsHiddens()
  149. * @uses drawConnectionsInputHidden()
  150. */
  151. protected function drawConnections()
  152. {
  153. $this->drawConnectionsInputHidden();
  154. $this->drawConnectionsHiddens();
  155. $this->drawConnectionsHiddenOutput();
  156. }
  157. /**
  158. * @uses calculateYPosStart()
  159. */
  160. protected function drawConnectionsInputHidden()
  161. {
  162. $intYPosHiddenStart = $this->calculateYPosStart($this->intNumberNeuronsOfHiddenLayer);
  163. $intYPosInputStart = $this->calculateYPosStart($this->intNumberInputs);
  164. for($intIndexInput = 0; $intIndexInput < $this->intNumberInputs; $intIndexInput++)
  165. for($intIndexHidden = 0; $intIndexHidden < $this->intNumberNeuronsOfHiddenLayer; $intIndexHidden++)
  166. {
  167. $intXPosInput = 100;
  168. $intYPosInput = $intYPosInputStart + $this->intNeuronDistance * $intIndexInput;
  169. $intXPosHidden = 100 + $this->intLayerDistance;
  170. $intYPosHidden = $intYPosHiddenStart + $this->intNeuronDistance * $intIndexHidden;
  171. imageline($this->handleImage, $intXPosInput, $intYPosInput, $intXPosHidden, $intYPosHidden, $this->handleColorConnection);
  172. }
  173. }
  174. /**
  175. * @uses calculateYPosStart()
  176. */
  177. protected function drawConnectionsHiddenOutput()
  178. {
  179. for($intIndexLayer = 0; $intIndexLayer < $this->intNumberHiddenLayers; $intIndexLayer++)
  180. $intXPosHidden = 100 + $this->intLayerDistance + $this->intLayerDistance * $intIndexLayer;
  181. $intYPosHiddenStart = $this->calculateYPosStart($this->intNumberNeuronsOfHiddenLayer);
  182. $intYPosOutputStart = $this->calculateYPosStart($this->intNumberOfOutputs);
  183. for($intIndexOutput = 0; $intIndexOutput < $this->intNumberOfOutputs; $intIndexOutput++)
  184. for($intIndexHidden = 0; $intIndexHidden < $this->intNumberNeuronsOfHiddenLayer; $intIndexHidden++)
  185. {
  186. $intXPosHidden = $intXPosHidden;
  187. $intYPosHidden = $intYPosHiddenStart + $this->intNeuronDistance * $intIndexHidden;
  188. $intXPosOutput = $intXPosHidden + $this->intLayerDistance;
  189. $intYPosOutput = $intYPosOutputStart + $this->intNeuronDistance * $intIndexOutput;
  190. imageline($this->handleImage, $intXPosHidden, $intYPosHidden, $intXPosOutput, $intYPosOutput, $this->handleColorConnection);
  191. }
  192. }
  193. /**
  194. * @uses calculateYPosStart()
  195. */
  196. protected function drawConnectionsHiddens()
  197. {
  198. if($this->intNumberHiddenLayers <= 1)
  199. return;
  200. $intYPosHiddenStart = $this->calculateYPosStart($this->intNumberNeuronsOfHiddenLayer);
  201. for($intIndexLayer = 1; $intIndexLayer < $this->intNumberHiddenLayers; $intIndexLayer++)
  202. for($intIndexHidden1 = 0; $intIndexHidden1 < $this->intNumberNeuronsOfHiddenLayer; $intIndexHidden1++)
  203. for($intIndexHidden2 = 0; $intIndexHidden2 < $this->intNumberNeuronsOfHiddenLayer; $intIndexHidden2++)
  204. {
  205. $intXPosHidden1 = 100 + $this->intLayerDistance + $this->intLayerDistance * $intIndexLayer - $this->intLayerDistance;
  206. $intYPosHidden1 = $intYPosHiddenStart + $this->intNeuronDistance * $intIndexHidden1;
  207. $intXPosHidden2 = 100 + $this->intLayerDistance + $this->intLayerDistance * $intIndexLayer;
  208. $intYPosHidden2 = $intYPosHiddenStart + $this->intNeuronDistance * $intIndexHidden2;
  209. imageline($this->handleImage, $intXPosHidden1, $intYPosHidden1, $intXPosHidden2, $intYPosHidden2, $this->handleColorConnection);
  210. }
  211. }
  212. /**
  213. * @uses calculateYPosStart()
  214. */
  215. protected function drawInputNeurons()
  216. {
  217. $intYPosInputStart = $this->calculateYPosStart($this->intNumberInputs);
  218. for($intIndex = 0; $intIndex < $this->intNumberInputs; $intIndex++)
  219. {
  220. imagefilledellipse($this->handleImage, 100, $intYPosInputStart + $this->intNeuronDistance * $intIndex, 30, 30, $this->handleColorNeuronInput);
  221. imageellipse($this->handleImage, 100, $intYPosInputStart + $this->intNeuronDistance * $intIndex, 30, 30, $this->handleColorNeuronBorder);
  222. }
  223. }
  224. /**
  225. * @uses calculateYPosStart()
  226. */
  227. protected function drawHiddenNeurons()
  228. {
  229. $intYPosHiddenStart = $this->calculateYPosStart($this->intNumberNeuronsOfHiddenLayer);
  230. for($intIndexLayer = 0; $intIndexLayer < $this->intNumberHiddenLayers; $intIndexLayer++)
  231. for($intIndexNeuron = 0; $intIndexNeuron < $this->intNumberNeuronsOfHiddenLayer; $intIndexNeuron++)
  232. {
  233. imagefilledellipse($this->handleImage, 100 + $this->intLayerDistance + $this->intLayerDistance * $intIndexLayer, $intYPosHiddenStart + $this->intNeuronDistance * $intIndexNeuron, 30, 30, $this->handleColorNeuronHidden);
  234. imageellipse($this->handleImage, 100 + $this->intLayerDistance + $this->intLayerDistance * $intIndexLayer, $intYPosHiddenStart + $this->intNeuronDistance * $intIndexNeuron, 30, 30, $this->handleColorNeuronBorder);
  235. }
  236. }
  237. /**
  238. * @uses calculateYPosStart()
  239. */
  240. protected function drawOutputNeurons()
  241. {
  242. for($intIndexLayer = 0; $intIndexLayer < $this->intNumberHiddenLayers; $intIndexLayer++)
  243. $xpos = 100 + $this->intLayerDistance + $this->intLayerDistance * $intIndexLayer;
  244. $yposStart = $this->calculateYPosStart($this->intNumberOfOutputs);
  245. for($intIndexNeuron = 0; $intIndexNeuron < $this->intNumberOfOutputs; $intIndexNeuron++)
  246. {
  247. imagefilledellipse($this->handleImage, $xpos + $this->intLayerDistance, $yposStart + $this->intNeuronDistance * $intIndexNeuron, 30, 30, $this->handleColorNeuronOutput);
  248. imageellipse($this->handleImage, $xpos + $this->intLayerDistance, $yposStart + $this->intNeuronDistance * $intIndexNeuron, 30, 30, $this->handleColorNeuronBorder);
  249. }
  250. }
  251. /**
  252. * @uses calculateImageHeight()
  253. * @uses calculateImageWidth()
  254. * @uses setBackground()
  255. * @uses setColors()
  256. */
  257. protected function createImage()
  258. {
  259. $this->handleImage = imagecreatetruecolor($this->calculateImageWidth(), $this->calculateImageHeight());
  260. $this->setColors();
  261. $this->setBackground();
  262. }
  263. protected function setColors()
  264. {
  265. $this->handleColorBackground = imagecolorallocate($this->handleImage, 200, 200, 200);
  266. $this->handleColorNeuronInput = imagecolorallocate($this->handleImage, 0, 255, 0);
  267. $this->handleColorNeuronHidden = imagecolorallocate($this->handleImage, 255, 0, 0);
  268. $this->handleColorNeuronOutput = imagecolorallocate($this->handleImage, 0, 0, 255);
  269. $this->handleColorConnection = imagecolorallocate($this->handleImage, 155, 255, 155);
  270. $this->handleColorNeuronBorder = imagecolorallocate($this->handleImage, 0, 0, 0);
  271. }
  272. protected function setBackground()
  273. {
  274. imagefill($this->handleImage, 0, 0, $this->handleColorBackground);
  275. }
  276. /**
  277. * Returns PNG image
  278. *
  279. * @return binary Image
  280. */
  281. public function getImage()
  282. {
  283. ob_start();
  284. imagepng($this->handleImage);
  285. $binReturn = ob_get_contents();
  286. ob_end_clean();
  287. return $binReturn;
  288. }
  289. /**
  290. * Print PNG image
  291. *
  292. * @uses getImage()
  293. */
  294. public function printImage()
  295. {
  296. header('Content-type: image/png');
  297. print $this->getImage();
  298. }
  299. /**
  300. * @param integer $intNumberNeurons
  301. * @return integer
  302. */
  303. protected function calculateYPosStart($intNumberNeurons)
  304. {
  305. $v1 = $this->intMaxNeuronsPerLayer * $this->intNeuronDistance / 2;
  306. $v2 = $intNumberNeurons * $this->intNeuronDistance / 2;
  307. return $v1 - $v2 + $this->intNeuronDistance;
  308. }
  309. /**
  310. * @return integer Pixel
  311. */
  312. protected function calculateImageHeight()
  313. {
  314. return (int)($this->intMaxNeuronsPerLayer * $this->intNeuronDistance + $this->intNeuronDistance);
  315. }
  316. /**
  317. * @return integer Pixel
  318. */
  319. protected function calculateImageWidth()
  320. {
  321. return (int)(($this->intNumberHiddenLayers + 2) * $this->intLayerDistance);
  322. }
  323. /**
  324. * Saves PNG image
  325. *
  326. * @param string $strFilename
  327. * @uses getImage()
  328. */
  329. public function saveToFile($strFilename)
  330. {
  331. file_put_contents($strFilename, $this->getImage());
  332. }
  333. }