Skip to main content

A simple package to work with AI

Project description

Logo of Tona AI

Make Artificial Intelligence easier

Static Badge License: MIT GitHub release

Summary

Introduction

This 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.

Note: This project is currently in Beta and still under active development. Many features are planned for future releases.

Installation

pip install tona-ai

Neural Network

Explanations

A neural network consists of neurons and synapses. The neurons are organized into different layers:

  • The input layer INPUT
    • 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.
  • The hidden layers HIDDEN
    • 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.
  • The output layer OUTPUT
    • This layer is mandatory and unique. The neurons in this layer receive the output values of the neural network when it is executed.

Neurons 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.

Available activation functions are:

  • Sigmoid function
  • ReLU (Rectified Linear Unit)
  • Hyperbolic tangent (TANH)

Synapses 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.

Tona AI allows you to create a custom neural network. You have access to each neuron and each synapse.

Usage

Create a neural network

To create a neural network, you can simply use the create() method of the NeuralNetwork class:

from tona_ai import ActivationFunction, NeuralNetwork

# Layered parameter is required, to define if the network is organized into strict layers
nn = NeuralNetwork(layered=False)
nn.create(
    input_size=2,
    output_size=1,
    layers=[
        (4, ActivationFunction.TANH),
    ],
    dense=True,
    output_activation_function=ActivationFunction.TANH,
)

Example code available here!

Or you can manually create the neurons and the connections between them:

from tona_ai import (
    ActivationFunction,
    Layer,
    LayerType,
    NeuralNetwork,
    Neuron,
    Synapse,
)

# Define the layers
input_layer = Layer(layer_type=LayerType.INPUT)
output_layer = Layer(layer_type=LayerType.OUTPUT)
# hidden layer can have multiple layers so you need to specify the index
hidden_layer = Layer(layer_type=LayerType.HIDDEN, layer_index=0)

# Define the neurons
neurons = [
    # Input Neurons do not have a bias or activation
    Neuron(id=0, layer=input_layer),  # x1
    Neuron(id=1, layer=input_layer),  # x2
    # Hidden Neurons
    Neuron(
        id=2,
        layer=hidden_layer,
        bias=0.0,
        activation_function=ActivationFunction.RELU,
    ),  # h1
    Neuron(
        id=3,
        layer=hidden_layer,
        bias=0.0,
        activation_function=ActivationFunction.RELU,
    ),  # h2
    # Output Neurons
    Neuron(
        id=4,
        layer=output_layer,
        bias=-2.0,
        activation_function=ActivationFunction.SIGMOID,
    ),  # o
]

# Define the synapses
synapses = [
    Synapse(in_neuron=neurons[0], out_neuron=neurons[2], weight=2.0),  # x1 -> h1
    Synapse(in_neuron=neurons[0], out_neuron=neurons[3], weight=-2.0),  # x1 -> h2
    Synapse(in_neuron=neurons[1], out_neuron=neurons[2], weight=-2.0),  # x2 -> h1
    Synapse(in_neuron=neurons[1], out_neuron=neurons[3], weight=2.0),  # x2 -> h2
    Synapse(in_neuron=neurons[2], out_neuron=neurons[4], weight=2.0),  # h1 -> o
    Synapse(in_neuron=neurons[3], out_neuron=neurons[4], weight=2.0),  # h2 -> o
]

# Add the synapses to the neurons
for synapse in synapses:
    synapse.out_neuron.inputs_synapses.append(synapse)

# Create the neural network
# Layered parameter is required, to define if the network is organized into strict layers
nn = NeuralNetwork(layered=True, neurons=neurons, synapses=synapses)

Example code available here!

Execute a neural network

To 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.

result_1 = nn.forward([0.0, 0.0])  # [0.11920292202211755]
result_2 = nn.forward([0.0, 1.0])  # [0.8807970779778823]
result_3 = nn.forward([1.0, 0.0])  # [0.8807970779778823]
result_4 = nn.forward([1.0, 1.0])  # [0.11920292202211755]

