Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract AI (Machine learning) API #31

Draft
wants to merge 6 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ai/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
*/

dependencies {
//compile "nl.sandergielisse:mythan:1.0-SNAPSHOT"
compile "nl.sandergielisse:mythan:1.0-SNAPSHOT"
}
33 changes: 33 additions & 0 deletions ai/src/main/java/net/daporkchop/lib/ai/AI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai;

/**
* Abstract representation of an AI.
*
* @author DaPorkchop_
* @see NeuralNetwork
*/
public interface AI {
/**
* Gets this AIs fitness level (aka skill).
*
* The meaning of this value varies depending on the {@link Evaluator} used to train this AI.
*
* @return this AIs fitness
*/
double fitness();
}
88 changes: 88 additions & 0 deletions ai/src/main/java/net/daporkchop/lib/ai/Evaluator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai;

import lombok.NonNull;

/**
* A type that can train an AI.
*
* @author DaPorkchop_
*/
public interface Evaluator<A extends AI> {
/**
* Initializes the trainer in preparation for training.
* <p>
* This method is only called once for the beginning of training.
* <p>
* This may be used to e.g. load training data from disk.
*
* @param totalWorkers the total number of workers that will be used
* @throws Exception if an exception occurs while initializing
*/
default void init(int totalWorkers) throws Exception {
}

/**
* Initializes a single worker in preparation for training.
* <p>
* This method is only called once per worker, and will always be called from the same thread that the worker
* will later be training on.
*
* @param worker the ordinal of the current worker
* @param totalWorkers the total number of workers
* @throws Exception if an exception occurs while initializing
*/
default void initWorker(int worker, int totalWorkers) throws Exception {
}

/**
* Evaluates a single specimen.
* <p>
* This method should evaluate the fitness of the given specimen by feeding it a large number of test
* data samples and seeing what the results are, and return a {@code double} value that represents the fitness
* of the specimen. The network's fitness is not on any sort of scale, higher values simply indicate that the
* specimen performed better (although the fitness value should be directly proportional to the specimen's
* performance, for example it could be simply the number of tests that were passed successfully). However, the
* fitness must be at least {@code 0.0d} and may not be {@link Double#NaN}.
*
* @param specimen the specimen to evaluate
* @return the specimen's skill
*/
double evaluate(@NonNull A specimen);

/**
* De-initializes a worker after training is complete.
* <p>
* This method is only called once per worker, and will always be called from the same thread that the worker
* will later be training on.
*
* @param worker the ordinal of the current worker
* @param totalWorkers the total number of workers
* @throws Exception if an exception occurs while de-initializing
*/
default void deinitWorker(int worker, int totalWorkers) throws Exception {
}

/**
* De-initializes the trainer after training is complete.
*
* @param totalWorkers the total number of workers
* @throws Exception if an exception occurs while initializing
*/
default void deinit(int totalWorkers) throws Exception {
}
}
61 changes: 61 additions & 0 deletions ai/src/main/java/net/daporkchop/lib/ai/NeuralNetwork.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai;

import lombok.NonNull;

/**
* An {@link AI} based on a network of interconnected nodes.
* <p>
* A neural network typically has a fixed number of inputs and outputs.
*
* @author DaPorkchop_
*/
public interface NeuralNetwork extends AI {
/**
* Runs the network on the given input data, storing the output values in the given array.
*
* @param inputs an array containing the input values
* @param outputs an array that the output values will be stored in
* @throws IllegalArgumentException if either parameters are not exactly the correct size (see {@link #inputs()} and {@link #outputs()}, respectively)
*/
void compute(@NonNull double[] inputs, @NonNull double[] outputs) throws IllegalArgumentException;

/**
* Runs the network on the given input data, storing the output values in the returned array.
* <p>
* This method should be avoided in favor of {@link #compute(double[], double[])} if possible.
*
* @param inputs an array containing the input values
* @return an array containing the output values
* @throws IllegalArgumentException if the input array is not exactly the same size as {@link #inputs()}
*/
default double[] compute(@NonNull double[] inputs) throws IllegalArgumentException {
double[] outputs = new double[this.outputs()];
this.compute(inputs, outputs);
return outputs;
}

/**
* @return the network's input count
*/
int inputs();

/**
* @return the network's output count
*/
int outputs();
}
49 changes: 49 additions & 0 deletions ai/src/main/java/net/daporkchop/lib/ai/Trainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai;

