Git Product home page Git Product logo

yaricom / goneat Goto Github PK

View Code? Open in Web Editor NEW
74.0 7.0 19.0 3.57 MB

The GOLang implementation of NeuroEvolution of Augmented Topologies (NEAT) method to evolve and train Artificial Neural Networks without error back propagation

License: MIT License

Go 77.43% Makefile 0.37% Jupyter Notebook 22.20%
artificial-neural-networks neuroevolution neat augmenting-topologies unsupervised-learning unsupervised-machine-learning neural-network reinforcement-learning-algorithms reinforcement-learning

goneat's Introduction

goNEAT πŸ‡ΊπŸ‡¦ Made in Ukraine

banner

NeuroEvolution β€” evolving Artificial Neural Networks topology from the scratch

version GoDoc Go version license yaricom/goNEAT DOI

Branch Tests Coverage Linting Code Security
master CI codecov Lint CodeQL

Overview

This repository provides implementation of NeuroEvolution of Augmenting Topologies (NEAT) method written in Go language.

The NeuroEvolution (NE) is an artificial evolution of Neural Networks (NN) using genetic algorithms to find optimal NN parameters and network topology. NeuroEvolution of NN may assume a search for optimal weights of connections between NN nodes and search for the optimal topology of the resulting network graph. The NEAT method implemented in this work searches for optimal connection weights and the network graph topology for a given task (number of NN nodes per layer and their interconnections).

Minimum requirements

Requirement Notes
Go version Go1.18 or higher

Releases

Please do not depend on master as your production branch. Use releases instead.

Quick Start

You can evaluate the NEAT algorithm performance by running the following command:

cd $GOPATH/src/github.com/yaricom/goNEAT
go run executor.go -out ./out/xor -context ./data/xor.neat -genome ./data/xorstartgenes -experiment XOR

Or

make run-xor

The command above will run the XOR problem solver experiment and save the collected data samples. You can use saved experimental data for analysis using standard plotting libraries as in the figure below.

The XOR results plot

The figure was created using Matplotlib. You can find more details in the Jupyter notebook.

Documentation

You can find the algorithm performance evaluation and related documentation in the project's wiki

The goNEAT library saves results of the experiments using Numpy NPZ format, which allows analysis of collected experimental data samples using a variety of readily available Python libraries.

For your reference, we included Jupyter notebook with an example of the collected experimental data analysis, which can be used as a starter kit to analyze data samples acquired from your experiments.

Installation

Make sure you have at least GO 1.15.x installed onto your system and execute the following command:

go get github.com/yaricom/goNEAT

For new projects, consider using the v2 of the library with the following import:

import "github.com/yaricom/goNEAT/v3"

Essential Packages

genetics package

The genetics package provides the genetic part of the NEAT algorithm describing all the machinery related to genome mutations, mating, and speciation of the population of organisms.

It contains implementation of all important types related to the NEAT algorithm:

  • Gene type in this system specifies a "Connection Gene."
  • MIMOControlGene type is the Multiple-Input Multiple-Output (MIMO) control Gene which allows creation of modular genomes
  • Genome type is the primary source of genotype information used to create a phenotype.
  • Organism type is Genotypes (Genomes) and Phenotypes (Networks) combined with fitness information, i.e. the genotype and phenotype together.
  • Population type is a group of Organisms including their Species
  • Species type is a group of similar Organisms. Reproduction takes place mostly within a single species, so that compatible organisms can mate.

Additionally, it contains variety of utility functions to serialise/deserialize specified above types using two supported data formats:

  • plain text
  • YAML

The current implementation supports sequential and parallel execution of evolution epoch which controlled by related parameter in the NEAT context options.

math package

Package math defines standard mathematical primitives used by the NEAT algorithm as well as utility functions

network package

Package network provides data structures and utilities to describe Artificial Neural Network and network solvers.

The most important types are:

  • NNode type defines the node of the network and is a part of organism's genotype as well as phenotype
  • Link type is a connection from one node to another with an associated weight.
  • Network type is a collection of all nodes within an organism's phenotype, which effectively defines Neural Network topology.
  • Solver type defines network solver interface, which allows propagation of the activation waves through the underlying network graph.

