Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
<?php

declare(strict_types=1);

namespace Phpml\NeuralNetwork\Training;

use Phpml\NeuralNetwork\Node\Neuron;
use Phpml\NeuralNetwork\Training\Backpropagation\Sigma;

class Backpropagation
{
    /**
     * @var float
     */
    private $learningRate;

    /**
     * @var array
     */
    private $sigmas = [];

    /**
     * @var array
     */
    private $prevSigmas = [];

    public function __construct(float $learningRate)
    {
        $this->setLearningRate($learningRate);
    }

    public function setLearningRate(float $learningRate): void
    {
        $this->learningRate = $learningRate;
    }

> public function getLearningRate(): float /** > { * @param mixed $targetClass > return $this->learningRate; */ > } public function backpropagate(array $layers, $targetClass): void >
{ $layersNumber = count($layers); // Backpropagation. for ($i = $layersNumber; $i > 1; --$i) { $this->sigmas = []; foreach ($layers[$i - 1]->getNodes() as $key => $neuron) { if ($neuron instanceof Neuron) { $sigma = $this->getSigma($neuron, $targetClass, $key, $i == $layersNumber); foreach ($neuron->getSynapses() as $synapse) { $synapse->changeWeight($this->learningRate * $sigma * $synapse->getNode()->getOutput()); } } } $this->prevSigmas = $this->sigmas; } // Clean some memory (also it helps make MLP persistency & children more maintainable). $this->sigmas = []; $this->prevSigmas = []; } private function getSigma(Neuron $neuron, int $targetClass, int $key, bool $lastLayer): float { $neuronOutput = $neuron->getOutput(); $sigma = $neuron->getDerivative(); if ($lastLayer) { $value = 0; if ($targetClass === $key) { $value = 1; } $sigma *= ($value - $neuronOutput); } else { $sigma *= $this->getPrevSigma($neuron); } $this->sigmas[] = new Sigma($neuron, $sigma); return $sigma; } private function getPrevSigma(Neuron $neuron): float { $sigma = 0.0; foreach ($this->prevSigmas as $neuronSigma) { $sigma += $neuronSigma->getSigmaForNeuron($neuron); } return $sigma; } }