{"id":24282291,"url":"https://github.com/maartz/nn","last_synced_at":"2026-05-21T16:16:31.631Z","repository":{"id":272325605,"uuid":"916204119","full_name":"Maartz/NN","owner":"Maartz","description":"A Feed Forward Neural Network in Erlang","archived":false,"fork":false,"pushed_at":"2025-01-22T16:16:05.000Z","size":20,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-22T17:25:55.560Z","etag":null,"topics":["ai","erlang","feedforward-neural-network"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Maartz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-13T16:44:58.000Z","updated_at":"2025-01-22T16:16:10.000Z","dependencies_parsed_at":"2025-01-13T18:28:40.828Z","dependency_job_id":"d26346e1-7272-43a9-8b44-566e3ebd1bcf","html_url":"https://github.com/Maartz/NN","commit_stats":null,"previous_names":["maartz/nn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Maartz%2FNN","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Maartz%2FNN/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Maartz%2FNN/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Maartz%2FNN/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Maartz","download_url":"https://codeload.github.com/Maartz/NN/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242048372,"owners_count":20063400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","erlang","feedforward-neural-network"],"created_at":"2025-01-16T03:20:29.721Z","updated_at":"2026-05-21T16:16:31.625Z","avatar_url":"https://github.com/Maartz.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Feed-Forward Neural Network in Erlang/OTP\n\n[![Erlang/OTP](https://img.shields.io/badge/Erlang%2FOTP-26%2B-red.svg)](https://www.erlang.org/)\n[![Documentation](https://img.shields.io/badge/docs-ExDoc-blue.svg)](doc/readme.html)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\n\u003e A concurrent, message-passing based neural network implementation using Erlang's actor model\n\n## Overview\n\nThis project implements a **Feed-Forward Neural Network (FFNN)** using Erlang/OTP's actor model with a **perturbation-based learning algorithm**. Each component of the neural network (neurons, sensors, actuators, cortex, and scapes) is implemented as a separate concurrent process, allowing for **parallel execution** and **message-passing based communication**.\n\n### Key Features\n\n- 🧠 **Actor-based architecture** - Each neuron, sensor, and actuator runs as an independent process\n- ⚡ **Concurrent execution** - Natural parallelism through Erlang's process model\n- 🔄 **Perturbation learning** - Evolutionary-style weight optimization without backpropagation\n- 📊 **Built-in benchmarking** - Statistical analysis across multiple training runs\n- 💾 **Persistent genotypes** - Save and load trained networks via Mnesia/ETS\n- 📚 **Complete documentation** - ExDoc-generated API documentation with examples\n\n## Architecture\n\n### System Components\n\nThe system consists of several key modules:\n\n1. `exoself.erl` - Orchestrates the network creation, lifecycle, and training loop\n2. `genotype.erl` - Generates and persists network structure and weights\n3. `morphology.erl` - Defines problem-specific sensor/actuator configurations\n4. `scape.erl` - Implements environment simulations (e.g., XOR problem)\n5. `sensor.erl` - Handles input generation from scapes\n6. `neuron.erl` - Implements neuron behavior with weight management\n7. `actuator.erl` - Manages output processing and fitness collection\n8. `cortex.erl` - Orchestrates synchronous network operation cycles\n9. `trainer.erl` - Manages training sessions with fitness tracking\n10. `benchmarker.erl` - Runs statistical benchmarks across multiple training runs\n11. `platform.erl` - Gen_server for managing shared scapes and modules\n12. `records.hrl` - Defines data structures\n\n### Process Hierarchy\n\n```mermaid\ngraph TD\n    P[Platform] -.-\u003e|Manages| PSC[Public Scapes]\n    P -.-\u003e|Mnesia| DB[(Database)]\n    B[Benchmarker] --\u003e|Spawns| T[Trainer]\n    T --\u003e|Spawns| E[ExoSelf]\n    E --\u003e|Creates| SC[Private Scapes]\n    E --\u003e|Creates| C[Cortex]\n    E --\u003e|Creates| S[Sensors]\n    E --\u003e|Creates| N[Neurons]\n    E --\u003e|Creates| A[Actuators]\n    C --\u003e|Sync| S\n    S --\u003e|Percepts| SC\n    S -.-\u003e|Can use| PSC\n    S --\u003e|Forward| N\n    N --\u003e|Forward| A\n    A --\u003e|Actions| SC\n    A -.-\u003e|Can use| PSC\n    SC --\u003e|Fitness| A\n    PSC -.-\u003e|Fitness| A\n    A --\u003e|Sync| C\n    C --\u003e|Results| E\n    E --\u003e|Best Fitness| T\n    T --\u003e|Statistics| B\n```\n\n### Message Flow (One Evaluation Cycle)\n\n```mermaid\nsequenceDiagram\n    participant E as ExoSelf\n    participant C as Cortex\n    participant S as Sensor\n    participant SC as Scape\n    participant N as Neuron\n    participant A as Actuator\n\n    E-\u003e\u003eC: Send PIDs \u0026 IDs\n    C-\u003e\u003eS: {sync}\n    S-\u003e\u003eSC: {sense}\n    SC-\u003e\u003eS: {percept, Input}\n    S-\u003e\u003eN: {forward, Input}\n    N-\u003e\u003eN: Compute: tanh(dot(Input, Weights))\n    N-\u003e\u003eA: {forward, Output}\n    A-\u003e\u003eSC: {action, Output}\n    SC-\u003e\u003eA: {Fitness, HaltFlag}\n    A-\u003e\u003eC: {sync, Fitness, HaltFlag}\n    C-\u003e\u003eE: {evaluation_completed, Fitness, Cycles, Time}\n```\n\n### Key Data Structures\n\n#### Core Neural Network Records\n\n```erlang\n-record(sensor, {id, cortex_id, name, scape, vector_length, fanout_ids}).\n-record(actuator, {id, cortex_id, name, scape, vector_length, fanin_ids}).\n-record(neuron, {id, cortex_id, activation_function, input_ids, output_ids}).\n-record(cortex, {id, sensor_ids, actuator_ids, neuron_ids}).\n```\n\n**Note:** Sensors and actuators include a `scape` field which specifies the environment (e.g., `{private, xor_sim}` for a private XOR simulator).\n\n#### Evolutionary Algorithm Records (Future Support)\n\n```erlang\n-record(agent, {id, generation, population_id, specie_id, cortex_id, fingerprint,\n                constraint, evolution_history=[], fitness, innovation_factor=0, pattern=[]}).\n-record(specie, {id, population_id, fingerprint, constraint, agent_ids=[], dead_pool=[],\n                 champion_ids=[], fitness, innovation_factor=0}).\n-record(population, {id, platform_id, specie_ids=[], morphologies=[], innovation_factor}).\n-record(constraint, {morphology=xor_mimic, neural_afs=[tanh, cos, gauss, abs]}).\n```\n\nThese records support evolutionary/genetic algorithm capabilities:\n- **agent**: Individual neural network in a population with evolutionary history\n- **specie**: Group of similar agents sharing a fingerprint\n- **population**: Collection of species being evolved\n- **constraint**: Evolutionary constraints (morphology type, available activation functions)\n\n## Neural Network Mathematics\n\n### Dot Product\n\nThe dot product is used in neurons to compute the weighted sum of inputs:\n\n```erlang\ndot([I | Input], [W | Weights], Acc) -\u003e\n    dot(Input, Weights, I * W + Acc);\ndot([], [], Acc) -\u003e\n    Acc.\n```\n\nThis operation:\n\n- Multiplies each input by its corresponding weight\n- Sums all products\n- Determines neuron activation strength\n\n### Activation Function (tanh)\n\nThe network uses hyperbolic tangent (tanh) as its activation function:\n\n```erlang\ntanh(Val) -\u003e\n    math:tanh(Val).\n```\n\nKey properties:\n\n- Bounds output between -1 and 1\n- Non-linear transformation\n- Smooth gradient\n- Zero-centered output\n\nBenefits for neural networks:\n\n1. Prevents numerical overflow\n2. Allows for negative outputs\n3. Strong gradients near zero\n4. Smooth activation curves\n\n## Detailed Component Descriptions\n\n### ExoSelf (exoself.erl)\n\nThe ExoSelf process is the top-level orchestrator responsible for:\n\n1. **Genotype Loading**: Reads network configuration from ETS table files\n2. **Process Spawning**: Creates all cerebral units (cortex, sensors, neurons, actuators) and scapes\n3. **Connection Mapping**: Establishes IdsNPIds ETS table mapping element IDs to PIDs\n4. **Process Linking**: Sends initialization messages with connection information\n5. **Training Loop**: Implements perturbation-based learning:\n   - Perturbs random subset of neuron weights (probability = 1/sqrt(total_neurons))\n   - Backs up weights when fitness improves\n   - Restores weights when fitness degrades\n   - Terminates after MAX_ATTEMPTS (50) consecutive failures\n6. **Genotype Persistence**: Saves trained weights back to genotype file\n7. **Result Reporting**: Communicates final fitness/statistics to trainer process\n\n### Cortex (cortex.erl)\n\nThe Cortex orchestrates the synchronous operation of the neural network:\n\n- **Cycle Management**: Triggers sensors to begin each evaluation cycle\n- **Synchronization**: Collects sync messages from all actuators before starting next cycle\n- **Fitness Accumulation**: Aggregates fitness scores from actuators\n- **Evaluation Completion**: Detects end of evaluation (via EndFlag) and reports to ExoSelf\n- **State Transitions**: Switches between active (running) and inactive (waiting for reactivation) states\n- **Timing**: Tracks cycle count and execution time for performance metrics\n\n### Scapes (scape.erl)\n\nScapes implement the problem environments:\n\n- **XOR Simulator** (`xor_sim/1`): Provides XOR training data\n  - Cycles through 4 XOR cases: `[{[-1,-1],[-1]}, {[1,-1],[1]}, {[-1,1],[1]}, {[1,1],[-1]}]`\n  - Calculates Mean Squared Error (MSE) between network output and target\n  - Returns fitness as `1/(MSE + 0.00001)` after completing all 4 cases\n- **Protocol**: Responds to `{sense}` messages with percepts, receives `{action, Output}` messages\n- **Scope**: Can be private (spawned per network) or public (shared across networks)\n\n### Sensors (sensor.erl)\n\nSensors generate or retrieve input data:\n\n- **Scape Communication**: Sends `{sense}` message and receives `{percept, Vector}` response\n- **Data Forwarding**: Broadcasts sensory vector to all connected neurons (fanout)\n- **Sensor Types**:\n  - `xor_GetInput/2`: Retrieves input from XOR scape\n  - `rng/1`: Generates random numbers (for testing)\n- **Synchronization**: Triggered by cortex `{sync}` messages\n\n### Neurons (neuron.erl)\n\nNeurons perform the core neural computation:\n\n- **Weighted Sum**: Computes dot product of inputs and weights\n- **Activation**: Applies tanh activation function\n- **Weight Management**:\n  - `weight_backup`: Stores current weights in process dictionary\n  - `weight_restore`: Reverts to backed up weights\n  - `weight_perturb`: Randomly perturbs weights (probability = 1/sqrt(total_weights))\n- **Saturation**: Limits weight values to ±2π range\n- **Delta Multiplier**: Uses 2π for perturbation magnitude\n\n### Actuators (actuator.erl)\n\nActuators collect network outputs and interact with scapes:\n\n- **Output Collection**: Gathers outputs from all connected neurons (fanin)\n- **Scape Interaction**: Sends `{action, Output}` to scape, receives `{Fitness, HaltFlag}`\n- **Fitness Reporting**: Forwards fitness and halt flag to cortex\n- **Actuator Types**:\n  - `xor_SendOutput/2`: Sends output to XOR scape and gets fitness\n  - `pts/2`: Prints result to screen (for debugging)\n\n### Platform (platform.erl)\n\nThe Platform module is a gen_server that manages shared infrastructure:\n\n- **Scape Management**: Hosts public scapes that can be shared across multiple networks\n- **Module Supervision**: Starts and stops supervised modules\n- **Mnesia Integration**: Initializes and manages Mnesia database for evolutionary algorithms\n- **Database Schema**: Creates tables for populations, species, agents, and neural components\n- **Utility Functions**:\n  - `platform:sync()`: Recompiles all modules using `make:all([load])`\n  - `platform:create()`: Creates Mnesia schema and tables\n  - `platform:reset()`: Deletes and recreates Mnesia schema\n  - `platform:start()`: Starts the platform gen_server\n  - `platform:stop()`: Gracefully stops the platform\n\n**Note**: Currently configured with empty module and scape lists. Designed for future evolutionary algorithm support with persistent storage in Mnesia.\n\n## Documentation\n\n**Full API documentation** is available via ExDoc. To generate and view:\n\n```bash\n# Generate documentation\nrebar3 ex_doc\n\n# Open in browser (macOS)\nopen doc/readme.html\n\n# Or navigate to doc/readme.html in your browser\n```\n\nThe documentation includes:\n- **Module documentation** with detailed descriptions\n- **Function specifications** with types and examples\n- **Type definitions** for all records and custom types\n- **Interactive search** and navigation\n- **Mermaid diagrams** for architecture visualization\n\n## Getting Started\n\n### Prerequisites\n\n- **Erlang/OTP 26+** - Required for running the neural network\n- **Rebar3** - Build tool and dependency manager\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/yourusername/NN.git\ncd NN\n\n# Compile the project\nrebar3 compile\n\n# Generate documentation (optional)\nrebar3 ex_doc\n```\n\n### Quick Start\n\n```bash\n# Start an Erlang shell with the compiled project\nrebar3 shell\n```\n\n```erlang\n% Create a neural network for XOR problem with 3 hidden neurons\n1\u003e genotype:construct(my_network, xor_mimic, [3]).\n\n% Train the network (runs until convergence or max attempts)\n2\u003e exoself:map(my_network).\n\n% The trained network is automatically saved to 'my_network' file\n```\n\n## Usage\n\n### Creating a Network\n\nCreate a network genotype (blueprint) with custom topology:\n\n```erlang\n% Basic: One hidden layer with 3 neurons\ngenotype:construct(my_network, xor_mimic, [3]).\n\n% Advanced: Two hidden layers with 5 and 3 neurons\ngenotype:construct(deep_network, xor_mimic, [5, 3]).\n```\n\n**Parameters:**\n- `my_network` - Filename for saving the genotype\n- `xor_mimic` - Morphology (problem domain configuration)\n- `[3]` or `[5, 3]` - Hidden layer sizes (number of neurons per layer)\n\n### Training a Network\n\n#### Simple Training (Single Run)\n\n```erlang\n% Create and train in one go\nexoself:map(my_network).\n```\n\n**What happens:**\n1. Loads genotype from file\n2. Spawns all neural processes (cortex, sensors, neurons, actuators, scapes)\n3. Runs perturbation-based training (up to 50 attempts)\n4. Saves improved weights back to genotype file\n5. Prints final fitness and statistics\n\n#### Advanced Training with Trainer\n\n```erlang\n% Basic training (5 attempts, infinite eval limit, infinite fitness target)\ntrainer:go(xor_mimic, [2]).\n\n% Training with custom parameters\nMaxAttempts = 10,\nEvalLimit = 1000,\nFitnessTarget = 0.9,\ntrainer:go(xor_mimic, [2], MaxAttempts, EvalLimit, FitnessTarget).\n```\n\nThe trainer will:\n- Create a new genotype for each training run\n- Run until MaxAttempts, EvalLimit, or FitnessTarget is reached\n- Save the best genotype to a file (e.g., `best_12345`)\n- Print the final results\n\n### Running Benchmarks\n\n```erlang\n% Run 100 training sessions and collect statistics\nbenchmarker:go(xor_mimic, [2]).\n\n% Custom number of runs\nbenchmarker:go(xor_mimic, [2], 50).\n\n% Full control over all parameters\nbenchmarker:go(xor_mimic, [2], MaxAttempts, EvalLimit, FitnessTarget, TotRuns).\n```\n\nBenchmark output includes:\n- Fitness: Max, Min, Avg, Std\n- Evaluations: Max, Min, Avg, Std\n- Cycles: Max, Min, Avg, Std\n- Time: Max, Min, Avg, Std\n\n## Development Commands\n\n### Building and Testing\n\n```bash\n# Compile the project\nrebar3 compile\n\n# Start interactive shell with compiled modules\nrebar3 shell\n\n# Clean build artifacts\nrebar3 clean\n\n# Generate documentation\nrebar3 ex_doc\n\n# Open documentation in browser (macOS)\nopen doc/readme.html\n```\n\n### Alternative: Manual Compilation (without rebar3)\n\nIf you prefer to work directly in the Erlang shell:\n\n```erlang\n% Start Erlang shell\nerl\n\n% Compile all modules\n1\u003e make:all([load]).\n\n% Or compile individual modules\n2\u003e c(genotype).\n3\u003e c(neuron).\n\n% Recompile changed modules (via platform)\n4\u003e platform:sync().\n```\n\n## Network Flow\n\n### 1. Initialization Phase\n- ExoSelf loads genotype from ETS file\n- Spawns scape processes for environment simulation\n- Spawns cortex, sensors, neurons, and actuators\n- Creates IdsNPIds mapping table (ID ↔ PID)\n- Links all processes by sending initialization messages with connection info\n\n### 2. Evaluation Cycle\n- **Cortex** sends `{sync}` to all sensors\n- **Sensors** request percepts from scapes, forward to neurons\n- **Neurons** compute weighted sum + tanh activation, forward to next layer\n- **Actuators** collect outputs, send to scape, receive fitness\n- **Actuators** send `{sync, Fitness, HaltFlag}` to cortex\n- **Cortex** accumulates fitness, checks for evaluation completion\n\n### 3. Learning Phase (Perturbation-Based)\n- **ExoSelf** receives evaluation results from cortex\n- If fitness improved:\n  - Send `{weight_backup}` to all neurons → saves current weights\n  - Reset attempt counter\n- If fitness degraded:\n  - Send `{weight_restore}` to perturbed neurons → revert to backup\n  - Increment attempt counter\n- Select random neuron subset (probability = 1/sqrt(N))\n- Send `{weight_perturb}` to selected neurons\n- Send `{reactivate}` to cortex to start next evaluation\n\n### 4. Termination\n- After MAX_ATTEMPTS (50) consecutive failures, training ends\n- ExoSelf collects final weights from neurons\n- Updates genotype and saves to file\n- Sends results to trainer process (if registered)\n- All processes receive `{terminate}` messages and shut down\n\n## Implementation Details\n\n### Concurrency Model\n\n- Each component (cortex, sensor, neuron, actuator, scape) runs as a separate Erlang process\n- Communication exclusively via asynchronous message passing\n- ExoSelf manages the phenotype lifecycle without OTP supervision trees\n- Processes use receive loops to handle messages\n- IdsNPIds ETS table provides O(1) ID-to-PID and PID-to-ID lookups\n\n### Data Persistence (Genotype/Phenotype Separation)\n\n- **Genotype**: Static network blueprint stored in ETS table files\n  - Contains structure (connectivity), initial weights, morphology\n  - Created by `genotype:construct/3`\n  - Updated with trained weights after successful training\n  - Loaded via `genotype:load_from_file/1`\n- **Phenotype**: Running network of concurrent processes\n  - Spawned from genotype by `exoself:map/1`\n  - Lives only during training/evaluation\n  - Neurons maintain current weights and backup weights in memory\n  - Terminated after training; weights persisted back to genotype\n\n### Process Spawning Pattern\n\nAll processes follow a common spawning pattern:\n```erlang\ngen(ExoSelf_PId, Node) -\u003e\n    spawn(Node, ?MODULE, prep, [ExoSelf_PId]).\n\nprep(ExoSelf_PId) -\u003e\n    receive\n        {ExoSelf_PId, InitData} -\u003e\n            loop(InitData)\n    end.\n```\n\nThis allows distributed deployment and clean initialization.\n\n### Weight Perturbation Algorithm\n\nNeurons use a random perturbation strategy:\n- Perturbation probability per weight: `MP = 1/sqrt(TotalWeights)`\n- Perturbation magnitude: `(rand:uniform() - 0.5) * 2π`\n- Weights saturated to range `[-2π, 2π]`\n- Same perturbation applied to bias weights\n\n### Morphology System\n\nMorphologies define problem-specific interfaces:\n- `morphology:Morphology(sensors)` returns sensor specifications\n- `morphology:Morphology(actuators)` returns actuator specifications\n- Each sensor/actuator specifies its scape (environment)\n- Currently implemented: `xor_mimic` for XOR problem\n\n### Scape Protocol\n\nScapes must implement:\n- `{ScapePId, sense}` → respond with `{ScapePId, percept, Vector}`\n- `{ActuatorPId, action, Output}` → respond with `{ScapePId, Fitness, HaltFlag}`\n- `{ExoSelfPId, terminate}` → cleanup and terminate\n\nHaltFlag = 1 signals evaluation complete; 0 means continue.\n\n## Resources\n\nFor learning more about Erlang/OTP and neural networks:\n\n- [Learn You Some Erlang](https://learnyousomeerlang.com/) - Excellent Erlang tutorial\n- [Erlang Documentation](https://www.erlang.org/docs) - Official documentation\n- [Making reliable distributed systems in the presence of software errors](https://erlang.org/download/armstrong_thesis_2003.pdf) - Joe Armstrong's thesis on Erlang\n\n## Example Sessions\n\n### Basic Network Creation and Training\n\n```erlang\nEshell V14.1.1\n\n% Compile all modules\n1\u003e make:all([load]).\n\n% Create a genotype for XOR problem with 2 hidden neurons\n2\u003e genotype:construct(test_nn_genotype, xor_mimic, [2]).\nok\n\n% Print the genotype structure\n3\u003e genotype:print(test_nn_genotype).\n{cortex,cortex,[{sensor,{-0.5,1.234}}],[{actuator,{-0.5,5.678}}],\n       [{neuron,{1,1}},{neuron,{1,2}},{neuron,{2,1}}]}\n{sensor,{-0.5,1.234},cortex,xor_GetInput,{private,xor_sim},2,\n       [{neuron,{1,1}},{neuron,{1,2}}]}\n...\n\n% Train the network\n4\u003e exoself:map(test_nn_genotype).\nExoSelf: Starting prep for test_nn_genotype\nCortex: Starting with 1 sensors, 3 neurons, 1 actuators\nActuator {actuator,{-0.5,5.678}}: Got fitness 12.5, endflag 1\nCortex:\u003c0.95.0\u003e finished training. Genotype has been backed up.\n Fitness:156.78\n TotEvaluations:8\n TotCycles:32\n TimeAcc:45678\n\u003c0.89.0\u003e\n```\n\n### Running a Benchmark\n\n```erlang\n% Run 10 training sessions to collect statistics\n5\u003e benchmarker:go(xor_mimic, [2], 10).\n\u003c0.120.0\u003e\n\nStarting benchmark run 10 of 10\nRun complete: Fitness=145.67 Evals=12\n...\nBenchmark results for: xor_mimic\nFitness::\n Max:245.89\n Min:98.45\n Avg:156.23\n Std:34.56\nEvals::\n Max:25\n Min:5\n Avg:12.3\n Std:5.2\n...\n```\n\n### Using the Trainer\n\n```erlang\n% Train with custom limits\n6\u003e trainer:go(xor_mimic, [2], 10, 100, 200.0).\n\u003c0.130.0\u003e\n\n% Trainer will create unique genotype files like:\n% - experimental_123456 (working copy)\n% - best_123456 (best solution found)\n```\n\n## Key Concepts\n\n### Genotype vs Phenotype\n- **Genotype** = Blueprint (ETS table file with structure and weights)\n- **Phenotype** = Running network (living processes doing computation)\n- Training happens in phenotype, results saved to genotype\n\n### Perturbation-Based Learning\nInstead of backpropagation, this system uses evolutionary-style learning:\n1. Randomly tweak some weights\n2. If performance improves → keep changes\n3. If performance degrades → revert changes\n4. Repeat until convergence or max attempts\n\n### Message-Passing Architecture\n- No shared memory between components\n- All communication via Erlang messages\n- Natural parallelism and fault isolation\n- Supports distributed deployment across nodes\n\n### Morphologies\nDefine the \"body\" of the neural network:\n- What sensors does it have? (inputs)\n- What actuators does it have? (outputs)\n- What scape (environment) does it interact with?\n\n## Extending the System\n\n### Adding a New Morphology\n\n1. Define sensors and actuators in `morphology.erl`:\n```erlang\nmy_problem(sensors) -\u003e\n    [#sensor{id={sensor,helpers:generate_id()},\n             name=my_GetInput,\n             scape={private,my_sim},\n             vector_length=4}];\nmy_problem(actuators) -\u003e\n    [#actuator{id={actuator,helpers:generate_id()},\n               name=my_SendOutput,\n               scape={private,my_sim},\n               vector_length=2}].\n```\n\n2. Implement sensor/actuator functions in their respective modules\n3. Implement scape in `scape.erl`:\n```erlang\nmy_sim(ExoSelf_PId) -\u003e\n    % Initialize environment\n    my_sim(ExoSelf_PId, InitialState).\n\nmy_sim(ExoSelf_PId, State) -\u003e\n    receive\n        {From, sense} -\u003e\n            From ! {self(), percept, InputVector},\n            my_sim(ExoSelf_PId, State);\n        {From, action, Output} -\u003e\n            Fitness = evaluate(Output, State),\n            HaltFlag = check_done(State),\n            From ! {self(), Fitness, HaltFlag},\n            my_sim(ExoSelf_PId, update_state(State));\n        {ExoSelf_PId, terminate} -\u003e\n            ok\n    end.\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaartz%2Fnn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaartz%2Fnn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaartz%2Fnn/lists"}