The current implementation supports two types of network solvers:

  • FastModularNetworkSolver is the network solver implementation to be used for large neural networks simulation.
  • Standard Network Solver implemented by the Network type

The topology of the Neural Network represented by the Network fully supports the directed graph presentation as defined by Gonum graph package. This feature can be used for analysis of the network topology as well as encoding the graph in variety of popular graph presentation formats.

experiment package

Package experiment defines standard evolutionary epochs evaluators and experimental data samples collectors. It provides standardised approach to define experiments using the NEAT algorithm implementation.

The most important type here is:

You can find examples of GenerationEvaluator implementations at examples:

  • pole - single-, double-pole balancing experiments
  • xor - XOR solver experiment

The following code snippet demonstrates how to run experiments using different implementations of the GenerationEvaluator and the experiment.Execute:

// create experiment
expt := experiment.Experiment{
    Id:       0,
    Trials:   make(experiment.Trials, neatOptions.NumRuns),
    RandSeed: seed,
}
var generationEvaluator experiment.GenerationEvaluator
switch *experimentName {
case "XOR":
    expt.MaxFitnessScore = 16.0 // as given by fitness function definition
    generationEvaluator = xor.NewXORGenerationEvaluator(outDir)
case "cart_pole":
    expt.MaxFitnessScore = 1.0 // as given by fitness function definition
    generationEvaluator = pole.NewCartPoleGenerationEvaluator(outDir, true, 500000)
case "cart_2pole_markov":
    expt.MaxFitnessScore = 1.0 // as given by fitness function definition
    generationEvaluator = pole.NewCartDoublePoleGenerationEvaluator(outDir, true, pole.ContinuousAction)
case "cart_2pole_non-markov":
    generationEvaluator = pole.NewCartDoublePoleGenerationEvaluator(outDir, false, pole.ContinuousAction)
default:
    log.Fatalf("Unsupported experiment: %s", *experimentName)
}

// prepare to execute
errChan := make(chan error)
ctx, cancel := context.WithCancel(context.Background())

// run experiment in the separate GO routine
go func() {
    if err = expt.Execute(neat.NewContext(ctx, neatOptions), startGenome, generationEvaluator, nil); err != nil {
        errChan <- err
    } else {
        errChan <- nil
    }
}()

For more details, take a look at the experiment executor implementation provided with the goNEAT library.

neat package

Package neat is an entry point to the NEAT algorithm. It defines the NEAT execution context and configuration options.

You can find all available configuration options in the Options.

The configuration options can be saved either using plain text or the YAML format. We recommend using the YAML format for new projects because it allows for a more flexible setup and detailed documentation of the configuration parameters.

Take a look at the example configuration file to get a better understanding.

The NEAT context options can be read as follows:

// Loading YAML options
optFile, err := os.Open("./data/xor_test.neat.yml")
if err != nil {
	return err
}
options, err := neat.LoadYAMLOptions(optFile)

Or with plain-text format:

// Loading plain-text options
optFile, err := os.Open("./data/xor_test.neat")
if err != nil {
	return err
}
options, err := neat.LoadNeatOptions(optFile)

Phenotype Network Graph Visualization

The formats package provides support for various network graph serialization formats which can be used to visualize the graph with help of well-known tools. Currently, we have support for DOT and CytoscapeJS data formats.

The CytoscapeJS JSON format

Another important data format supported by the library is the CytoscapeJS JSON. The Network graph serialized into this format can be easily rendered using either Cytoscape App or the corresponding CytoscapeJS JavaScript library.

The following code snippet demonstrates how this can be done:

import (
"github.com/yaricom/goNEAT/v3/neat/network"
"github.com/yaricom/goNEAT/v3/neat/network/formats"
"bytes"
"fmt"
)

allNodes := []*network.NNode{
	network.NewNNode(1, network.InputNeuron), 
	network.NewNNode(2, network.InputNeuron), 
	network.NewNNode(3, network.BiasNeuron), 
	network.NewNNode(4, network.HiddenNeuron), 
	network.NewNNode(5, network.HiddenNeuron), 
	network.NewNNode(6, network.HiddenNeuron), 
	network.NewNNode(7, network.OutputNeuron), 
	network.NewNNode(8, network.OutputNeuron),
}

