A neuroevolution library for Java and Kotlin written purely in Kotlin, featuring multiple neuroevolution algorithms, serialization and multi-threading.
From Maven Central:
Maven
<dependencies>
<dependency>
<groupId>eu.timerertim.knevo</groupId>
<artifactId>knevo</artifactId>
<version>0.2.0-RC</version>
</dependency>
</dependencies>Gradle Groovy
dependencies {
implementation 'eu.timerertim.knevo:knevo:0.2.0-RC'
}Gradle KTS
dependencies {
implementation("eu.timerertim.knevo:knevo:0.2.0-RC")
}Algorithms:
Features:
- Serialization
- Multithreading using Coroutines
- Custom Activation Functions
You must implement the Environment interface and override the evaluateFitness(population: List<Genome>) function.
For each Genome in the population, you want to set its fitness.
Everything requires an Instance. It is the interface to an algorithm implementation.
val instance = InstinctInstanceBuilder(2, 1)
.mutateAddSelfConnectionChance(0F)
.mutateAddRecurrentConnectionChance(0F)
.mutateRemoveConnectionChance(2.15F)
.hiddenActivations(Sigmoid(), Tanh(), Step(), Sign(), Linear(), Sinus(), Relu(), Selu(), Silu())
.outputActivations(Sign())
.build()val network = instance.Network()
println(network(floatArrayOf(0F, 1F)))The Instance can be set globally, so you don't have to explicitly specify the Instance everytime.
globalInstinctInstance = InstinctInstance(2, 1)val network = Network()
println(network(floatArrayOf(0F, 1F)))You can use individual Networks like above. However, you typically want to make use of a bigger population.
val pool = Pool(
populationSize = 500,
select = Tournament(10)
)You can use this and some environment to write a training loop.
do {
pool.evolve(environment)
} while(pool.topFitness < 100)Finally, the trained Genome can be retrieved.
val network = pool.topGenomeThis library supports multithreading by using Coroutines. Populations are separated into batches, which are processed
in parallel. This behavior can be configured on every Population.
val pool = PoolBuilder()
.populationSize(200)
.batchSize(50)
.build()Note that when using this feature, the Environment has to be thread safe as multiple Genomes are evaluated in
parallel.
You can easily save any Network or Pool:
network.save("out/my_trained_network.knv")And load it as easily:
val network: InstinctNetwork = load("out/my_trained_network.knv") ?: Network()Because the load function returns null if the specified file does not yet exist, you can easily define an
initiative Network or Pool.
Knevo is licensed under the MIT License.
I, the project owner, am currently attending the higher technical college of Grieskirchen. My education takes me about as much time as a full time job, not counting homework and similar tasks. In addition, I also have a part-time job. Because of this, the development pace is not as fast as one may expect. Nonetheless, I like to extend this library as demanded. Just be aware that development might be or become a little slow.