Perceptron in pure PHP

This entry page combines two separate runnable examples: a classic perceptron and a minimal MLP in PHP. Choose the implementation you need below and run it independently.

Classic Rosenblatt perceptron (standalone run)

A minimal implementation of the classic perceptron: weighted sum, threshold activation, and training with the Rosenblatt update rule.

 
<?php

namespace app\classes;

class 
Perceptron {
    
/** @var list<float> */
    
private array $weights;
    private 
float $bias;
    private 
float $learningRate;

    public function 
__construct(int $nFeatures, float $lr = 0.1) {
        
$this->learningRate = $lr;
        
$this->weights = array_fill(0, $nFeatures, 0.0);
        
$this->bias = 0.0;
    }

    
/**
     * @return list<float>
     */
    
public function getWeights(): array {
        return 
$this->weights;
    }

    public function 
getBias(): float {
        return 
$this->bias;
    }

    private function 
activation(float $z): int {
        return 
$z > 0 ? 1 : 0;
    }

    
/**
     * @param list<float> $x
     */
    
public function predict(array $x): int {
        
$z = $this->bias;

        foreach (
$x as $i => $value) {
            
$z += $this->weights[$i] * $value;
        }

        return 
$this->activation($z);
    }

    
/**
     * @param list<list<float>> $X
     * @param list<int> $y
     */
    
public function train(array $X, array $y, int $epochs = 100): void {
        for (
$e = 0; $e < $epochs; $e++) {
            foreach (
$X as $i => $sample) {
                
$prediction = $this->predict($sample);
                
$error = $y[$i] - $prediction;

                foreach (
$sample as $j => $value) {
                    
$this->weights[$j] += $this->learningRate * $error * $value;
                }

                
$this->bias += $this->learningRate * $error;
            }
        }
    }
}

One hidden layer and forward pass (standalone run)

A simplified one-hidden-layer MLP without bias terms: this example demonstrates only the forward pass on an input vector.

 
<?php

namespace app\classes;

class 
SimpleMLP {
    private array 
$W1;
    private array 
$W2;
    private 
float $lr;
    private array 
$hidden;

    public function 
__construct(int $inputSize, int $hiddenSize, float $lr = 0.01) {
        
$this->lr = $lr;
        
$this->hidden = [];
        
$this->W1 = [];

        for (
$i = 0; $i < $hiddenSize; $i++) {
            
$this->W1[$i] = array_fill(0, $inputSize, mt_rand() / mt_getrandmax());
        }

        
$this->W2 = array_fill(0, $hiddenSize, mt_rand() / mt_getrandmax());
    }

    public function 
getW1(): array {
        return 
$this->W1;
    }

    public function 
getW2(): array {
        return 
$this->W2;
    }

    public function 
getHidden(): array {
        return 
$this->hidden;
    }

    private function 
relu(float $z): float {
        return 
max(0, $z);
    }

    public function 
forward(array $x): float {
        
$hidden = [];

        foreach (
$this->W1 as $weights) {
            
$z = 0.0;

            foreach (
$weights as $i => $w) {
                
$z += $w * $x[$i];
            }

            
$hidden[] = $this->relu($z);
        }

        
$this->hidden = $hidden;

        
$output = 0.0;

        foreach (
$hidden as $i => $h) {
            
$output += $this->W2[$i] * $h;
        }

        return 
$output;
    }
}