Layer.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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) 2002, Eddy Young
  16. * Copyright (c) 2007 - 2012, Thomas Wien
  17. * All rights reserved.
  18. *
  19. * Redistribution and use in source and binary forms, with or without
  20. * modification, are permitted provided that the following conditions
  21. * are met:
  22. *
  23. * 1. Redistributions of source code must retain the above copyright
  24. * notice, this list of conditions and the following disclaimer.
  25. *
  26. * 2. Redistributions in binary form must reproduce the above copyright
  27. * notice, this list of conditions and the following disclaimer in the
  28. * documentation and/or other materials provided with the distribution.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  33. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  34. * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  35. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  39. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  40. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41. * POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. * @author Eddy Young <jeyoung_at_priscimon_dot_com>
  44. * @author Thomas Wien <info_at_thwien_dot_de>
  45. * @version ANN Version 1.0 by Eddy Young
  46. * @version ANN Version 2.2 by Thomas Wien
  47. * @copyright Copyright (c) 2002 by Eddy Young
  48. * @copyright Copyright (c) 2007-2012 by Thomas Wien
  49. * @package ANN
  50. */
  51. namespace ANN;
  52. /**
  53. * @package ANN
  54. * @access private
  55. */
  56. final class Layer
  57. {
  58. /**#@+
  59. * @ignore
  60. */
  61. /**
  62. * @var array
  63. */
  64. protected $arrNeurons = array();
  65. /**
  66. * @var array
  67. */
  68. protected $arrOutputs = array();
  69. /**
  70. * @var Network
  71. */
  72. protected $objNetwork = null;
  73. /**
  74. * @var Layer
  75. */
  76. protected $objNextLayer = null;
  77. /**
  78. * @var integer
  79. */
  80. protected $intNumberOfNeurons = null;
  81. /**#@-*/
  82. /**
  83. * @param Network $objNetwork
  84. * @param integer $intNumberOfNeurons
  85. * @param Layer $objNextLayer (Default: null)
  86. * @uses createNeurons()
  87. */
  88. public function __construct(Network $objNetwork, $intNumberOfNeurons, Layer $objNextLayer = null)
  89. {
  90. $this->objNetwork = $objNetwork;
  91. $this->objNextLayer = $objNextLayer;
  92. $this->createNeurons($intNumberOfNeurons);
  93. $this->intNumberOfNeurons = $intNumberOfNeurons;
  94. }
  95. /**
  96. * @param array &$arrInputs
  97. * @uses Neuron::setInputs()
  98. */
  99. public function setInputs(&$arrInputs)
  100. {
  101. foreach($this->arrNeurons as $objNeuron)
  102. $objNeuron->setInputs($arrInputs);
  103. }
  104. /**
  105. * @return array
  106. */
  107. public function getNeurons()
  108. {
  109. return $this->arrNeurons;
  110. }
  111. /**
  112. * @return integer
  113. */
  114. public function getNeuronsCount()
  115. {
  116. return $this->intNumberOfNeurons;
  117. }
  118. /**
  119. * @return array
  120. */
  121. public function getOutputs()
  122. {
  123. return $this->arrOutputs;
  124. }
  125. /**
  126. * @return array
  127. * @uses Maths::threshold()
  128. */
  129. public function getThresholdOutputs()
  130. {
  131. $arrReturnOutputs = array();
  132. foreach($this->arrOutputs as $intKey => $floatOutput)
  133. $arrReturnOutputs[$intKey] = Maths::threshold($floatOutput);
  134. return $arrReturnOutputs;
  135. }
  136. /**
  137. * @param integer $intNumberOfNeurons
  138. * @uses Neuron::__construct()
  139. */
  140. protected function createNeurons($intNumberOfNeurons)
  141. {
  142. for($intIndex = 0; $intIndex < $intNumberOfNeurons; $intIndex++)
  143. $this->arrNeurons[] = new Neuron($this->objNetwork);
  144. }
  145. /**
  146. * @uses Neuron::activate()
  147. * @uses Neuron::getOutput()
  148. * @uses Layer::setInputs()
  149. * @uses Layer::activate()
  150. */
  151. public function activate()
  152. {
  153. foreach($this->arrNeurons as $intKey => $objNeuron)
  154. {
  155. $objNeuron->activate();
  156. $arrOutputs[$intKey] = $objNeuron->getOutput();
  157. }
  158. if($this->objNextLayer !== null)
  159. {
  160. $this->objNextLayer->setInputs($arrOutputs);
  161. $this->objNextLayer->activate();
  162. }
  163. $this->arrOutputs = $arrOutputs;
  164. }
  165. /**
  166. * @uses Neuron::setDelta()
  167. * @uses Neuron::getWeight()
  168. * @uses Neuron::getDelta()
  169. * @uses Neuron::getOutput()
  170. * @uses getNeurons()
  171. */
  172. public function calculateHiddenDeltas()
  173. {
  174. $floatDelta = 0;
  175. $floatSum = 0;
  176. $arrNeuronsNextLayer = $this->objNextLayer->getNeurons();
  177. /* @var $objNeuron Neuron */
  178. foreach($this->arrNeurons as $intKeyNeuron => $objNeuron)
  179. {
  180. /* @var $objNeuronNextLayer Neuron */
  181. foreach($arrNeuronsNextLayer as $objNeuronNextLayer)
  182. $floatSum += $objNeuronNextLayer->getWeight($intKeyNeuron) * $objNeuronNextLayer->getDelta() * $this->objNetwork->floatMomentum;
  183. $floatOutput = $objNeuron->getOutput();
  184. $floatDelta = $floatOutput * (1 - $floatOutput) * $floatSum;
  185. $objNeuron->setDelta($floatDelta);
  186. }
  187. }
  188. /**
  189. * @param array $arrDesiredOutputs
  190. * @uses Neuron::setDelta()
  191. * @uses Neuron::getOutput()
  192. */
  193. public function calculateOutputDeltas($arrDesiredOutputs)
  194. {
  195. foreach($this->arrNeurons as $intKeyNeuron => $objNeuron)
  196. {
  197. $floatOutput = $objNeuron->getOutput();
  198. $floatDelta = $floatOutput * ($arrDesiredOutputs[$intKeyNeuron] - $floatOutput) * (1 - $floatOutput);
  199. $objNeuron->setDelta($floatDelta);
  200. }
  201. }
  202. /**
  203. * @uses Neuron::adjustWeights()
  204. */
  205. public function adjustWeights()
  206. {
  207. foreach($this->arrNeurons as $objNeuron)
  208. $objNeuron->adjustWeights();
  209. }
  210. }