// HIDDEN 4
allNodes[3].connectFrom(allNodes[0], 15.0)
allNodes[3].connectFrom(allNodes[1], 10.0)
// HIDDEN 5
allNodes[4].connectFrom(allNodes[1], 5.0)
allNodes[4].connectFrom(allNodes[2], 1.0)
// HIDDEN 6
allNodes[5].connectFrom(allNodes[4], 17.0)
// OUTPUT 7
allNodes[6].connectFrom(allNodes[3], 7.0)
allNodes[6].connectFrom(allNodes[5], 4.5)
// OUTPUT 8
allNodes[7].connectFrom(allNodes[5], 13.0)

net := network.NewNetwork(allNodes[0:3], allNodes[6:8], allNodes, 0)

b := bytes.NewBufferString("")
err := formats.WriteCytoscapeJSON(b, net)
fmt.Println(b)

The produced output looks like the following:

{
  "elements": {
    "nodes": [
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#339FDC",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "1",
          "in_connections_count": 0,
          "neuron_type": "INPT",
          "node_type": "SENSOR",
          "out_connections_count": 1,
          "parent": "",
          "shape": "diamond"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#339FDC",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "2",
          "in_connections_count": 0,
          "neuron_type": "INPT",
          "node_type": "SENSOR",
          "out_connections_count": 2,
          "parent": "",
          "shape": "diamond"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#FFCC33",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "3",
          "in_connections_count": 0,
          "neuron_type": "BIAS",
          "node_type": "SENSOR",
          "out_connections_count": 1,
          "parent": "",
          "shape": "pentagon"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#009999",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "4",
          "in_connections_count": 2,
          "neuron_type": "HIDN",
          "node_type": "NEURON",
          "out_connections_count": 1,
          "parent": "",
          "shape": "hexagon"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#009999",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "5",
          "in_connections_count": 2,
          "neuron_type": "HIDN",
          "node_type": "NEURON",
          "out_connections_count": 1,
          "parent": "",
          "shape": "hexagon"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#009999",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "6",
          "in_connections_count": 1,
          "neuron_type": "HIDN",
          "node_type": "NEURON",
          "out_connections_count": 2,
          "parent": "",
          "shape": "hexagon"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#E7298A",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "7",
          "in_connections_count": 2,
          "neuron_type": "OUTP",
          "node_type": "NEURON",
          "out_connections_count": 0,
          "parent": "",
          "shape": "round-rectangle"
        },
        "selectable": true
      },
      {
        "data": {
          "activation_function": "SigmoidSteepenedActivation",
          "activation_value": 0,
          "background-color": "#E7298A",
          "border-color": "#CCCCCC",
          "control_node": false,
          "id": "8",
          "in_connections_count": 1,
          "neuron_type": "OUTP",
          "node_type": "NEURON",
          "out_connections_count": 0,
          "parent": "",
          "shape": "round-rectangle"
        },
        "selectable": true
      }
    ],
    "edges": [
      {
        "data": {
          "id": "1-4",
          "recurrent": false,
          "source": "1",
          "target": "4",
          "time_delayed": false,
          "weight": 15
        },
        "selectable": true
      },
      {
        "data": {
          "id": "2-4",
          "recurrent": false,
          "source": "2",
          "target": "4",
          "time_delayed": false,
          "weight": 10
        },
        "selectable": true
      },
      {
        "data": {
          "id": "2-5",
          "recurrent": false,
          "source": "2",
          "target": "5",
          "time_delayed": false,
          "weight": 5
        },
        "selectable": true
      },
      {
        "data": {
          "id": "3-5",
          "recurrent": false,
          "source": "3",
          "target": "5",
          "time_delayed": false,
          "weight": 1
        },
        "selectable": true
      },
      {
        "data": {
          "id": "5-6",
          "recurrent": false,
          "source": "5",
          "target": "6",
          "time_delayed": false,
          "weight": 17
        },
        "selectable": true
      },
      {
        "data": {
          "id": "4-7",
          "recurrent": false,
          "source": "4",
          "target": "7",
          "time_delayed": false,
          "weight": 7
        },
        "selectable": true
      },
      {
        "data": {
          "id": "6-7",
          "recurrent": false,
          "source": "6",
          "target": "7",
          "time_delayed": false,
          "weight": 4.5
        },
        "selectable": true
      },
      {
        "data": {
          "id": "6-8",
          "recurrent": false,
          "source": "6",
          "target": "8",
          "time_delayed": false,
          "weight": 13
        },
        "selectable": true
      }
    ]
  },
  "layout": {
    "name": "circle"
  },
  "style": [
    {
      "selector": "node",
      "style": {
        "background-color": "data(background-color)",
        "border-color": "data(border-color)",
        "border-width": 3,
        "label": "data(id)",
        "shape": "data(shape)"
      }
    },
    {
      "selector": "edge",
      "style": {
        "curve-style": "bezier",
        "line-color": "#CCCCCC",
        "target-arrow-color": "#CCCCCC",
        "target-arrow-shape": "triangle-backcurve",
        "width": 5
      }
    }
  ]
}