Example code available here!

Save a neural network

nn.save("my_network.pkl")

Example code available here!

Load a neural network

loaded_nn = NeuralNetwork.load("my_network.pkl")

Example code available here!

NEAT

DISCLAIMER

The algorithm implementation is still under development. Currently, only an EXTREMELY simplified version is available.

Explanations

Tona AI provides a very simplified version of the NEAT algorithm (see 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.

Usage

Setup an environment

The environment is essential as it defines how individuals are evaluated and how their efficiency is calculated.

To create an environment, simply create a class inheriting from the Environment class:

from tona_ai import Environment, Individual

# Create a simple XOR environment
class XorEnvironment(Environment):
    def __init__(self):
        super().__init__()

    # Implement the run method
    # This method is called when an individual is evaluated for each generation
    def run(self, individual: Individual) -> float:
        inputs = [[0, 0], [0, 1], [1, 0], [1, 1]]
        expected_outputs = [0, 1, 1, 0]

        fitness = 0
        for index, input in enumerate(inputs):
            output = individual.genome.forward(input)
            fitness += self.fitness_calculation(
                outputs=output, expected_output=expected_outputs[index]
            )

        fitness = fitness * fitness
        individual.fitness = fitness
        return fitness

    # Implement the fitness calculation method
    def fitness_calculation(self, outputs: list[float], **kwargs: dict) -> float:
        error = (outputs[0] - kwargs["expected_output"]) ** 2
        mse = error
        fitness = 1 / (1 + mse)
        return fitness

Example code available here!

Execute the NEAT algorithm

To 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.

# Create a simple genome with two inputs, one output, and one hidden layer of 4 neurons
genome = Genome()
genome.create(
    input_size=2,
    output_size=1,
    layers=[
        (4, ActivationFunction.TANH),
    ],
    dense=True,
    output_activation_function=ActivationFunction.TANH,
)

# Create a population of 100 individuals based on the genome
pop = Population()
pop.create(population_size=100, initial_genome=genome)

# Create the NEAT object
neat = NEAT(
    population=pop,
    environment=XorEnvironment(),
    mutation_rate=0.1,
    mutation_range=(-0.5, 0.5),
)

# Run the NEAT algorithm for 100000 epochs
neat.run(epochs=100000)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tona_ai-0.0.9.tar.gz (262.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tona_ai-0.0.9-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file tona_ai-0.0.9.tar.gz.

File metadata

  • Download URL: tona_ai-0.0.9.tar.gz
  • Upload date:
  • Size: 262.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for tona_ai-0.0.9.tar.gz
Algorithm Hash digest
SHA256 25c962ba2de4150ce6476c2c2cfa399b2ae1f96f64548dd7abf2384738d8d5fa
MD5 d5356caa6b7b28a7f51aa2c98ad514f8
BLAKE2b-256 720cf2dde29a0da90c8b1ac619390180120b74d1d6caed20c3d5260a1aad2956

See more details on using hashes here.

Provenance

The following attestation bundles were made for tona_ai-0.0.9.tar.gz:

Publisher: pypi-publish.yml on Tonaxis/tona-ai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tona_ai-0.0.9-py3-none-any.whl.

File metadata

  • Download URL: tona_ai-0.0.9-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for tona_ai-0.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 0f8bcd67ef1233cf6af2f8adf2531ef359ecb697fc6d80e30758b2f82e9cc4ab
MD5 07d02081cbdebe046e9014da0546958b
BLAKE2b-256 562d916e060978df3fa7ae6835eef332def35ae8061ca2321047d94d463a9634

See more details on using hashes here.

Provenance

The following attestation bundles were made for tona_ai-0.0.9-py3-none-any.whl:

Publisher: pypi-publish.yml on Tonaxis/tona-ai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page