import net.daporkchop.lib.ai.alg.MachineLearning;
import net.daporkchop.lib.ai.alg.TrainingOptions;

/**
* Helper class to manage training of AIs.
*
* @author DaPorkchop_
*/
//TODO: this should be made using futures and stuff, so that training may be paused, etc.
public interface Trainer<A extends AI, O extends TrainingOptions<? extends A, O>> /*extends Serializable*/ {
/**
* @return the specimen with the highest fitness
*/
A fittestSpecimen();

/**
* @return the options used by this trainer
*/
O options();

/**
* @return the {@link Evaluator} instance being used by this trainer
*/
Evaluator<? extends A> evaluator();

/**
* Initiates the training cycle, continuing until a specimen reaches at least the given fitness.
*
* @param fitness the minimum fitness to train to
*/
void trainToFitness(double fitness);
}
37 changes: 37 additions & 0 deletions ai/src/main/java/net/daporkchop/lib/ai/alg/MachineLearning.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai.alg;

import lombok.NonNull;
import net.daporkchop.lib.ai.AI;
import net.daporkchop.lib.ai.Evaluator;
import net.daporkchop.lib.ai.Trainer;

/**
* Abstract representation of a machine learning algorithm.
*
* @author DaPorkchop_
*/
public interface MachineLearning<A extends AI, O extends TrainingOptions<? extends A, O>> {
/**
* Prepares to begin training an AI.
*
* @param evaluator the {@link Evaluator} that will evaluate the AI's performance
* @param options options used for training
* @return a {@link Trainer} that will be used to control the training process
*/
Trainer<A, O> beginTraining(@NonNull Evaluator<A> evaluator, @NonNull O options);
}
49 changes: 49 additions & 0 deletions ai/src/main/java/net/daporkchop/lib/ai/alg/TrainingOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai.alg;

import lombok.Getter;
import lombok.experimental.Accessors;
import net.daporkchop.lib.ai.AI;
import net.daporkchop.lib.common.util.PorkUtil;

/**
* Options used when training an AI.
*
* @author DaPorkchop_
*/
@Accessors(fluent = true, chain = true)
@Getter
public abstract class TrainingOptions<A extends AI, O extends TrainingOptions<A, O>> {
/**
* The number of worker threads to use for training.
* <p>
* Defaults to the CPU count.
*/
protected int workers = PorkUtil.CPU_COUNT;

/**
* @see #workers
*/
@SuppressWarnings("unchecked")
public O workers(int workers) {
if (workers <= 0) {
throw new IllegalStateException("Must have at least 1 worker!");
}
this.workers = workers;
return (O) this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Adapted from the Wizardry License
*
* Copyright (c) 2018-2019 DaPorkchop_ and contributors
*
* Permission is hereby granted to any persons and/or organizations using this software to copy, modify, merge, publish, and distribute it. Said persons and/or organizations are not allowed to use the software or any derivatives of the work for commercial use or any other means to generate income, nor are they allowed to claim this software as their own.
*
* The persons and/or organizations are also disallowed from sub-licensing and/or trademarking this software without explicit permission from DaPorkchop_.
*
* Any persons and/or organizations using this software must disclose their source code and have it publicly available, include this license, provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package net.daporkchop.lib.ai.alg.abst;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import net.daporkchop.lib.ai.NeuralNetwork;
import net.daporkchop.lib.ai.alg.TrainingOptions;

/**
* A basic implementation of {@link NeuralNetwork}.
*
* @author DaPorkchop_
*/
@RequiredArgsConstructor
@Getter
@Accessors(fluent = true)
public abstract class AbstractNeuralNetwork implements NeuralNetwork {
protected final int inputs;
protected final int outputs;

protected double fitness = Double.NaN;

protected void validateParameters(@NonNull double[] inputs, @NonNull double[] outputs) throws IllegalArgumentException {
if (inputs.length != this.inputs) {
throw new IllegalArgumentException(String.format("Invalid input count! Expected %d, found %d", this.inputs, inputs.length));
} else if (outputs.length != this.outputs) {
throw new IllegalArgumentException(String.format("Invalid output count! Expected %d, found %d", this.outputs, outputs.length));
}
}
}
Loading