The above CYJS can be visualized as following with Cytoscape App.

Example Network

You can find more interesting visualizations at project's Wiki.

The DOT format

The Network can be serialized into popular GraphViz DOT format. The following code snippet demonstrates how this can be done:

import (
"github.com/yaricom/goNEAT/v3/neat/network"
"github.com/yaricom/goNEAT/v3/neat/network/formats"
"bytes"
"fmt"
)

allNodes := []*network.NNode{
	network.NewNNode(1, network.InputNeuron), 
	network.NewNNode(2, network.InputNeuron), 
	network.NewNNode(3, network.BiasNeuron), 
	network.NewNNode(4, network.HiddenNeuron), 
	network.NewNNode(5, network.HiddenNeuron), 
	network.NewNNode(6, network.HiddenNeuron), 
	network.NewNNode(7, network.OutputNeuron), 
	network.NewNNode(8, network.OutputNeuron),
}

// HIDDEN 4
allNodes[3].connectFrom(allNodes[0], 15.0)
allNodes[3].connectFrom(allNodes[1], 10.0)
// HIDDEN 5
allNodes[4].connectFrom(allNodes[1], 5.0)
allNodes[4].connectFrom(allNodes[2], 1.0)
// HIDDEN 6
allNodes[5].connectFrom(allNodes[4], 17.0)
// OUTPUT 7
allNodes[6].connectFrom(allNodes[3], 7.0)
allNodes[6].connectFrom(allNodes[5], 4.5)
// OUTPUT 8
allNodes[7].connectFrom(allNodes[5], 13.0)

net := network.NewNetwork(allNodes[0:3], allNodes[6:8], allNodes, 0)
net.Name = "TestNN"

b := bytes.NewBufferString("")
err := formats.WriteDOT(b, net)
fmt.Println(b)

The DOT output can be saved into the file for subsequent visualization by variety of tools listed at GraphViz Downloads.

Conclusion

The experiments described in this work confirm that introduced NEAT algorithm implementation can evolve new structures in the Artificial Neural Networks (XOR experiments) and can solve reinforcement learning tasks under conditions of incomplete knowledge (single-pole balancing and double-pole balancing).

We hope that you will find great applications in your research and work projects for the provided NEAT algorithm's implementation as well as utilities to run experiments while collecting relevant data samples.

Projects Using goNEAT library

  • Learning to play Asteroids in Golang with NEAT - interesting article about implementation of the intelligent agent to play classic Asteroid game using the NEAT algorithm.
  • NEAT with Novelty Search - implementation of the Novelty Search optimization algorithm for solution search in the deceptive environments.
  • Evolvable-Substrate HyperNEAT - is hypercube-based extension of the NEAT allowing to encode ANNs in the substrate with specific geometric topology and with significant number of neural units.

References

Citing

If you find our work useful, please consider citing:

