diff --git a/src/Phpml/Exception/InvalidArgumentException.php b/src/Phpml/Exception/InvalidArgumentException.php index 798532d..d280296 100644 --- a/src/Phpml/Exception/InvalidArgumentException.php +++ b/src/Phpml/Exception/InvalidArgumentException.php @@ -73,4 +73,12 @@ class InvalidArgumentException extends \Exception { return new self(sprintf('Can\'t find %s language for StopWords', $language)); } + + /** + * @return InvalidArgumentException + */ + public static function invalidLayerNodeClass() + { + return new self('Layer node class must implement Node interface'); + } } diff --git a/src/Phpml/NeuralNetwork/Layer.php b/src/Phpml/NeuralNetwork/Layer.php new file mode 100644 index 0000000..6700164 --- /dev/null +++ b/src/Phpml/NeuralNetwork/Layer.php @@ -0,0 +1,49 @@ +nodes[] = new $nodeClass(); + } + } + + /** + * @param Node $node + */ + public function addNode(Node $node) + { + $this->nodes[] = $node; + } + + /** + * @return Node[] + */ + public function getNodes() + { + return $this->nodes; + } +} diff --git a/src/Phpml/NeuralNetwork/Node/Bias.php b/src/Phpml/NeuralNetwork/Node/Bias.php new file mode 100644 index 0000000..f19dcb6 --- /dev/null +++ b/src/Phpml/NeuralNetwork/Node/Bias.php @@ -0,0 +1,18 @@ +input = $input; + } + + /** + * @return float + */ + public function getOutput(): float + { + return $this->input; + } + + /** + * @param float $input + */ + public function setInput(float $input) + { + $this->input = $input; + } +} diff --git a/src/Phpml/NeuralNetwork/Node/Neuron.php b/src/Phpml/NeuralNetwork/Node/Neuron.php index 8d2fb4a..677831e 100644 --- a/src/Phpml/NeuralNetwork/Node/Neuron.php +++ b/src/Phpml/NeuralNetwork/Node/Neuron.php @@ -5,6 +5,7 @@ declare (strict_types = 1); namespace Phpml\NeuralNetwork\Node; use Phpml\NeuralNetwork\ActivationFunction; +use Phpml\NeuralNetwork\Node\Neuron\Synapse; use Phpml\NeuralNetwork\Node; class Neuron implements Node diff --git a/src/Phpml/NeuralNetwork/Node/Synapse.php b/src/Phpml/NeuralNetwork/Node/Neuron/Synapse.php similarity index 94% rename from src/Phpml/NeuralNetwork/Node/Synapse.php rename to src/Phpml/NeuralNetwork/Node/Neuron/Synapse.php index 923c4ff..3813d71 100644 --- a/src/Phpml/NeuralNetwork/Node/Synapse.php +++ b/src/Phpml/NeuralNetwork/Node/Neuron/Synapse.php @@ -2,11 +2,11 @@ declare (strict_types = 1); -namespace Phpml\NeuralNetwork\Node; +namespace Phpml\NeuralNetwork\Node\Neuron; use Phpml\NeuralNetwork\Node; -class Synapse implements Node +class Synapse { /** * @var float diff --git a/tests/Phpml/NeuralNetwork/LayerTest.php b/tests/Phpml/NeuralNetwork/LayerTest.php new file mode 100644 index 0000000..5706ab4 --- /dev/null +++ b/tests/Phpml/NeuralNetwork/LayerTest.php @@ -0,0 +1,56 @@ +assertEquals([], $layer->getNodes()); + } + + public function testLayerInitializationWithDefaultNodesType() + { + $layer = new Layer($number = 5); + + $this->assertCount($number, $layer->getNodes()); + foreach ($layer->getNodes() as $node) { + $this->assertInstanceOf(Neuron::class, $node); + } + } + + public function testLayerInitializationWithExplicitNodesType() + { + $layer = new Layer($number = 5, $class = Bias::class); + + $this->assertCount($number, $layer->getNodes()); + foreach ($layer->getNodes() as $node) { + $this->assertInstanceOf($class, $node); + } + } + + /** + * @expectedException \Phpml\Exception\InvalidArgumentException + */ + public function testThrowExceptionOnInvalidNodeClass() + { + new Layer(1, \stdClass::class); + } + + public function testAddNodesToLayer() + { + $layer = new Layer(); + $layer->addNode($node1 = new Neuron()); + $layer->addNode($node2 = new Neuron()); + + $this->assertEquals([$node1, $node2], $layer->getNodes()); + } +} diff --git a/tests/Phpml/NeuralNetwork/Node/BiasTest.php b/tests/Phpml/NeuralNetwork/Node/BiasTest.php new file mode 100644 index 0000000..c0ece3f --- /dev/null +++ b/tests/Phpml/NeuralNetwork/Node/BiasTest.php @@ -0,0 +1,17 @@ +assertEquals(1.0, $bias->getOutput()); + } +} diff --git a/tests/Phpml/NeuralNetwork/Node/InputTest.php b/tests/Phpml/NeuralNetwork/Node/InputTest.php new file mode 100644 index 0000000..b0abdcc --- /dev/null +++ b/tests/Phpml/NeuralNetwork/Node/InputTest.php @@ -0,0 +1,27 @@ +assertEquals(0.0, $input->getOutput()); + + $input = new Input($value = 9.6); + $this->assertEquals($value, $input->getOutput()); + } + + public function testSetInput() + { + $input = new Input(); + $input->setInput($value = 6.9); + + $this->assertEquals($value, $input->getOutput()); + } +} diff --git a/tests/Phpml/NeuralNetwork/Node/SynapseTest.php b/tests/Phpml/NeuralNetwork/Node/Neuron/SynapseTest.php similarity index 93% rename from tests/Phpml/NeuralNetwork/Node/SynapseTest.php rename to tests/Phpml/NeuralNetwork/Node/Neuron/SynapseTest.php index 41fc937..9ad733d 100644 --- a/tests/Phpml/NeuralNetwork/Node/SynapseTest.php +++ b/tests/Phpml/NeuralNetwork/Node/Neuron/SynapseTest.php @@ -2,10 +2,10 @@ declare (strict_types = 1); -namespace tests\Phpml\NeuralNetwork\Node; +namespace tests\Phpml\NeuralNetwork\Node\Neuron; +use Phpml\NeuralNetwork\Node\Neuron\Synapse; use Phpml\NeuralNetwork\Node\Neuron; -use Phpml\NeuralNetwork\Node\Synapse; class SynapseTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Phpml/NeuralNetwork/Node/NeuronTest.php b/tests/Phpml/NeuralNetwork/Node/NeuronTest.php index 526041b..c416ffd 100644 --- a/tests/Phpml/NeuralNetwork/Node/NeuronTest.php +++ b/tests/Phpml/NeuralNetwork/Node/NeuronTest.php @@ -6,7 +6,7 @@ namespace tests\Phpml\NeuralNetwork\Node; use Phpml\NeuralNetwork\ActivationFunction\BinaryStep; use Phpml\NeuralNetwork\Node\Neuron; -use Phpml\NeuralNetwork\Node\Synapse; +use Phpml\NeuralNetwork\Node\Neuron\Synapse; class NeuronTest extends \PHPUnit_Framework_TestCase { @@ -53,7 +53,7 @@ class NeuronTest extends \PHPUnit_Framework_TestCase /** * @param int $output * - * @return \PHPUnit_Framework_MockObject_MockObject + * @return Synapse|\PHPUnit_Framework_MockObject_MockObject */ private function getSynapseMock($output = 2) {