From 858b54115f9aa6282a732f5b846109f4da0c3779 Mon Sep 17 00:00:00 2001 From: LonlyDWolf Date: Sun, 18 Oct 2026 12:19:03 +0300 Subject: [PATCH] Include the completed C++ and C# closeouts in XOR --- .github/workflows/python-reference.yml | 37 ++++++++++++++- README.md | 63 ++++++++++++++++++-------- cpp | 2 +- csharp | 2 +- docs/RETROSPECTIVE.md | 26 ++++++----- 5 files changed, 98 insertions(+), 32 deletions(-) diff --git a/.github/workflows/python-reference.yml b/.github/workflows/python-reference.yml index eae7b42..a044a7c 100644 --- a/.github/workflows/python-reference.yml +++ b/.github/workflows/python-reference.yml @@ -1,4 +1,4 @@ -name: Python reference +name: Neural network checks on: push: @@ -26,3 +26,38 @@ jobs: run: python -m unittest discover -s python/tests -v - name: Run the seeded example run: python python/examples/xor_demo.py --seed 0 + + cpp: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Build C++ example and tests + run: | + mkdir -p cpp/build + c++ -std=c++17 -Wall -Wextra -pedantic -I cpp/NN cpp/NN/Network.cpp cpp/NN/Neuron.cpp cpp/examples/xor_demo.cpp -o cpp/build/xor_demo + c++ -std=c++17 -Wall -Wextra -pedantic -I cpp/NN cpp/NN/Network.cpp cpp/NN/Neuron.cpp cpp/tests/network_tests.cpp -o cpp/build/network_tests + - name: Check errors, dimensions, and convergence + run: ./cpp/build/network_tests + - name: Run the seeded example + run: ./cpp/build/xor_demo --seed 0 + + csharp: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - uses: actions/setup-dotnet@v6 + with: + dotnet-version: '10.0.x' + - name: Build C# example + run: dotnet build csharp/NN.csproj --configuration Release + - name: Check gradients, momentum, convergence, and data handling + run: dotnet run --project csharp/NN.csproj --configuration Release --no-build -- --test + - name: Run the seeded example + run: dotnet run --project csharp/NN.csproj --configuration Release --no-build diff --git a/README.md b/README.md index db0ba3d..dfb77bd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A completed learning project implementing a small neural network directly in Python, C++, and C#, without an ML framework. The exercise explores forward propagation, backpropagation, and momentum updates on the four-case XOR problem. -The Python implementation is the reproducible reference for this closeout. C++ and C# remain historical ports with different initialization and training settings; this repository does not establish identical results across languages. There is no active feature roadmap. +Each implementation now includes a runnable seeded example and focused regression checks. The languages retain different initialization and training settings; this repository does not establish identical numerical results across them. There is no active feature roadmap. Read the [technical retrospective](docs/RETROSPECTIVE.md) for the scope, checks, and limitations. @@ -22,36 +22,63 @@ git submodule sync --recursive git submodule update --init --recursive ``` -## Run the Python reference +All commands below run from this parent repository's root. Install only the toolchain for the implementation you want to explore. None of the examples requires a model download or an external ML package. -Use Python 3.12 or later; the example and tests use only the standard library. From this repository's root: +## Python + +Use Python 3.12 or later: ```sh python3 python/examples/xor_demo.py --seed 0 python3 -m unittest discover -s python/tests -v ``` -On Windows, use `py -3` in place of `python3` if that is how Python is installed. +On Windows, use `py -3` in place of `python3` if that is how Python is installed. The example trains on the checked-in 4,000-example sequence and leaves historical output files unchanged. Tests cover numerical gradients, convergence for seeds 0–4, and portable paths. See the [Python README](python/README.md) for the original trainer's file-output behavior. + +## C++ + +Use a C++17 compiler such as Clang or GCC. These commands use a POSIX shell: + +```sh +mkdir -p cpp/build +c++ -std=c++17 -Wall -Wextra -pedantic -I cpp/NN cpp/NN/Network.cpp cpp/NN/Neuron.cpp cpp/examples/xor_demo.cpp -o cpp/build/xor_demo +c++ -std=c++17 -Wall -Wextra -pedantic -I cpp/NN cpp/NN/Network.cpp cpp/NN/Neuron.cpp cpp/tests/network_tests.cpp -o cpp/build/network_tests +./cpp/build/xor_demo --seed 0 +./cpp/build/network_tests +``` + +The example trains on 4,000 samples by repeating the four XOR cases and writes no files. Tests cover initial and multi-output error statistics, dimension validation, and convergence for seeds 0–4. The standalone example and tests are separate from the historical Visual Studio project. See the [C++ README](cpp/README.md). + +## C# + +Use a .NET 10 SDK: + +```sh +dotnet build csharp/NN.csproj --configuration Release +dotnet run --project csharp/NN.csproj --configuration Release --no-build +dotnet run --project csharp/NN.csproj --configuration Release --no-build -- --test +``` + +The bundled fixture is copied beside the executable. By default, seed 42 initializes weights and 10,000 epochs traverse the four cases, for 40,000 updates. The example writes no report file unless requested. Tests cover convergence for seeds 42, 7 and 123, numerical gradients and momentum, multi-output error, and data/path validation. See the [C# README](csharp/README.md) for arguments and the text-data format. -The example reads the checked-in 4,000-example training sequence, seeds weight initialization, and prints predictions for `00`, `01`, `10`, and `11` after training. Classification uses a threshold of `0.5`. It does not rewrite the historical training-output file. Repeating a seed makes the experiment reproducible within the same runtime; exact floating-point values can vary across runtimes. +## Shared concepts and different settings -The tests check XOR classification at fixed seeds, compare a backpropagation update with finite-difference gradients, and exercise file paths from a different working directory. The GitHub Actions workflow runs the reference checks on Linux and Windows. These checks cover the Python implementation, not numerical equivalence with the other ports. +All three examples use a `2 → 4 → 1` topology, `tanh` activation, and a fixed `+1` bias at each non-input neuron. Biases are not learned. All use learning rate `0.2` and evaluate the four XOR inputs with a classification threshold of `0.5`. -XOR contains only four possible input pairs. Demonstrating convergence on those pairs verifies this small exercise; it is not a benchmark of generalization to unseen tasks. +| Implementation | Initial weights | Momentum | Default training | +| --- | --- | --- | --- | +| Python | Uniform between -0.5 and 0.5 | 0.001 | 4,000 checked-in examples | +| C++ | C `rand` scaled to [0, 1] | 0.5 | 4,000 cyclic truth-table samples | +| C# | `Random` scaled to [-0.5, 0.5) | 0.001 | 40,000 cyclic truth-table samples | -## Repository structure +Seeds repeat initialization within the same runtime; random generators and floating-point results can differ across runtimes. The examples do not use a common initial-weight fixture or matched training budget, so their outputs are not a controlled language comparison. -- [`python/`](python): Python reference, deterministic example, and regression tests. See its [README](python/README.md) for the original trainer's file-output behavior. -- [`cpp/`](cpp): historical C++ implementation and Visual Studio project. The source compiled during review, but its full training run was not validated. -- [`csharp/`](csharp): historical C# implementation targeting .NET Core 3.1. Its expected input-data fixture is not included in the pinned tree; its run was not validated. +The parent CI checks the pinned implementations: Python on Linux/Windows, C++ on Linux/macOS, and C# on Linux. XOR contains only four possible input pairs; fitting those cases is a convergence check, not a benchmark of generalization to unseen tasks. -All implementations use `tanh` activation and a fixed `+1` bias at each non-input neuron. Biases are not learned. The Python reference has a `[2, 4, 1]` topology for the checked-in dataset. +## Scope and history -## Limits and historical differences +The closeout fixes the C++ uninitialized error accumulator and both ports' multi-output error aggregation. C# now includes its data fixture and targets .NET 10. The earlier implementations date to 2020; the 2026 closeout adds reproducible entry points and bounded checks while retaining their original activation and weight-update equations. -- C++ uses different momentum and random-initialization settings from Python and C#. No cross-language parity test is included. -- The C++ smoothed-error accumulator starts uninitialized. Its logged error is not a validated metric, even if the source compiles. -- The C++ and C# error calculations need attention before expanding to multiple output neurons. -- The parent repository collects earlier implementations whose pinned history dates to 2020. This closeout makes the Python exercise easier to reproduce; it does not turn the project into a general-purpose neural-network library. +This remains a small learning exercise, not a general-purpose neural-network library. C++ does not have a comprehensive numerical-gradient test, and none of the suites establishes correctness for arbitrary topologies, datasets, or seeds. The historical C++ Visual Studio entry point and training traces remain reference artifacts. -Changes to language code belong in the corresponding repository. This parent records the reviewed submodule revisions and provides the common entry point. +Changes to language code belong in the corresponding repository. This parent records the reviewed submodule revisions and provides the common entry point. Earlier pinned revisions predate these repairs; the child READMEs' historical-parent notes describe that earlier state. diff --git a/cpp b/cpp index 7733981..330b73b 160000 --- a/cpp +++ b/cpp @@ -1 +1 @@ -Subproject commit 773398184af2c7b5d8a0c9a87bc0255ed781b5a8 +Subproject commit 330b73b04f1a86ed35d61e9bf2e944a680e7c484 diff --git a/csharp b/csharp index 082febb..85f608e 160000 --- a/csharp +++ b/csharp @@ -1 +1 @@ -Subproject commit 082febb2127945523e9ba690ced06029cd5a34ed +Subproject commit 85f608eaf7cfc9eb6234f29b8d9337a271f3db97 diff --git a/docs/RETROSPECTIVE.md b/docs/RETROSPECTIVE.md index 529a35b..9d41bc0 100644 --- a/docs/RETROSPECTIVE.md +++ b/docs/RETROSPECTIVE.md @@ -1,29 +1,33 @@ # A reproducible neural-network fundamentals exercise -This project contains direct implementations of a small fully connected network in Python, C++, and C#. It preserves an earlier learning exercise and makes one reference implementation easy to inspect and run. It does not claim production readiness or measured improvements over an ML library. +This project contains direct implementations of a small fully connected network in Python, C++, and C#. It preserves an earlier learning exercise and makes each implementation easy to inspect and run. It does not claim production readiness or measured improvements over an ML library. ## What the implementation exposes -The neuron and network classes make the calculations visible: weighted sums, `tanh` activation, output and hidden-layer gradients, and updates with momentum. The checked-in Python dataset specifies two inputs, four hidden neurons, and one output. +The neuron and network classes make the calculations visible: weighted sums, `tanh` activation, output and hidden-layer gradients, and updates with momentum. The XOR examples use two inputs, four hidden neurons, and one output. -For the single-output reference, the gradient check uses the loss `L = 0.5 * (prediction - target)^2`. The derivative of `tanh` is `1 - output^2`. On the initial update, momentum contributes zero, so a weight's update should equal the negative numerical loss gradient multiplied by the learning rate. Comparing every weight against a finite-difference estimate checks the interaction of forward propagation and backpropagation without reimplementing the same analytic formula as the test oracle. +For Python's single-output gradient check, the loss is `L = 0.5 * (prediction - target)^2`. The derivative of `tanh` is `1 - output^2`. On the initial update, momentum contributes zero, so a weight's update should equal the negative numerical loss gradient multiplied by the learning rate. Comparing every weight against a finite-difference estimate checks forward propagation and backpropagation without using the same analytic formula as the test oracle. -The fixed `+1` neuron bias is a simplification of this implementation. There are no trainable bias parameters. The four XOR inputs are both the task and the evaluation cases, so successful classification is evidence of learning this truth table, not broader generalization. +C# extends this check to a two-output test network over two updates, summing half-squared errors and including momentum. C++ checks the corrected error statistic and convergence without claiming numerical-gradient coverage. -## Why the closeout focuses on Python +The fixed `+1` neuron bias is a simplification. There are no trainable bias parameters. The four XOR inputs are both the task and the evaluation cases, so successful classification is evidence of learning this truth table, not broader generalization. -The historical code had useful behavior behind an unreliable entry point. Windows-specific path concatenation prevented ordinary Python startup on macOS. The parent clone command also contained Markdown link syntax, while SSH submodule URLs imposed an unnecessary authentication prerequisite for public source. +## What the closeout repairs -The closeout repairs those entry points, adds a seeded example that leaves tracked training logs alone, and adds regression checks for convergence, numerical gradients, and paths. The neural-network algorithm remains the historical implementation. The example and tests require no model download or third-party Python packages. +The historical code had useful behavior behind unreliable entry points. Windows-specific paths prevented ordinary Python startup on macOS. The parent clone command contained Markdown link syntax, while SSH submodule URLs imposed an authentication prerequisite for public source. The Python closeout repaired paths and added a seeded example that leaves tracked training logs alone. + +The subsequent C++ and C# closeouts make both ports runnable as well. C++ initializes numerical state, accumulates squared error across all outputs, validates dimensions, and provides a standalone seeded example. C# supplies the missing input fixture, moves from .NET Core 3.1 to .NET 10, uses one seeded random generator, repairs error aggregation, and validates data independently of locale. Report-file output is opt-in for the new examples. + +All three retain their original activation and weight-update equations. The default training schedules are explicit, and the examples require no external ML packages. The parent pins the merged closeout revisions and runs the implementations' checks in CI. ## Why the language ports are not called equivalent -The ports explore the same general algorithm, but they do not use a shared initial-weight fixture or the same momentum. They also have different execution prerequisites. Describing their results as identical would require controlled inputs, matched settings, and comparison within an explicit numerical tolerance. +The ports explore the same general algorithm, but they do not use a shared random generator, initial-weight fixture, momentum, or training budget. Python reads 4,000 checked-in examples; C++ repeats the truth table for 4,000 updates; C# repeats it for 40,000 updates. C++ retains momentum 0.5 and nonnegative initial weights, while Python and C# use momentum 0.001 and weights around zero. -C++ source compilation was checked in the October 2026 review; the full executable was not run. Its uninitialized smoothed-error accumulator remains a known limitation. C# was not executed, and its expected data fixture is absent. Those implementations remain historical reference material rather than newly validated examples. +Describing their numerical results as identical would require controlled inputs, matched settings, and comparison within an explicit tolerance. The closeout verifies each example on its own terms. It does not establish cross-language parity or turn the historical C++ Visual Studio project into the supported demo build. ## What the evidence supports -A reviewer can now run the Python exercise, inspect all four predictions, and run tests that would detect meaningful regressions in weight updates and classification. The test suite is intentionally small and tied to the exercise's claims. It does not establish that arbitrary network topologies, new datasets, or the other language ports behave correctly. +A reviewer can run all three examples, inspect their four predictions, and run focused tests. Python checks numerical gradients, convergence, and portable paths. C++ checks error initialization/aggregation, dimension handling, and convergence. C# checks gradients and momentum, convergence, error aggregation, and fixture/path handling. CI exercises the pinned code using the platforms documented in the README. -The broader lesson is that a compact fundamentals project benefits from explicit assumptions and reproducible results. Its value comes from making the algorithm and its limits understandable. Further feature development is not planned. +These suites do not establish correctness for arbitrary topologies, new datasets, or every seed. Their value is a compact, inspectable demonstration of the algorithm and its limits. Further feature development is not planned.