@software{omelianenko_iaroslav_2023_8178789,
  author       = {Omelianenko, Iaroslav},
  title        = {{The GoLang implementation of NeuroEvolution of 
                   Augmented Topologies (NEAT) algorithm}},
  month        = jul,
  year         = 2023,
  note         = {If you use this software, please cite it as below.},
  publisher    = {Zenodo},
  version      = {v4.0.1},
  doi          = {10.5281/zenodo.8178789},
  url          = {https://doi.org/10.5281/zenodo.8178789}
}

This source code maintained and managed by Iaroslav Omelianenko

goneat's People

Contributors

yaricom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

goneat's Issues

Explore possibilities of saving genomes into directed graphs

Saving genome structure into directed graph provides ability to perform various kinds of analysis using graph theory. Also, it will allow us to create visualizations of genome structures. Similar to way we already done in the goNEAT_NS repository.

How to set up start genomes?

Hi,
The library looks really nice, but sadly it's missing a more idiot-proof type of documentation.
The executor and single pole example files were helpful in setting up something, but still contain tons of stuff
which are not so well documented.
Especially, setting up some custom own project is kinda hard. The simplicity of the linked blog post:
(https://maori.geek.nz/learning-to-play-asteroids-in-golang-with-neat-f44c3472938f) is quite nice to understand things better,
but it completely skips the part where you actually set up the project with start genome etc.
A really nice thing would be a minimal, complete example on how to setup everything for a random problem like the asteroids game.
so concrete question:

  • how do i create the proper start genome for my problem having x input variables and y output variables?
    i don't get the consturctor and docu is not existent. i saw randomGenome as private func, but it has no public c-tor

best regards

We need to extract Mutator and Reproducer.

Currently the mutation and reproduction logic encapsulated into Genome and Population. We need to extract it into Interfaces with concrete implementations to make code more clear.

Random genomes and add link mutations will link output nodes to other nodes

Upon inspecting a new random population with a larger set of max nodes I discovered that links using output nodes as input nodes to any non sensor, including other output nodes, may occur. This can also occur as far as I can tell with the add link mutations.

In most topologies, including NEAT, I think an output node should be an end state unless it is a recurrent connection back to another non-output node and never with itself. If my assumption is incorrect could you point me to a paper that defines the expected constraints on the node types? What I have read so far seems to imply constraints but doesn't really speak about it or explores the benifits of such constraints on an output node.

These type of connections are likely weeded out in normal experiments but I speculate their existence very much complicated and increases the problem domain to search and degrades the quality or consistency of the network actions. Especially in cases that I've noticed where many outputs will directly activate into another output node. In my model of asexual reproduction it is much less likely to lose an output link like this once they occur and the initial populations will randomly have many of them.

I think it is an issue this implementation provides non recurrent link genes from output nodes to hidden, output, or even itself. But I don't really know.

Perhaps it should be a configurable option to not form nonrecurrent output links, especially for mutations as pruning the new mutations at runtime from client code greatly impacts runtime in the realtime simulation use cases.

Implement SIGTERM support for experiment runner

We need to implement the SIGTERM support for experiment runner by sharing the execution context and sending cancel signal to the experiment executor upon receiving SIGTERM or similar events from the underlying OS.

Style not rendering from formats generated cytoscape json data.

While working on another issue I was attempting to visualize my networks to better demonstrate the results. I am using the formats WriteCryptoScapes function and using the Cryptoscape desktop app which I think the README.md is referring to as the Cryptoscape App.

The styles appear to be written to the JSON file (see attach, remove .txt extension required by github)
1-1-0.json.txt

However, no styles or formatting is shown at all. Perhaps I just don't know how to use the app correctly. I've tried 3.9.1 and a few older versions of the Cryptospace app with the same results. See the GIF to see how I'm importing the json file and the resulting default style:
cytoscape

I expect the style as in the file which seems to be the same formatting applied in the example shown in the README.md of this repository.

I'm using v3 of goNEAT. Perhaps there is a regression in the formater, it only works with a certain version of the Cryptospace app, or it is user error on my part that isn't obvious?

As always thanks for your time.

Change logger

We need to change logger to more performant and common one, like zap

Automatically tune compatibility threshold for species when training

Hello!
While reading this cool documentation on the technicalities of NEAT, I stumbled upon a Q/A section named:

- Is there a way to automatically set the compatibility threshold for speciation?

image

In their implementation, there seems to be a way to edit the source code and to recompile the NEAT engine so that a certain amount of species is kept when training, so that the number of species does not "explode uncontrollably" when some kind of mutations happen, and even sometimes approach the number of organism in the population, which is by itself very weird (I am the only organism of my species, and so are you! and you.. and you! Is this what extinction feels like?)

I find myself tweaking my threshold beforehand a lot, so that the number of species does not go too high, but it feels like having a set number of species would be desirable.

Have you thought about implementing this in goNEAT? Thanks!

Update GenerationEvaluator to take context.Context as parameter

Currently we have *neat.Options as parameter which is not generalizable for different types of algorithms and experiments. We need to substitute it with context.Context holding specific options for each type of algorithm, including basic neat.Options

How would one go about supporting recurrent graphs?

I would like to give you a hand, or at least try to, by beginning the implementation of recurrent networks in NEAT.

I love the idea of recurrent networks and their emergent properties. That said, have you thought about what steps would be needed for such an implementation? or if another implementation does it well, or if papers cite being able to generate recurrent networks with neat? I remember reading religiously the original NEAT paper and not finding much about the higher-level properties of the generated graphs that NEAT would create, so I am still wondering how one could bring this about (how are time steps counted, how is recurrent links represented, etc.)

Since you explicitly included paths of your code to enable recurrence, I wonder what were your plans about this.

Thanks again for your nice library!

Keep champions between generations

Suggestion in the title. Add a configuration to keep champions (N best of generation, or N best of each species) between generations, so we can keep the best organism and not lose their "winner" genome in breeding.

Missing genome file documentation

hi @yaricom ,

I am trying to use this lib, but I did not find a documentation about how the genoma file is created.
I could guess some columns meaning, but not all of them.

Could we have short description of each column?

Thank you

Remove nodes and links during mutations

I have a larger network with 18 inputs and 3 outputs, and I'm having trouble understanding how hidden nodes, biases, and genes get removed during the process. It seems like no matter what parameters I set for my context, my organisms eventually just expand infinitely with more and more nodes and links, getting slower and slower without making any real fitness improvements.

Digging around in the source code myself, I'm only seeing methods for adding links and nodes but not removing them. Now correct me if I'm wrong but shouldn't it be possible for nodes and links to get deleted during mutation to get rid of unneeded connections?

NewPopulationRandom does not assign random configured activatiors

Hi! Thanks for the awesome library. I'm not sure if this is incorrect behavior, but it was unexpected to me. I'm using v3.

When creating a population with NewRandomPopulation it initializes all activators in the initial genome (inputs, hidden, output) with SigmoidSteepenedActivation. I was expecting it to select from the random activations and weights used in the configuration passed in with the opts parameter.

In my use case this activation type doesn't work well on the output node when the network still lacks many hidden nodes. I'd like it to choose from a random as configured or minimally be able to select the default activation node to use for the first random genome.

Maybe a workaround is to tweak them myself after the initial population is created.

Not sure if this is an issue or a feature request. Thanks for your time!

Log levels do not work properly

// InfoLog The logger to output messages with Info and up level
	InfoLog = func(message string) {
		if LogLevel <= LogLevelInfo {
			_ = loggerInfo.Output(2, message)
		}
	}

neat.InfoLog will log message even when neat.LogLevel = neat.LogLevelError because "error" <= "info" is true.
Please fix

Optimizing genomes before saving

Hello @yaricom , thanks for making such a nice library.

I think it provides lots of very interesting features, as I've used them in my https://github.com/qwertyuu/go-ur project, about trying to teach my computer to play The Royal Game of Ur for fun. I currently have a bot that's been trained using goNEAT in production here https://ur.whnet.ca/ under the name "Neato"

I've been enjoying the Cytoscape export feature, as I think it helps a lot to visualize the phenotype. I also found that some of my very good organisms had "dangling" links, that is, links that pointed to nodes that were not directed towards the output at all.. maybe after mutation, which I expect.

I was thinking, is there a plan to add some kind of tree-shaking to remove those links and nodes that are not in the path to the output?

More details on traits

Hello @yaricom

I like that you innovated in this version of NEAT by adding traits. Though, I think I would like a bit more explanation, as this seem not to be transferrable to other neat implementations.

How are they used in the phenotype?

How are they interpreted by someone exterior to the library for, say, graph visualization of the phenotype?

How are they initialized in the original starting structure for your organisms (the yml file)?

What are the parameters for?

This would be a nice addition to the NEAT world, but I think needs more details for us NEAT-neophytes

Thanks for taking time to make and maintain such a nice piece of lib!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.