{"id":24126509,"url":"https://github.com/tonaxis/tona-ai","last_synced_at":"2025-09-18T18:31:45.920Z","repository":{"id":271868340,"uuid":"914808918","full_name":"Tonaxis/tona-ai","owner":"Tonaxis","description":"Python package to make Artificial Intelligence easier","archived":false,"fork":false,"pushed_at":"2025-01-10T11:59:52.000Z","size":142,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-10T12:28:55.522Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tonaxis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-10T10:54:06.000Z","updated_at":"2025-01-10T11:59:55.000Z","dependencies_parsed_at":"2025-01-10T12:42:08.324Z","dependency_job_id":null,"html_url":"https://github.com/Tonaxis/tona-ai","commit_stats":null,"previous_names":["tonaxis/tona-ai"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tonaxis%2Ftona-ai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tonaxis%2Ftona-ai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tonaxis%2Ftona-ai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tonaxis%2Ftona-ai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tonaxis","download_url":"https://codeload.github.com/Tonaxis/tona-ai/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233356138,"owners_count":18663827,"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":[],"created_at":"2025-01-11T16:33:19.672Z","updated_at":"2025-09-18T18:31:45.908Z","avatar_url":"https://github.com/Tonaxis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://github.com/tonaxis/tona-ai\"\u003e\n\u003c!-- \u003cimg media=\"(prefers-color-scheme: dark)\" src=\"./docs/images/tona_ai_logo_dark.svg\" alt=\"Logo of Tona AI\" width=\"450px\"\u003e --\u003e\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./docs/images/tona_ai_logo_dark.svg\" alt=\"Logo of Tona AI\" width=\"450px\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./docs/images/tona_ai_logo_light.svg\" alt=\"Logo of Tona AI\" width=\"450px\"\u003e\n  \u003cimg alt=\"Logo of Tona AI\" width=\"450px\" src=\"./docs/images/tona_ai_logo_light.svg\"\u003e\n\u003c/picture\u003e\n\u003c/a\u003e\n\n**Make Artificial Intelligence easier**\n\n![Static Badge](https://img.shields.io/badge/BETA-Status?label=Status\u0026color=yellow)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n[![GitHub release](https://img.shields.io/github/v/release/tonaxis/tona-ai)](https://github.com/tonaxis/tona-ai/releases)\n![](https://img.shields.io/badge/Python-3.12.7-3776AB?style=flat-circle\u0026logo=python\u0026logoColor=3776AB)\n\u003c/div\u003e\n\n## Summary\n- [Introduction](#introduction)\n- [Installation](#installation)\n- [Neural Network](#neural-network)\n    - [Explanations](#explanations)\n    - [Usage](#usage)\n        - [Create a neural network](#create-a-neural-network)\n        - [Execute a neural network](#execute-a-neural-network)\n        - [Save a neural network](#save-a-neural-network)\n        - [Load a neural network](#load-a-neural-network)\n- [NEAT (WIP)](#neat)\n    - [Disclaimer](#disclaimer)\n    - [Explanations](#explanations-1)\n    - [Usage](#usage-1)\n        - [Setup an Envirnment](#setup-an-environment)\n        - [Execute the NEAT algorithm](#execute-the-neat-algorithm)\n\n## Introduction\nThis package was created to facilitate the manipulation of neural networks, understand their functioning, create custom models, and train them. It is developed in Python entirely from scratch, without using external packages beyond Python.\n\u003e Note: This project is currently in Beta and still under active development. Many features are planned for future releases.\n\n## Installation\n```shell\npip install tona-ai\n```\n\n## Neural Network\n### Explanations\nA **neural network** consists of neurons and synapses. The neurons are organized into different layers:\n- The input layer ``INPUT``\n    - This layer is mandatory and unique as it is the neurons in this layer that receive the input values of the neural network when it is executed.\n- The hidden layers ``HIDDEN``\n    - These layers are optional and there can be several of them. They allow the neural network to perform more complex calculations and be more precise.\n- The output layer ``OUTPUT``\n    - This layer is mandatory and unique. The neurons in this layer receive the output values of the neural network when it is executed.\n\nNeurons have an activation function and a bias. The activation function calculates the neuron's output, and the bias is added to the sum of the inputs before passing through the activation function. This bias adjusts the output.\n\nAvailable activation functions are:\n- Sigmoid function\n- ReLU (Rectified Linear Unit)\n- Hyperbolic tangent (TANH)\n\nSynapses serve as connections between neurons. Each synapse has an input neuron and an output neuron. Synapses also have a weight that can be adjusted and will be multiplied by the input neuron's output before being sent to the output neuron.\n\nTona AI allows you to create a custom neural network. You have access to each **neuron** and each **synapse**.\n\n### Usage\n#### Create a neural network\nTo create a neural network, you can simply use the ``create()`` method of the **NeuralNetwork** class:\n```python\nfrom tona_ai import ActivationFunction, NeuralNetwork\n\n# Layered parameter is required, to define if the network is organized into strict layers\nnn = NeuralNetwork(layered=False)\nnn.create(\n    input_size=2,\n    output_size=1,\n    layers=[\n        (4, ActivationFunction.TANH),\n    ],\n    dense=True,\n    output_activation_function=ActivationFunction.TANH,\n)\n```\nExample code available [here](./examples/creation_neural_network.py)!\n\nOr you can manually create the neurons and the connections between them:\n```python\nfrom tona_ai import (\n    ActivationFunction,\n    Layer,\n    LayerType,\n    NeuralNetwork,\n    Neuron,\n    Synapse,\n)\n\n# Define the layers\ninput_layer = Layer(layer_type=LayerType.INPUT)\noutput_layer = Layer(layer_type=LayerType.OUTPUT)\n# hidden layer can have multiple layers so you need to specify the index\nhidden_layer = Layer(layer_type=LayerType.HIDDEN, layer_index=0)\n\n# Define the neurons\nneurons = [\n    # Input Neurons do not have a bias or activation\n    Neuron(id=0, layer=input_layer),  # x1\n    Neuron(id=1, layer=input_layer),  # x2\n    # Hidden Neurons\n    Neuron(\n        id=2,\n        layer=hidden_layer,\n        bias=0.0,\n        activation_function=ActivationFunction.RELU,\n    ),  # h1\n    Neuron(\n        id=3,\n        layer=hidden_layer,\n        bias=0.0,\n        activation_function=ActivationFunction.RELU,\n    ),  # h2\n    # Output Neurons\n    Neuron(\n        id=4,\n        layer=output_layer,\n        bias=-2.0,\n        activation_function=ActivationFunction.SIGMOID,\n    ),  # o\n]\n\n# Define the synapses\nsynapses = [\n    Synapse(in_neuron=neurons[0], out_neuron=neurons[2], weight=2.0),  # x1 -\u003e h1\n    Synapse(in_neuron=neurons[0], out_neuron=neurons[3], weight=-2.0),  # x1 -\u003e h2\n    Synapse(in_neuron=neurons[1], out_neuron=neurons[2], weight=-2.0),  # x2 -\u003e h1\n    Synapse(in_neuron=neurons[1], out_neuron=neurons[3], weight=2.0),  # x2 -\u003e h2\n    Synapse(in_neuron=neurons[2], out_neuron=neurons[4], weight=2.0),  # h1 -\u003e o\n    Synapse(in_neuron=neurons[3], out_neuron=neurons[4], weight=2.0),  # h2 -\u003e o\n]\n\n# Add the synapses to the neurons\nfor synapse in synapses:\n    synapse.out_neuron.inputs_synapses.append(synapse)\n\n# Create the neural network\n# Layered parameter is required, to define if the network is organized into strict layers\nnn = NeuralNetwork(layered=True, neurons=neurons, synapses=synapses)\n```\nExample code available [here](./examples/xor_neural_network.py)!\n\n#### Execute a neural network\nTo run your neural network, use the ``forward()`` method by passing the input values as a list of floats. It will return the output values as a list of floats.\n```python\nresult_1 = nn.forward([0.0, 0.0])  # [0.11920292202211755]\nresult_2 = nn.forward([0.0, 1.0])  # [0.8807970779778823]\nresult_3 = nn.forward([1.0, 0.0])  # [0.8807970779778823]\nresult_4 = nn.forward([1.0, 1.0])  # [0.11920292202211755]\n```\nExample code available [here](./examples/xor_neural_network.py)!\n\n#### Save a neural network\n```python\nnn.save(\"my_network.pkl\")\n```\nExample code available [here](./examples/creation_neural_network.py)!\n\n#### Load a neural network\n```python\nloaded_nn = NeuralNetwork.load(\"my_network.pkl\")\n```\nExample code available [here](./examples/creation_neural_network.py)!\n\n## NEAT\n### DISCLAIMER\n\u003e **The algorithm implementation is still under development. Currently, only an __EXTREMELY__ simplified version is available.**\n\n### Explanations\nTona AI provides a very simplified version of the NEAT algorithm ([see disclaimer](#disclaimer)), but it is functional. The principle is simple: you need to define an environment where NEAT will evaluate each individual in the population, retain the top 50%, and for each individual create a mutated copy.\n\n### Usage\n#### Setup an environment\nThe environment is essential as it defines how individuals are evaluated and how their efficiency is calculated.\n\nTo create an environment, simply create a class inheriting from the Environment class:\n```python\nfrom tona_ai import Environment, Individual\n\n# Create a simple XOR environment\nclass XorEnvironment(Environment):\n    def __init__(self):\n        super().__init__()\n\n    # Implement the run method\n    # This method is called when an individual is evaluated for each generation\n    def run(self, individual: Individual) -\u003e float:\n        inputs = [[0, 0], [0, 1], [1, 0], [1, 1]]\n        expected_outputs = [0, 1, 1, 0]\n\n        fitness = 0\n        for index, input in enumerate(inputs):\n            output = individual.genome.forward(input)\n            fitness += self.fitness_calculation(\n                outputs=output, expected_output=expected_outputs[index]\n            )\n\n        fitness = fitness * fitness\n        individual.fitness = fitness\n        return fitness\n\n    # Implement the fitness calculation method\n    def fitness_calculation(self, outputs: list[float], **kwargs: dict) -\u003e float:\n        error = (outputs[0] - kwargs[\"expected_output\"]) ** 2\n        mse = error\n        fitness = 1 / (1 + mse)\n        return fitness\n```\nExample code available [here](./examples/xor_neat.py)!\n\n#### Execute the NEAT algorithm\nTo run NEAT, you first need to create a population. Start by creating a base **Genome**, which is equivalent to a **Neural Network** with some changes. Then create a population with the ``create()`` method by passing the initial genome. Finally, create a **NEAT** object by passing the population, the environment, and defining the mutation rate and range.\n```python\n# Create a simple genome with two inputs, one output, and one hidden layer of 4 neurons\ngenome = Genome()\ngenome.create(\n    input_size=2,\n    output_size=1,\n    layers=[\n        (4, ActivationFunction.TANH),\n    ],\n    dense=True,\n    output_activation_function=ActivationFunction.TANH,\n)\n\n# Create a population of 100 individuals based on the genome\npop = Population()\npop.create(population_size=100, initial_genome=genome)\n\n# Create the NEAT object\nneat = NEAT(\n    population=pop,\n    environment=XorEnvironment(),\n    mutation_rate=0.1,\n    mutation_range=(-0.5, 0.5),\n)\n\n# Run the NEAT algorithm for 100000 epochs\nneat.run(epochs=100000)\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonaxis%2Ftona-ai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftonaxis%2Ftona-ai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonaxis%2Ftona-ai/lists"}