Archive for the ‘Java’ Category
Interview-question: How to find all permutations of a given word in a given text? – Java example
Write a function (in Java) to find all permutations of a given word that appear in a given text. For example, for word abc and text abcxyaxbcayxycab the function should return abc, bca, cab.
Answer:
To find a permutation of a string you can use number theory.
There is a method where you can calculate a hash of a string using prime numbers. Every permutation of the same string will give the same hash value. All other string combination which is not a permutation will give some other hash value.
The hash-value is calculated by c1 * p1 + c2 * p2 + … + cn * pn
where ci is a unique value for the current char in the string and where pi is a unique prime number value for the ci char.
Here is the implementation.
Main.java
// Author: Kunuk Nykjaer
public class Main {
final static int[] primes = new int[] { 2, 3, 5, 7, 11, 13, 17,
19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113 };
public static void main(String[] args) {
final char[] text = "abcxaaabbbccyaxbcayaaaxycab"
.toCharArray();
int hash = val(new char[]{'a','b','c'});
for (int i = 0; i < text.length - 2; i++) {
char[] _123 = new char[]{text[i],text[i+1],text[i+2]};
if(val(_123)==hash){
System.out.println(new String(_123) );
}
}
}
static int p(char c) {
return primes[(int)c - (int)'a'];
}
static int val(char[] cs) {
return
p(cs[0])*(int)cs[0] + p(cs[1])*(int)cs[1] + p(cs[2])*(int)cs[2];
}
}
The output is: abc bca cab
Mario AI EANN (evolutionary artifical neural network)
I implemented a hybrid of GA and NN for an agent which plays Mario.
Training method with Genetic algorithm using a NN as a candidate in the population.
A mario framework game is provided by http://marioai.com where you get environment information, and you apply actions to the agent.
Here are two videos of my agent. I didn’t really manage to make it a generalized agent (performs good on unseen levels) but it manage well on levels which is has been trained for (over-fitting).
Below the screen is the input to the NN
Two matrix’s, one with levelscene (5×5), the other with enemies (5×5)
And then some states:
isOnGround, canJump, canShoot, marioMode, blockInFront?, enemyInFront?, pitInFront?
Outputs are: jump, left, right, fire/speed
Input 7, no matrix
Input 57, 5×5 matrix
NN topology
one hidden layer with size 20
Total outputs: 4
———-
Training method:
Fitness is distance passed + 1024 win bonus
Population 100
Generations: until level completed or maxloop is exceeded
Tournament selection
Elitism 20% no steady state
Gaussian mutation 2%
Montana uniform crossover
Hybrid AI example with Java, TicTacToe Reinforcement-Learning and NN
Training an AI player for the Tic Tac Toe game.
A simple example combining Reinforcement learning with Neural network.
I want to train the AI player to be able to beat an opponent which plays randomly.
The training method is simple.
The AI also plays randomly and after the game finishes A positive reward is given if it wins or a negative reward it if it looses.
The input size for the NN is 18 for the pieces on the board, which represent the state. Hidden layer is also 18.
9 for the AI pieces and 9 for opponents pieces. A 0 value is for no piece and 1 is a piece at the index. The output size is 9. The max value of the values is the preferred action. The back propagation is only for one output neuron, the chosen action.
Because I don’t know the next state for the Q-learning, the states are ‘delayed’ in the Q-learning algorithm.
It uses prev state and current state instead.
Winning results after 70.000 training games:
1000 games played.
Random starts
Hero (ai) = 616
Villain = 304
Draw = 80
Villain starts
Hero (ai) = 475
Villain = 449
Draw = 76
Hero starts
Hero (ai) = 807
Villain = 109
Draw = 84
Eclipse project download url options
Remote download:
http://www.mediafire.com/file/q4mh0lzomltdl8r/HybridRLNN_TicTacToe.zip
Local download, but rename the doc file to a zip file
hybridrlnn_tictactoe-zip.doc
Hybrid AI example with Java Genetic algo and NN
This simple example combines Genetic algo with Neural network.
We train the xor by using the weights as the chromosome. The population is candidates of NN.
The fitness function is (1/sumOfSquaredErrors).
The NN has 2 inputs, 2 hidden and 1 output.
After 1000 evolutions, the candidates has the ‘correct’ weights. The back propagation is not used for the NN.
This is a global search. Using only NN is local search, which might get stuck in a local minimum.
Hybrid.java
import java.util.*;
public class Hybrid {
LinkedList<NN> population = new LinkedList<NN>();
final static int populationSize = 100;
static Random rand = new Random();
public Hybrid() {
for (int i = 0; i < populationSize; i++) {
NN c = new NN();
population.add(c);
}
}
public static void main(String[] args) {
long BEGIN = System.currentTimeMillis();
Hybrid h = new Hybrid();
h.run(1000); // evolutions
long END = System.currentTimeMillis();
System.out.println("Time: " + (END - BEGIN) / 1000.0 + " sec.");
}
void run(int evolutions) {
int count = 0;
System.out.println("Optimal fitness value >= " + (1 / 0.001));
System.out.println("Fitness random init");
print();
while (count < evolutions) {
count++;
produceNextGen();
}
System.out.println("\nFitness Result after evolutions " + evolutions);
print();
System.out.println("First candidate test print");
NN nn = population.getFirst();
nn.printAllWeights();
System.out.println("sumSquaredErrors = " + (1 / nn.fitness()));
nn.resultPrint();
}
void print() {
System.out.println("-- print");
for (NN c : population) {
System.out.println(c);
}
}
/**
* Selection strategy: Tournament method Replacement strategy: steady state
* find 4 random in population not same let 2 fight, and 2 fight the winners
* makes 2 children
*/
void produceNextGen() {
LinkedList<NN> newpopulation = new LinkedList<NN>();
while (newpopulation.size() < populationSize) {
int size = population.size();
int i = rand.nextInt(size);
int j, k, l;
j = k = l = i;
while (j == i)
j = rand.nextInt(size);
while (k == i || k == j)
k = rand.nextInt(size);
while (l == i || l == j || k == l)
l = rand.nextInt(size);
NN c1 = population.get(i);
NN c2 = population.get(j);
NN c3 = population.get(k);
NN c4 = population.get(l);
double f1 = c1.fitness();
double f2 = c2.fitness();
double f3 = c3.fitness();
double f4 = c4.fitness();
NN w1, w2;
if (f1 > f2)
w1 = c1;
else
w1 = c2;
if (f3 > f4)
w2 = c3;
else
w2 = c4;
NN child1, child2;
// Method uniform crossover
NN[] childs = newChilds(w1, w2);
child1 = childs[0];
child2 = childs[1];
double mutatePercent = 0.01;
boolean m1 = rand.nextDouble() <= mutatePercent;
boolean m2 = rand.nextDouble() <= mutatePercent;
if (m1)
mutate(child1);
if (m2)
mutate(child2);
boolean isChild1Good = child1.fitness() >= w1.fitness();
boolean isChild2Good = child2.fitness() >= w2.fitness();
newpopulation.add(isChild1Good ? child1 : w1);
newpopulation.add(isChild2Good ? child2 : w2);
}
population = newpopulation;
}
void mutate(NN c) {
int i = rand.nextInt(NN.SIZE);
double range = getRandom() * 2; // range [-1;1[ * 2
c.chromosome[i] = c.chromosome[i] + range;
c.setChromosome(c.chromosome); // update
}
double getRandom() {
return (rand.nextDouble() * 2) - 1; // [-1;1[
}
// Uniform crossover
static NN[] newChilds(NN c1, NN c2) {
NN child1 = new NN();
NN child2 = new NN();
double[] chromosome1 = new double[NN.SIZE];
double[] chromosome2 = new double[NN.SIZE];
for (int i = 0; i < NN.SIZE; i++) {
boolean b = rand.nextDouble() >= 0.5;
if (b) {
chromosome1[i] = c1.chromosome[i];
chromosome2[i] = c2.chromosome[i];
} else {
chromosome1[i] = c2.chromosome[i];
chromosome2[i] = c1.chromosome[i];
}
}
child1.setChromosome(chromosome1);
child2.setChromosome(chromosome2);
return new NN[] { child1, child2 };
}
}
NN.java
import java.util.*;
public class NN {
Random rand = new Random();
// Inputs for xor problem
final float inputs[][] = { { 1, 1 }, { 1, 0 }, { 0, 1 }, { 0, 0 } };
// Corresponding outputs
final float expectedOutputs[][] = { { 0 }, { 1 }, { 1 }, { 0 } };
double resultOutputs[][] = { { -1 }, { -1 }, { -1 }, { -1 } };
double output[];
final int INPUT=0;
final int HIDDEN=1;
final int OUTPUT=2;
final static int SIZE = 9; // 2 2 1 layers, gives 9 weights total
public double[] chromosome = new double[SIZE];
final ArrayList<Neuron> inputLayer = new ArrayList<Neuron>();
final ArrayList<Neuron> hiddenLayer = new ArrayList<Neuron>();
final ArrayList<Neuron> outputLayer = new ArrayList<Neuron>();
final Neuron bias = new Neuron();
final static int layers[] = { 2, 2, 1 }; // input, hidden, output
final static int randomWeightMultiplier = 30;
float learningRate = 1f;
float momentum = 0.9f;
public NN() {
// create all Neurons and connections
// connections are created in the neuron class
for (int i = 0; i < layers.length; i++) {
if (i == INPUT) { // input layer
for (int j = 0; j < layers[i]; j++) {
Neuron neuron = new Neuron();
inputLayer.add(neuron);
}
} else if (i == HIDDEN) { // hidden layer
for (int j = 0; j < layers[i]; j++) {
Neuron neuron = new Neuron();
neuron.addInConnectionsS(inputLayer);
neuron.addBiasConnection(bias);
hiddenLayer.add(neuron);
}
}
else if (i == OUTPUT) { // output layer
for (int j = 0; j < layers[i]; j++) {
Neuron neuron = new Neuron();
neuron.addInConnectionsS(hiddenLayer);
neuron.addBiasConnection(bias);
outputLayer.add(neuron);
}
} else {
System.out.println("!Error NeuralNetwork init");
}
}
// initialize random weights
int i = 0;
for (Neuron neuron : hiddenLayer) {
ArrayList<Connection> connections = neuron.getAllInConnections();
for (Connection conn : connections) {
double newWeight = getRandom();
conn.setWeight(newWeight);
chromosome[i++] = newWeight;
}
}
for (Neuron neuron : outputLayer) {
ArrayList<Connection> connections = neuron.getAllInConnections();
for (Connection conn : connections) {
double newWeight = getRandom();
conn.setWeight(newWeight);
chromosome[i++] = newWeight;
}
}
// reset id counters
Neuron.counter = 0;
Connection.counter = 0;
}
// random
double getRandom() {
return randomWeightMultiplier * (rand.nextDouble() * 2 - 1); // [-1;1[
}
void setInput(float inputs[]) {
// There is equally many neurons in the input layer as there are
// input variables
for (int i = 0; i < inputLayer.size(); i++) {
inputLayer.get(i).setOutput(inputs[i]);
}
}
double[] getOutput() {
double[] outputs = new double[outputLayer.size()];
for (int i = 0; i < outputLayer.size(); i++)
outputs[i] = outputLayer.get(i).getOutput();
return outputs;
}
/**
* Calculate the output of the neural network based on the input The forward
* operation
*/
void activate() {
for (Neuron n : hiddenLayer) {
n.calculateOutput();
}
for (Neuron n : outputLayer) {
n.calculateOutput();
}
}
double[] getAllWeights() {
double[] ds = new double[SIZE];
int i = 0;
// weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = con.getWeight();
ds[i++] = w;
}
}
// weights for the output layer
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = con.getWeight();
ds[i++] = w;
}
}
return ds;
}
// chromosome
public void setChromosome(double[] weights) {
chromosome = weights;
int i = 0;
// weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = weights[i];
con.setWeight(w);
i++;
}
}
// weights for the output layer
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = weights[i];
con.setWeight(w);
i++;
}
}
}
public void printAllWeights() {
// weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = con.getWeight();
System.out.println("n=" + n.id + " c=" + con.id + " w=" + w);
}
}
// weights for the output layer
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = con.getWeight();
System.out.println("n=" + n.id + " c=" + con.id + " w=" + w);
}
}
}
double fitness() {
double error = 0;
for (int p = 0; p < inputs.length; p++) {
setInput(inputs[p]);
activate();
output = getOutput();
resultOutputs[p] = output;
for (int j = 0; j < expectedOutputs[p].length; j++) {
double err = Math.pow(resultOutputs[p][j]
- expectedOutputs[p][j], 2);
error += err;
}
}
return 1 / error; // error can not be 0
}
void resultPrint() {
for (int p = 0; p < inputs.length; p++) {
System.out.print("INPUTS: ");
for (int x = 0; x < layers[INPUT]; x++) {
System.out.print(Float.toString(inputs[p][x]) + " ");
}
System.out.print("EXPECTED: ");
for (int x = 0; x < layers[OUTPUT]; x++) {
System.out.print(Float.toString(expectedOutputs[p][x]) + " ");
}
System.out.print("ACTUAL: ");
for (int x = 0; x < layers[OUTPUT]; x++) {
System.out.print(resultOutputs[p][x] + " ");
}
System.out.println();
}
}
@Override
public String toString() {
return fitness() + "";
}
}
Connection.java
public class Connection
{
double weight=0;
double prevDeltaWeight=0; // for momentum
double deltaWeight=0;
public Neuron leftNeuron;
Neuron rightNeuron;
public static int counter = 0;
public int id;
public Connection(Neuron fromN, Neuron toN){
leftNeuron = fromN;
rightNeuron = toN;
id=counter;
counter++;
}
public double getWeight(){
return weight;
}
public void setWeight(double w){
weight = w;
}
public void setDeltaWeight(double w){
prevDeltaWeight = deltaWeight;
deltaWeight = w;
}
public double getPrevDeltaWeight(){
return prevDeltaWeight;
}
public Neuron getFromNeuron() {
return leftNeuron;
}
public void setFromNeuron(Neuron fromNeuron) {
this.leftNeuron = fromNeuron;
}
public Neuron getToNeuron() {
return rightNeuron;
}
public void setToNeuron(Neuron toNeuron) {
this.rightNeuron = toNeuron;
}
}
Neuron.java
import java.util.ArrayList;
import java.util.HashMap;
public class Neuron
{
public static int counter = 0;
public int id;
double prevWeighted_sum;
Connection biasConnection;
final double bias = -1;
double output;
ArrayList<Connection> Inconnections = new ArrayList<Connection>();
HashMap<Integer,Connection> connectionLookup = new HashMap<Integer,Connection>();
public Neuron(){
id = counter;
counter++;
}
/**
* Compute Sj = Wij*Aij + w0j*bias
* Apply activation function to get output
*/
public void calculateOutput(){
double s = 0;
for(Connection con : Inconnections){
Neuron leftNeuron = con.getFromNeuron();
double weight = con.getWeight();
double a = leftNeuron.getOutput(); //output from previous layer
s = s + (weight*a);
}
s = s + (biasConnection.getWeight()*bias);
output = g(s);
}
double g(double x) {
return sigmoid(x);
}
double sigmoid(double x) {
return 1.0 / (1.0 + (Math.exp(-x)));
}
public void addInConnectionsS(ArrayList<Neuron> inNeurons){
for(Neuron n: inNeurons){
Connection con = new Connection(n,this);
Inconnections.add(con);
connectionLookup.put(n.getId(), con);
}
}
public Connection getConnection(int neuronIndex){
return connectionLookup.get(neuronIndex);
}
public void addInConnection(Connection con){
Inconnections.add(con);
}
public void addBiasConnection(Neuron n){
Connection con = new Connection(n,this);
biasConnection = con;
Inconnections.add(con);
}
public ArrayList<Connection> getAllInConnections(){
return Inconnections;
}
public int getId(){
return id;
}
public void setId(int i){
id = i;
}
public double getBias() {
return bias;
}
public double getOutput() {
return output;
}
public void setOutput(double o){
output = o;
}
}
Result:
Optimal fitness value >= 1000.0
Fitness random init
– print
0.5000000009269805
0.500000232951657
…
Fitness Result after evolutions 1000
– print
3.3354638900410167E22
3.3354638900410167E22
…
First candidate test print
n=3 c=0 w=31.606277910728974
n=3 c=1 w=-50.54100092882488
n=3 c=2 w=17.775932295503686
n=4 c=3 w=49.91618475014163
n=4 c=4 w=-38.968161757863236
n=4 c=5 w=-20.253031449644787
n=5 c=6 w=55.76690734403492
n=5 c=7 w=-52.90412054261615
n=5 c=8 w=-26.253923811742883
sumSquaredErrors = 2.998083723783629E-23
INPUTS: 1.0 1.0 EXPECTED: 0.0 ACTUAL: 2.6666536854779678E-12
INPUTS: 1.0 0.0 EXPECTED: 1.0 ACTUAL: 0.9999999999997737
INPUTS: 0.0 1.0 EXPECTED: 1.0 ACTUAL: 0.9999999999960367
INPUTS: 0.0 0.0 EXPECTED: 0.0 ACTUAL: 2.6666567449509287E-12
Time: 3.411 sec.
Neural network backpropagation with Java
Neural network with backpropagation training xor example.
This framework supports only one hidden layer and the activation function is sigmoid.
In this example there are two inputs neurons, four neurons in hidden layers and one neuron in output layer.
The weights are initialized randomly.
NeuralNetwork.java
import java.text.*;
import java.util.*;
public class NeuralNetwork {
static {
Locale.setDefault(Locale.ENGLISH);
}
final boolean isTrained = false;
final DecimalFormat df;
final Random rand = new Random();
final ArrayList<Neuron> inputLayer = new ArrayList<Neuron>();
final ArrayList<Neuron> hiddenLayer = new ArrayList<Neuron>();
final ArrayList<Neuron> outputLayer = new ArrayList<Neuron>();
final Neuron bias = new Neuron();
final int[] layers;
final int randomWeightMultiplier = 1;
final double epsilon = 0.00000000001;
final double learningRate = 0.9f;
final double momentum = 0.7f;
// Inputs for xor problem
final double inputs[][] = { { 1, 1 }, { 1, 0 }, { 0, 1 }, { 0, 0 } };
// Corresponding outputs, xor training data
final double expectedOutputs[][] = { { 0 }, { 1 }, { 1 }, { 0 } };
double resultOutputs[][] = { { -1 }, { -1 }, { -1 }, { -1 } }; // dummy init
double output[];
// for weight update all
final HashMap<String, Double> weightUpdate = new HashMap<String, Double>();
public static void main(String[] args) {
NeuralNetwork nn = new NeuralNetwork(2, 4, 1);
int maxRuns = 50000;
double minErrorCondition = 0.001;
nn.run(maxRuns, minErrorCondition);
}
public NeuralNetwork(int input, int hidden, int output) {
this.layers = new int[] { input, hidden, output };
df = new DecimalFormat("#.0#");
/**
* Create all neurons and connections Connections are created in the
* neuron class
*/
for (int i = 0; i < layers.length; i++) {
if (i == 0) { // input layer
for (int j = 0; j < layers[i]; j++) {
Neuron neuron = new Neuron();
inputLayer.add(neuron);
}
} else if (i == 1) { // hidden layer
for (int j = 0; j < layers[i]; j++) {
Neuron neuron = new Neuron();
neuron.addInConnectionsS(inputLayer);
neuron.addBiasConnection(bias);
hiddenLayer.add(neuron);
}
}
else if (i == 2) { // output layer
for (int j = 0; j < layers[i]; j++) {
Neuron neuron = new Neuron();
neuron.addInConnectionsS(hiddenLayer);
neuron.addBiasConnection(bias);
outputLayer.add(neuron);
}
} else {
System.out.println("!Error NeuralNetwork init");
}
}
// initialize random weights
for (Neuron neuron : hiddenLayer) {
ArrayList<Connection> connections = neuron.getAllInConnections();
for (Connection conn : connections) {
double newWeight = getRandom();
conn.setWeight(newWeight);
}
}
for (Neuron neuron : outputLayer) {
ArrayList<Connection> connections = neuron.getAllInConnections();
for (Connection conn : connections) {
double newWeight = getRandom();
conn.setWeight(newWeight);
}
}
// reset id counters
Neuron.counter = 0;
Connection.counter = 0;
if (isTrained) {
trainedWeights();
updateAllWeights();
}
}
// random
double getRandom() {
return randomWeightMultiplier * (rand.nextDouble() * 2 - 1); // [-1;1[
}
/**
*
* @param inputs
* There is equally many neurons in the input layer as there are
* in input variables
*/
public void setInput(double inputs[]) {
for (int i = 0; i < inputLayer.size(); i++) {
inputLayer.get(i).setOutput(inputs[i]);
}
}
public double[] getOutput() {
double[] outputs = new double[outputLayer.size()];
for (int i = 0; i < outputLayer.size(); i++)
outputs[i] = outputLayer.get(i).getOutput();
return outputs;
}
/**
* Calculate the output of the neural network based on the input The forward
* operation
*/
public void activate() {
for (Neuron n : hiddenLayer)
n.calculateOutput();
for (Neuron n : outputLayer)
n.calculateOutput();
}
/**
* all output propagate back
*
* @param expectedOutput
* first calculate the partial derivative of the error with
* respect to each of the weight leading into the output neurons
* bias is also updated here
*/
public void applyBackpropagation(double expectedOutput[]) {
// error check, normalize value ]0;1[
for (int i = 0; i < expectedOutput.length; i++) {
double d = expectedOutput[i];
if (d < 0 || d > 1) {
if (d < 0)
expectedOutput[i] = 0 + epsilon;
else
expectedOutput[i] = 1 - epsilon;
}
}
int i = 0;
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double ak = n.getOutput();
double ai = con.leftNeuron.getOutput();
double desiredOutput = expectedOutput[i];
double partialDerivative = -ak * (1 - ak) * ai
* (desiredOutput - ak);
double deltaWeight = -learningRate * partialDerivative;
double newWeight = con.getWeight() + deltaWeight;
con.setDeltaWeight(deltaWeight);
con.setWeight(newWeight + momentum * con.getPrevDeltaWeight());
}
i++;
}
// update weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double aj = n.getOutput();
double ai = con.leftNeuron.getOutput();
double sumKoutputs = 0;
int j = 0;
for (Neuron out_neu : outputLayer) {
double wjk = out_neu.getConnection(n.id).getWeight();
double desiredOutput = (double) expectedOutput[j];
double ak = out_neu.getOutput();
j++;
sumKoutputs = sumKoutputs
+ (-(desiredOutput - ak) * ak * (1 - ak) * wjk);
}
double partialDerivative = aj * (1 - aj) * ai * sumKoutputs;
double deltaWeight = -learningRate * partialDerivative;
double newWeight = con.getWeight() + deltaWeight;
con.setDeltaWeight(deltaWeight);
con.setWeight(newWeight + momentum * con.getPrevDeltaWeight());
}
}
}
void run(int maxSteps, double minError) {
int i;
// Train neural network until minError reached or maxSteps exceeded
double error = 1;
for (i = 0; i < maxSteps && error > minError; i++) {
error = 0;
for (int p = 0; p < inputs.length; p++) {
setInput(inputs[p]);
activate();
output = getOutput();
resultOutputs[p] = output;
for (int j = 0; j < expectedOutputs[p].length; j++) {
double err = Math.pow(output[j] - expectedOutputs[p][j], 2);
error += err;
}
applyBackpropagation(expectedOutputs[p]);
}
}
printResult();
System.out.println("Sum of squared errors = " + error);
System.out.println("##### EPOCH " + i+"\n");
if (i == maxSteps) {
System.out.println("!Error training try again");
} else {
printAllWeights();
printWeightUpdate();
}
}
void printResult()
{
System.out.println("NN example with xor training");
for (int p = 0; p < inputs.length; p++) {
System.out.print("INPUTS: ");
for (int x = 0; x < layers[0]; x++) {
System.out.print(inputs[p][x] + " ");
}
System.out.print("EXPECTED: ");
for (int x = 0; x < layers[2]; x++) {
System.out.print(expectedOutputs[p][x] + " ");
}
System.out.print("ACTUAL: ");
for (int x = 0; x < layers[2]; x++) {
System.out.print(resultOutputs[p][x] + " ");
}
System.out.println();
}
System.out.println();
}
String weightKey(int neuronId, int conId) {
return "N" + neuronId + "_C" + conId;
}
/**
* Take from hash table and put into all weights
*/
public void updateAllWeights() {
// update weights for the output layer
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
String key = weightKey(n.id, con.id);
double newWeight = weightUpdate.get(key);
con.setWeight(newWeight);
}
}
// update weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
String key = weightKey(n.id, con.id);
double newWeight = weightUpdate.get(key);
con.setWeight(newWeight);
}
}
}
// trained data
void trainedWeights() {
weightUpdate.clear();
weightUpdate.put(weightKey(3, 0), 1.03);
weightUpdate.put(weightKey(3, 1), 1.13);
weightUpdate.put(weightKey(3, 2), -.97);
weightUpdate.put(weightKey(4, 3), 7.24);
weightUpdate.put(weightKey(4, 4), -3.71);
weightUpdate.put(weightKey(4, 5), -.51);
weightUpdate.put(weightKey(5, 6), -3.28);
weightUpdate.put(weightKey(5, 7), 7.29);
weightUpdate.put(weightKey(5, 8), -.05);
weightUpdate.put(weightKey(6, 9), 5.86);
weightUpdate.put(weightKey(6, 10), 6.03);
weightUpdate.put(weightKey(6, 11), .71);
weightUpdate.put(weightKey(7, 12), 2.19);
weightUpdate.put(weightKey(7, 13), -8.82);
weightUpdate.put(weightKey(7, 14), -8.84);
weightUpdate.put(weightKey(7, 15), 11.81);
weightUpdate.put(weightKey(7, 16), .44);
}
public void printWeightUpdate() {
System.out.println("printWeightUpdate, put this i trainedWeights() and set isTrained to true");
// weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
String w = df.format(con.getWeight());
System.out.println("weightUpdate.put(weightKey(" + n.id + ", "
+ con.id + "), " + w + ");");
}
}
// weights for the output layer
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
String w = df.format(con.getWeight());
System.out.println("weightUpdate.put(weightKey(" + n.id + ", "
+ con.id + "), " + w + ");");
}
}
System.out.println();
}
public void printAllWeights() {
System.out.println("printAllWeights");
// weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = con.getWeight();
System.out.println("n=" + n.id + " c=" + con.id + " w=" + w);
}
}
// weights for the output layer
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double w = con.getWeight();
System.out.println("n=" + n.id + " c=" + con.id + " w=" + w);
}
}
System.out.println();
}
}
Connection.java
import java.util.*;
public class Neuron {
static int counter = 0;
final public int id; // auto increment, starts at 0
Connection biasConnection;
final double bias = -1;
double output;
ArrayList<Connection> Inconnections = new ArrayList<Connection>();
HashMap<Integer,Connection> connectionLookup = new HashMap<Integer,Connection>();
public Neuron(){
id = counter;
counter++;
}
/**
* Compute Sj = Wij*Aij + w0j*bias
*/
public void calculateOutput(){
double s = 0;
for(Connection con : Inconnections){
Neuron leftNeuron = con.getFromNeuron();
double weight = con.getWeight();
double a = leftNeuron.getOutput(); //output from previous layer
s = s + (weight*a);
}
s = s + (biasConnection.getWeight()*bias);
output = g(s);
}
double g(double x) {
return sigmoid(x);
}
double sigmoid(double x) {
return 1.0 / (1.0 + (Math.exp(-x)));
}
public void addInConnectionsS(ArrayList<Neuron> inNeurons){
for(Neuron n: inNeurons){
Connection con = new Connection(n,this);
Inconnections.add(con);
connectionLookup.put(n.id, con);
}
}
public Connection getConnection(int neuronIndex){
return connectionLookup.get(neuronIndex);
}
public void addInConnection(Connection con){
Inconnections.add(con);
}
public void addBiasConnection(Neuron n){
Connection con = new Connection(n,this);
biasConnection = con;
Inconnections.add(con);
}
public ArrayList<Connection> getAllInConnections(){
return Inconnections;
}
public double getBias() {
return bias;
}
public double getOutput() {
return output;
}
public void setOutput(double o){
output = o;
}
}
Neuron.java
public class Connection {
double weight = 0;
double prevDeltaWeight = 0; // for momentum
double deltaWeight = 0;
final Neuron leftNeuron;
final Neuron rightNeuron;
static int counter = 0;
final public int id; // auto increment, starts at 0
public Connection(Neuron fromN, Neuron toN) {
leftNeuron = fromN;
rightNeuron = toN;
id = counter;
counter++;
}
public double getWeight() {
return weight;
}
public void setWeight(double w) {
weight = w;
}
public void setDeltaWeight(double w) {
prevDeltaWeight = deltaWeight;
deltaWeight = w;
}
public double getPrevDeltaWeight() {
return prevDeltaWeight;
}
public Neuron getFromNeuron() {
return leftNeuron;
}
public Neuron getToNeuron() {
return rightNeuron;
}
}
Result:
NN example with xor training
INPUTS: 1.0 1.0 EXPECTED: 0.0 ACTUAL: 0.01978605453528619
INPUTS: 1.0 0.0 EXPECTED: 1.0 ACTUAL: 0.9836399078122067
INPUTS: 0.0 1.0 EXPECTED: 1.0 ACTUAL: 0.9831299198563257
INPUTS: 0.0 0.0 EXPECTED: 0.0 ACTUAL: 0.007493158102140806
Sum of squared errors = 9.99887592864088E-4
##### EPOCH 5689