From 4e8104b136455771ecce507661ca0e8ebc2a0a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBarnecki?= Date: Tue, 17 Dec 2024 14:22:03 +0100 Subject: [PATCH 1/3] Neural networks perceptron classifier --- DIRECTORY.md | 9 + .../NeuralNetworkPerceptronClassifier.php | 192 ++++++++++++++++++ NeuralNetworks/PerceptronClassifier/README.md | 100 +++++++++ .../PerceptronClassifier/chart/dataset.png | Bin 0 -> 20630 bytes .../chart/linear-separated.png | Bin 0 -> 17021 bytes .../PerceptronClassifier/chart/sigmoid.png | Bin 0 -> 18089 bytes .../NeuralNetworkPerceptronClassifierTest.php | 23 +++ 7 files changed, 324 insertions(+) create mode 100644 NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifier.php create mode 100644 NeuralNetworks/PerceptronClassifier/README.md create mode 100644 NeuralNetworks/PerceptronClassifier/chart/dataset.png create mode 100644 NeuralNetworks/PerceptronClassifier/chart/linear-separated.png create mode 100644 NeuralNetworks/PerceptronClassifier/chart/sigmoid.png create mode 100644 tests/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifierTest.php diff --git a/DIRECTORY.md b/DIRECTORY.md index 3554092..bc7c615 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -97,6 +97,15 @@ * [Problem8](./Maths/ProjectEuler/Problem8.php) * [Problem9](./Maths/ProjectEuler/Problem9.php) +## NeuralNetworks + * PerceptronClassifier + * [NeuralNetworkPerceptronClassifier.php](NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifier.php) + * [README.md](NeuralNetworks/PerceptronClassifier/README.md) + * chart + * [dataset.png](NeuralNetworks/PerceptronClassifier/chart/dataset.png) + * [linear-separated.png](NeuralNetworks/PerceptronClassifier/chart/linear-separated.png) + * [sigmoid.png](NeuralNetworks/PerceptronClassifier/chart/sigmoid.png) + ## Searches * [Binarysearch](./Searches/BinarySearch.php) * [Exponentialsearch](./Searches/ExponentialSearch.php) diff --git a/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifier.php b/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifier.php new file mode 100644 index 0000000..6b94e54 --- /dev/null +++ b/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifier.php @@ -0,0 +1,192 @@ +initParams(count($X)); + + for ($i = 0; $i < $iterations; $i++) { + // Forward propagation + $A = $this->forwardPropagation($X, $W, $b); + + // Compute cost + $cost = $this->computeCost($A, $Y); + + // Backward propagation + [$dW, $db] = $this->backwardPropagation($A, $X, $Y); + + // Update parameters + [$W, $b] = $this->updateParams($W, $b, $dW, $db, $learningRate); + + if ($i % 100 == 0) { + echo "Iteration {$i} - Cost: {$cost}\n"; + } + } + + return [$W, $b]; + } + + /** + * @param array $X + * @param array $W + * @param float $b + * @return array + */ + public function predict(array $X, array $W, float $b): array + { + $A = $this->forwardPropagation($X, $W, $b); + return array_map(fn($a) => $a > 0.5 ? 1 : 0, $A); + } + + /** + * Stage 1. Prepare dataset + * @return array[] + */ + public function generateTrainingSet(): array + { + $m = 50; + + // Generate a 2 x m matrix with binary values (0 or 1) + $X = []; + for ($i = 0; $i < 2; $i++) { + for ($j = 0; $j < $m; $j++) { + $X[$i][$j] = rand(0, 1); + } + } + + // Compute Y: Logical AND condition (X[0] == 1 and X[1] == 0) + $Y = []; + for ($j = 0; $j < $m; $j++) { + $Y[$j] = ($X[0][$j] == 1 && $X[1][$j] == 0) ? 1 : 0; + } + + return [$X, $Y]; + } + + /** + * Stage 2. Initialize model parameters + * @param int $n Number of features + * @return array [$W, $b] Weight and bias arrays + */ + private function initParams(int $n): array + { + $W = []; + for ($i = 0; $i < $n; $i++) { + $W[$i] = mt_rand() / mt_getrandmax(); // Small random values + } + $b = 0.0; // Bias initialized to zero + return [$W, $b]; + } + + /** + * Sigmoid Activation Function + * @param float $z + * @return float + */ + private function sigmoid(float $z): float + { + return 1 / (1 + exp(-$z)); + } + + /** + * Stage 3. Forward Propagation + * @param array $X + * @param array $W + * @param float $b + * @return array + */ + private function forwardPropagation(array $X, array $W, float $b): array + { + $Z = []; + for ($j = 0; $j < count($X[0]); $j++) { + $sum = $b; + for ($i = 0; $i < count($W); $i++) { + $sum += $W[$i] * $X[$i][$j]; + } + $Z[$j] = $this->sigmoid($sum); + } + return $Z; + } + + /** + * Stage 4. Compute Cost Function (Binary Cross-Entropy Loss) + * @param array $A + * @param array $Y + * @return float + */ + private function computeCost(array $A, array $Y): float + { + $m = count($Y); + $cost = 0.0; + for ($i = 0; $i < $m; $i++) { + $cost += -($Y[$i] * log($A[$i]) + (1 - $Y[$i]) * log(1 - $A[$i])); + } + return $cost / $m; + } + + /** + * Stage 5. Backward Propagation + * @param array $A + * @param array $X + * @param array $Y + * @return array + */ + private function backwardPropagation(array $A, array $X, array $Y): array + { + $m = count($Y); + $dW = array_fill(0, count($X), 0.0); + $db = 0.0; + + for ($j = 0; $j < $m; $j++) { + $dZ = $A[$j] - $Y[$j]; + for ($i = 0; $i < count($X); $i++) { + $dW[$i] += $dZ * $X[$i][$j]; + } + $db += $dZ; + } + + // Average gradients + for ($i = 0; $i < count($dW); $i++) { + $dW[$i] /= $m; + } + $db /= $m; + + return [$dW, $db]; + } + + /** + * STage 6. Update Parameters + * @param array $W + * @param float $b + * @param array $dW + * @param float $db + * @param float $learningRate + * @return array + */ + private function updateParams(array $W, float $b, array $dW, float $db, float $learningRate): array + { + for ($i = 0; $i < count($W); $i++) { + $W[$i] -= $learningRate * $dW[$i]; + } + $b -= $learningRate * $db; + + return [$W, $b]; + } +} diff --git a/NeuralNetworks/PerceptronClassifier/README.md b/NeuralNetworks/PerceptronClassifier/README.md new file mode 100644 index 0000000..870c972 --- /dev/null +++ b/NeuralNetworks/PerceptronClassifier/README.md @@ -0,0 +1,100 @@ +## Maths behind the single Perceptron Neural Network with Activation Function + +This work is based on examples from course https://www.coursera.org/learn/machine-learning-calculus prepared by author Luis Serrano. + +Linear separation refers to data points in binary classification problems that can be separated by a linear decision boundary. +If the data points can be separated by a line, linear function, or flat hyperplane, they are said to be linearly separable. + +If separate points in an n-dimensional space exist, then it is said to be linearly separable + +$$w_1x_1 + w_2x_2 + w_nx_n + b = 0$$ + +For two-dimensional input data, if there is a line, whose equation is $$w_1x_1 + w_2x_2 + b = 0$$ + +that separates all samples of one class from the other class, then the corresponding observation can be derived from the equation of the separating line. +Such classification problems are called "linearly separable", i.e. separating by linear combination. + + + +The input layer contains two nodes $x_1$ and $x_2$. Weight vector $W = \begin{bmatrix} w_1 & w_2\end{bmatrix}$ and bias ($b$) are the parameters to be updated during the model training. + +$$z^{(i)} = w_1x_1^{(i)} + w_2x_2^{(i)} + b = Wx^{(i)} + b.\tag{1}$$ + +To be able to perform classification we need nonlinear approach. This can achieved with sigmoid activation function which roughly replace values with nearly 0 or nearly 1 for most cases and some values between for small range near 0. + +$$\hat{y} = \begin{cases} 1 & \mbox{if } a > 0.5 \\ 0 & \mbox{otherwise } \end{cases}\tag{10}$$ + +Sigmoid activation function is defined as + +$$a = \sigma\left(z\right) = \frac{1}{1+e^{-z}}.\tag{2}$$ + + + +Threshold value of $0.5$ can be used for predictions: $1$ (red) if $a > 0.5$ and $0$ (blue) otherwise. + +The single perceptron neural network with sigmoid activation function can be expressed as: + +\begin{align} +z^{(i)} &= W x^{(i)} + b,\\ +a^{(i)} &= \sigma\left(z^{(i)}\right).\\\tag{3} +\end{align} + + +With $m$ training examples organised in the columns of ($2 \times m$) matrix $X$, you can apply the activation function element-wise. So the model can be written as: + + +\begin {align} +Z &= W X + b,\\ +A &= \sigma\left(Z\right),\\\tag{4} +\end{align} + +When dealing with classification problems, the most commonly used cost function is the **log loss**, which is described by the following equation + +$$\mathcal{L}\left(W, b\right) = \frac{1}{m}\sum_{i=1}^{m} L\left(W, b\right) = \frac{1}{m}\sum_{i=1}^{m} \large\left(\small -y^{(i)}\log\left(a^{(i)}\right) - (1-y^{(i)})\log\left(1- a^{(i)}\right) \large \right) \small,\tag{5}$$ + +where $y^{(i)} \in \{0,1\}$ are the original labels and $a^{(i)}$ are the continuous output values of the forward propagation step (elements of array $A$). + + +We want to minimize the cost function during the training. To implement gradient descent, calculate partial derivatives using chain rule + + +\begin{align} +\frac{\partial \mathcal{L} }{ \partial w_1 } &= +\frac{1}{m}\sum_{i=1}^{m} \left(a^{(i)} - y^{(i)}\right)x_1^{(i)},\\ +\frac{\partial \mathcal{L} }{ \partial w_2 } &= +\frac{1}{m}\sum_{i=1}^{m} \left(a^{(i)} - y^{(i)}\right)x_2^{(i)},\tag{7}\\ +\frac{\partial \mathcal{L} }{ \partial b } &= +\frac{1}{m}\sum_{i=1}^{m} \left(a^{(i)} - y^{(i)}\right). +\end{align} + +Equations above can be rewritten in a matrix form + + +\begin{align} +\frac{\partial \mathcal{L} }{ \partial W } &= +\begin{bmatrix} \frac{\partial \mathcal{L} }{ \partial w_1 } & +\frac{\partial \mathcal{L} }{ \partial w_2 }\end{bmatrix} = \frac{1}{m}\left(A - Y\right)X^T,\\ +\frac{\partial \mathcal{L} }{ \partial b } &= \frac{1}{m}\left(A - Y\right)\mathbf{1}. +\tag{8} +\end{align} + +where $\left(A - Y\right)$ is an array of a shape ($1 \times m$), $X^T$ is an array of a shape ($m \times 2$) and $\mathbf{1}$ is just a ($m \times 1$) vector of ones. + +Then you can update the parameters: + +\begin{align} +W &= W - \alpha \frac{\partial \mathcal{L} }{ \partial W },\\ +b &= b - \alpha \frac{\partial \mathcal{L} }{ \partial b }, +\tag{9}\end{align} + +where $\alpha$ is the learning rate. Repeat the process in a loop until the cost function stops decreasing. + +in last step apply activation +$$\hat{y} = \begin{cases} 1 & \mbox{if } a > 0.5 \\ 0 & \mbox{otherwise } \end{cases}\tag{10}$$ + + +### Dataset + +As a dataset we will generate $m=50$ data points $(x_1, x_2)$, where $x_1, x_2 \in \{0,1\}$ and save them in the `NumPy` array `X` of a shape $(2 \times m)$. The labels ($0$: blue, $1$: red) will be calculated so that $y = 1$ if $x_1 = 1$ and $x_2 = 0$, in the rest of the cases $y=0$. The labels will be saved in the array `Y` of a shape $(1 \times m)$. + + diff --git a/NeuralNetworks/PerceptronClassifier/chart/dataset.png b/NeuralNetworks/PerceptronClassifier/chart/dataset.png new file mode 100644 index 0000000000000000000000000000000000000000..95a5042ae01a6328044a02567fe41f8144c947f4 GIT binary patch literal 20630 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 literal 0 HcmV?d00001 diff --git a/NeuralNetworks/PerceptronClassifier/chart/linear-separated.png b/NeuralNetworks/PerceptronClassifier/chart/linear-separated.png new file mode 100644 index 0000000000000000000000000000000000000000..061be4bc6949e893f4a9cedbab7c140181300a40 GIT binary patch literal 17021 zcma)kc|4Wh*Y+)yQc@|BP$8lCO2~ASiVm5l%$1Ni^N=YT5h4khr_3_XLqdjQ9x@-9 zj#-Z3nBR5#{)XrIz0dP`-#>ihoO|zk4{NV=t!rJocM5V+RFr2a5d@*a-n*lOAp0-~ zLY8&tAbgVi&@vQ$3EAF#V5@9tXzTFE+5nM#Wc$p_($>uQ@p*d#Ya3%r3qI}}+<#p; z|J2s@nT;?HkNLkI;I_0j;^F_6mkOO6es)j820^GFp+96_#gmK?H68@sd|S`T8i2fD{q0$GfRl6MM6Pt+R_;D;g%E!R&c`$DtHc9lWQwWz zv4yk+l=&WNsj69&(pF@54$!P37knPoOP=o^+uqcFeZ2(xIh3!FXr)u+!Dn};E4V1q7zNBw@|J2ZF=9vUfPfuUBpM9XJrY4X^{K?`^_*2K+^ZnJ4JhyG< zUNZq5mp?TrU$f>}IT2(lf>-j@D<0#~+AFGRZmF;cwhbH$#*6s6)921vtT@WKhCN=-|WKShnb3#CN4GGepH#&U;z@W+pxSp$YSSnG4^*n6af z3;Dl)|E86CarOu`wYp=WLxkf2#6!?z2*>y2XNR|c#n6&PWbaN_IKa9{o%t0s>!)Ku!Yap<|!#D+kNTzu3HX?CL|1Pdpqsy1<1Y1>6? z`vE%b)+g(~Ykc_4`>tc#UDpPa^y~blR{Jg0vDkObm`$^E?II<3EmI^df(#q_Dk`?= z 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 literal 0 HcmV?d00001 diff --git a/NeuralNetworks/PerceptronClassifier/chart/sigmoid.png b/NeuralNetworks/PerceptronClassifier/chart/sigmoid.png new file mode 100644 index 0000000000000000000000000000000000000000..985603111c7e6f9b98c242c4896af0a371327d99 GIT binary patch literal 18089 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 literal 0 HcmV?d00001 diff --git a/tests/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifierTest.php b/tests/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifierTest.php new file mode 100644 index 0000000..61eacc4 --- /dev/null +++ b/tests/NeuralNetworks/PerceptronClassifier/NeuralNetworkPerceptronClassifierTest.php @@ -0,0 +1,23 @@ +generateTrainingSet(); + // Train the model + [$W, $b] = $nnClassifier->trainModel($X, $Y, 1000, 0.1); + + // Make predictions + $predictions = $nnClassifier->predict([[0, 0, 1, 1], [0, 1, 1, 0]], $W, $b); + $this->assertEquals([0, 0, 0, 1], $predictions); + } +} From 23fe7b2d04b7a71a3e2a5b57fbbb66b9d8bd4472 Mon Sep 17 00:00:00 2001 From: Michal Zarnecki Date: Thu, 15 Aug 2024 22:51:20 +0200 Subject: [PATCH 2/3] Sieve of Eratosthenes algorithm --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index bc7c615..d60918a 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -96,6 +96,7 @@ * [Problem7](./Maths/ProjectEuler/Problem7.php) * [Problem8](./Maths/ProjectEuler/Problem8.php) * [Problem9](./Maths/ProjectEuler/Problem9.php) + * [Eratosthenessieve](./Maths/EratosthenesSieve.php) ## NeuralNetworks * PerceptronClassifier @@ -179,6 +180,7 @@ * [Eratosthenessievetest](./tests/Maths/EratosthenesSieveTest.php) * [Mathstest](./tests/Maths/MathsTest.php) * [Projecteulertest](./tests/Maths/ProjectEulerTest.php) + * [Eratosthenessievetest](./tests/Maths/EratosthenesSieveTest.php) * Searches * [Searchestest](./tests/Searches/SearchesTest.php) * Sorting From 0b5707445010a7f9609e8966d472450285221adb Mon Sep 17 00:00:00 2001 From: darwinz Date: Fri, 3 Jan 2025 20:26:52 +0000 Subject: [PATCH 3/3] updating DIRECTORY.md --- DIRECTORY.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index d60918a..bc7c615 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -96,7 +96,6 @@ * [Problem7](./Maths/ProjectEuler/Problem7.php) * [Problem8](./Maths/ProjectEuler/Problem8.php) * [Problem9](./Maths/ProjectEuler/Problem9.php) - * [Eratosthenessieve](./Maths/EratosthenesSieve.php) ## NeuralNetworks * PerceptronClassifier @@ -180,7 +179,6 @@ * [Eratosthenessievetest](./tests/Maths/EratosthenesSieveTest.php) * [Mathstest](./tests/Maths/MathsTest.php) * [Projecteulertest](./tests/Maths/ProjectEulerTest.php) - * [Eratosthenessievetest](./tests/Maths/EratosthenesSieveTest.php) * Searches * [Searchestest](./tests/Searches/SearchesTest.php) * Sorting