Last active
November 9, 2017 06:42
-
-
Save adrianseeley/9582220 to your computer and use it in GitHub Desktop.
Code Used To Generate: Neural Genetic Adaptation of the Iris Dataset (GATO-2014)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function gnn (cases, wide, tall, population, iterations, error_fn, error_thresh) { | |
var inputs = cases[0][0].length; | |
var outputs = cases[0][1].length; | |
// declare net, provide input layer | |
var net = [new Array(inputs)]; | |
// create input neurons in input layer | |
for (var i = 0; i < inputs; i++) | |
net[0][i] = {output: 0} | |
// create hidden layers | |
for (var x = 0; x < wide; x++) { | |
var hidden_layer = []; | |
// create hidden neurons | |
for (var y = 0; y < tall; y++) { | |
// create weights from length of previous layer in net | |
var weights = []; | |
for (var w = 0; w < net[net.length - 1].length; w++) | |
weights.push(0); | |
var hidden_node = {weights: weights, bias: 0, output: 0} | |
hidden_layer.push(hidden_node); | |
} | |
net.push(hidden_layer); | |
} | |
// create output layer | |
var output_layer = []; | |
for (var o = 0; o < outputs; o++) { | |
var weights = []; | |
for (var w = 0; w < net[net.length - 1].length; w++) | |
weights.push(0); | |
output_layer.push({weights: weights, bias: 0, output: 0}); | |
} | |
net.push(output_layer); | |
// declare population and fill | |
var pop = []; | |
while(pop.length < population) | |
pop.push(JSON.parse(JSON.stringify(net))); | |
// declare snaps | |
var snaps = [-32, -16, -8, -4, -2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2, 4, 8, 16, 32]; | |
// declare breeding cap | |
var breeding_cap = Math.ceil(population * 0.05); | |
// provide starting fitness | |
pop[0].fitness = error_fn(pop[0], cases); | |
// begin genetic cycle | |
for (var i = 0; i < iterations && pop[0].fitness > error_thresh; i++) { | |
var muta = (Math.sin(i * (1 / (10 + (i / 100)))) + 1) / 2; | |
console.log(i, pop[0].fitness, muta); | |
// fill breeding room | |
for (var dest = breeding_cap; dest < pop.length; dest = dest /*NOOP*/) { | |
for (var host_left = 0; host_left < breeding_cap && dest < pop.length; host_left++) { | |
for (var host_right = 0; host_right < breeding_cap && dest < pop.length; host_right++) { | |
for (var layer = 1; layer < pop[host_left].length; layer++) { | |
for (var neuron = 0; neuron < pop[host_left][layer].length; neuron++) { | |
// weights | |
for (var weight = 0; weight < pop[host_left][layer][neuron].weights.length; weight++) { | |
// perform snapping (choose new component from snaps) | |
if (Math.random() < muta) { | |
pop[dest][layer][neuron].weights[weight] = snaps[Math.floor(Math.random() * snaps.length)]; | |
// perform full crossover (copy right component) | |
} else if (Math.random() < muta) { | |
pop[dest][layer][neuron].weights[weight] = pop[host_right][layer][neuron].weights[weight]; | |
// perform average crossover (add left and right components then divide by 2) | |
} else if (Math.random() < muta) { | |
pop[dest][layer][neuron].weights[weight] = (pop[host_left][layer][neuron].weights[weight] + pop[host_right][layer][neuron].weights[weight]) / 2; | |
// copy left component (full left crossover) | |
} else { | |
pop[dest][layer][neuron].weights[weight] = pop[host_left][layer][neuron].weights[weight]; | |
} | |
// perform mutation independtanly (so crossover or snap then muta is possible) | |
if (Math.random() < muta) { | |
pop[dest][layer][neuron].weights[weight] += muta * ((Math.random() * 2) - 1); | |
} | |
} | |
// bias | |
// perform snapping (choose new bias from snaps) | |
if (Math.random() < muta) { | |
pop[dest][layer][neuron].bias = snaps[Math.floor(Math.random() * snaps.length)]; | |
// perform full crossover (copy right bias) | |
} else if (Math.random() < muta) { | |
pop[dest][layer][neuron].bias = pop[host_right][layer][neuron].bias; | |
// perform average crossover (add left and right bias then divide by 2) | |
} else if (Math.random() < muta) { | |
pop[dest][layer][neuron].bias = (pop[host_left][layer][neuron].bias + pop[host_right][layer][neuron].bias) / 2; | |
// copy left bias (full left crossover) | |
} else { | |
pop[dest][layer][neuron].bias = pop[host_left][layer][neuron].bias; | |
} | |
// perform mutation independtanly (so crossover or snap then muta is possible) | |
if (Math.random() < muta) { | |
pop[dest][layer][neuron].bias += muta * ((Math.random() * 2) - 1); | |
} | |
} | |
} | |
dest++; | |
} | |
} | |
} | |
// provide fitness to new networks | |
for (var dest = breeding_cap; dest < pop.length; dest++) { | |
pop[dest].fitness = error_fn(pop[dest], cases); | |
} | |
// sort pop | |
pop.sort(function (a, b) { return a.fitness - b.fitness; }); | |
} | |
return pop[0]; | |
}; | |
function run (nn, inputs) { | |
// provide input values to input neurons | |
for (var i = 0; i < inputs.length; i++) | |
nn[0][i].output = inputs[i]; | |
// resolve network | |
for (var x = 1; x < nn.length; x++) | |
for (var y = 0; y < nn[x].length; y++) { | |
// transfer | |
nn[x][y].output = nn[x][y].bias; | |
for (var y2 = 0; y2 < nn[x - 1].length; y2++) | |
nn[x][y].output += nn[x - 1][y2].output * nn[x][y].weights[y2]; | |
// activate | |
nn[x][y].output = 1 / (1 + Math.exp(-nn[x][y].output)); | |
} | |
// gather outputs | |
var outputs = []; | |
for (var o = 0; o < nn[nn.length - 1].length; o++) | |
outputs.push(nn[nn.length - 1][o].output); | |
return outputs; | |
}; | |
function error_rmse (nn, cases) { | |
var se_overall = 0; | |
for (var c = 0; c < cases.length; c++) { | |
var outputs = run(nn, cases[c][0]); | |
var se_per_case = 0; | |
for (var o = 0; o < outputs.length; o++) | |
se_per_case += Math.pow(outputs[o] - cases[c][1][o], 2); | |
se_overall += Math.sqrt(se_per_case / outputs.length); | |
} | |
return Math.sqrt(se_overall / cases.length); | |
}; | |
var iris = [ | |
[[5.1, 3.5, 1.4, 0.2], [0]], | |
[[4.9, 3.0, 1.4, 0.2], [0]], | |
[[4.7, 3.2, 1.3, 0.2], [0]], | |
[[4.6, 3.1, 1.5, 0.2], [0]], | |
[[5.0, 3.6, 1.4, 0.2], [0]], | |
[[5.4, 3.9, 1.7, 0.4], [0]], | |
[[4.6, 3.4, 1.4, 0.3], [0]], | |
[[5.0, 3.4, 1.5, 0.2], [0]], | |
[[4.4, 2.9, 1.4, 0.2], [0]], | |
[[4.9, 3.1, 1.5, 0.1], [0]], | |
[[5.4, 3.7, 1.5, 0.2], [0]], | |
[[4.8, 3.4, 1.6, 0.2], [0]], | |
[[4.8, 3.0, 1.4, 0.1], [0]], | |
[[4.3, 3.0, 1.1, 0.1], [0]], | |
[[5.8, 4.0, 1.2, 0.2], [0]], | |
[[5.7, 4.4, 1.5, 0.4], [0]], | |
[[5.4, 3.9, 1.3, 0.4], [0]], | |
[[5.1, 3.5, 1.4, 0.3], [0]], | |
[[5.7, 3.8, 1.7, 0.3], [0]], | |
[[5.1, 3.8, 1.5, 0.3], [0]], | |
[[5.4, 3.4, 1.7, 0.2], [0]], | |
[[5.1, 3.7, 1.5, 0.4], [0]], | |
[[4.6, 3.6, 1.0, 0.2], [0]], | |
[[5.1, 3.3, 1.7, 0.5], [0]], | |
[[4.8, 3.4, 1.9, 0.2], [0]], | |
[[5.0, 3.0, 1.6, 0.2], [0]], | |
[[5.0, 3.4, 1.6, 0.4], [0]], | |
[[5.2, 3.5, 1.5, 0.2], [0]], | |
[[5.2, 3.4, 1.4, 0.2], [0]], | |
[[4.7, 3.2, 1.6, 0.2], [0]], | |
[[4.8, 3.1, 1.6, 0.2], [0]], | |
[[5.4, 3.4, 1.5, 0.4], [0]], | |
[[5.2, 4.1, 1.5, 0.1], [0]], | |
[[5.5, 4.2, 1.4, 0.2], [0]], | |
[[4.9, 3.1, 1.5, 0.2], [0]], | |
[[5.0, 3.2, 1.2, 0.2], [0]], | |
[[5.5, 3.5, 1.3, 0.2], [0]], | |
[[4.9, 3.6, 1.4, 0.1], [0]], | |
[[4.4, 3.0, 1.3, 0.2], [0]], | |
[[5.1, 3.4, 1.5, 0.2], [0]], | |
[[5.0, 3.5, 1.3, 0.3], [0]], | |
[[4.5, 2.3, 1.3, 0.3], [0]], | |
[[4.4, 3.2, 1.3, 0.2], [0]], | |
[[5.0, 3.5, 1.6, 0.6], [0]], | |
[[5.1, 3.8, 1.9, 0.4], [0]], | |
[[4.8, 3.0, 1.4, 0.3], [0]], | |
[[5.1, 3.8, 1.6, 0.2], [0]], | |
[[4.6, 3.2, 1.4, 0.2], [0]], | |
[[5.3, 3.7, 1.5, 0.2], [0]], | |
[[5.0, 3.3, 1.4, 0.2], [0]], | |
[[7.0, 3.2, 4.7, 1.4], [0.5]], | |
[[6.4, 3.2, 4.5, 1.5], [0.5]], | |
[[6.9, 3.1, 4.9, 1.5], [0.5]], | |
[[5.5, 2.3, 4.0, 1.3], [0.5]], | |
[[6.5, 2.8, 4.6, 1.5], [0.5]], | |
[[5.7, 2.8, 4.5, 1.3], [0.5]], | |
[[6.3, 3.3, 4.7, 1.6], [0.5]], | |
[[4.9, 2.4, 3.3, 1.0], [0.5]], | |
[[6.6, 2.9, 4.6, 1.3], [0.5]], | |
[[5.2, 2.7, 3.9, 1.4], [0.5]], | |
[[5.0, 2.0, 3.5, 1.0], [0.5]], | |
[[5.9, 3.0, 4.2, 1.5], [0.5]], | |
[[6.0, 2.2, 4.0, 1.0], [0.5]], | |
[[6.1, 2.9, 4.7, 1.4], [0.5]], | |
[[5.6, 2.9, 3.6, 1.3], [0.5]], | |
[[6.7, 3.1, 4.4, 1.4], [0.5]], | |
[[5.6, 3.0, 4.5, 1.5], [0.5]], | |
[[5.8, 2.7, 4.1, 1.0], [0.5]], | |
[[6.2, 2.2, 4.5, 1.5], [0.5]], | |
[[5.6, 2.5, 3.9, 1.1], [0.5]], | |
[[5.9, 3.2, 4.8, 1.8], [0.5]], | |
[[6.1, 2.8, 4.0, 1.3], [0.5]], | |
[[6.3, 2.5, 4.9, 1.5], [0.5]], | |
[[6.1, 2.8, 4.7, 1.2], [0.5]], | |
[[6.4, 2.9, 4.3, 1.3], [0.5]], | |
[[6.6, 3.0, 4.4, 1.4], [0.5]], | |
[[6.8, 2.8, 4.8, 1.4], [0.5]], | |
[[6.7, 3.0, 5.0, 1.7], [0.5]], | |
[[6.0, 2.9, 4.5, 1.5], [0.5]], | |
[[5.7, 2.6, 3.5, 1.0], [0.5]], | |
[[5.5, 2.4, 3.8, 1.1], [0.5]], | |
[[5.5, 2.4, 3.7, 1.0], [0.5]], | |
[[5.8, 2.7, 3.9, 1.2], [0.5]], | |
[[6.0, 2.7, 5.1, 1.6], [0.5]], | |
[[5.4, 3.0, 4.5, 1.5], [0.5]], | |
[[6.0, 3.4, 4.5, 1.6], [0.5]], | |
[[6.7, 3.1, 4.7, 1.5], [0.5]], | |
[[6.3, 2.3, 4.4, 1.3], [0.5]], | |
[[5.6, 3.0, 4.1, 1.3], [0.5]], | |
[[5.5, 2.5, 4.0, 1.3], [0.5]], | |
[[5.5, 2.6, 4.4, 1.2], [0.5]], | |
[[6.1, 3.0, 4.6, 1.4], [0.5]], | |
[[5.8, 2.6, 4.0, 1.2], [0.5]], | |
[[5.0, 2.3, 3.3, 1.0], [0.5]], | |
[[5.6, 2.7, 4.2, 1.3], [0.5]], | |
[[5.7, 3.0, 4.2, 1.2], [0.5]], | |
[[5.7, 2.9, 4.2, 1.3], [0.5]], | |
[[6.2, 2.9, 4.3, 1.3], [0.5]], | |
[[5.1, 2.5, 3.0, 1.1], [0.5]], | |
[[5.7, 2.8, 4.1, 1.3], [0.5]], | |
[[6.3, 3.3, 6.0, 2.5], [1]], | |
[[5.8, 2.7, 5.1, 1.9], [1]], | |
[[7.1, 3.0, 5.9, 2.1], [1]], | |
[[6.3, 2.9, 5.6, 1.8], [1]], | |
[[6.5, 3.0, 5.8, 2.2], [1]], | |
[[7.6, 3.0, 6.6, 2.1], [1]], | |
[[4.9, 2.5, 4.5, 1.7], [1]], | |
[[7.3, 2.9, 6.3, 1.8], [1]], | |
[[6.7, 2.5, 5.8, 1.8], [1]], | |
[[7.2, 3.6, 6.1, 2.5], [1]], | |
[[6.5, 3.2, 5.1, 2.0], [1]], | |
[[6.4, 2.7, 5.3, 1.9], [1]], | |
[[6.8, 3.0, 5.5, 2.1], [1]], | |
[[5.7, 2.5, 5.0, 2.0], [1]], | |
[[5.8, 2.8, 5.1, 2.4], [1]], | |
[[6.4, 3.2, 5.3, 2.3], [1]], | |
[[6.5, 3.0, 5.5, 1.8], [1]], | |
[[7.7, 3.8, 6.7, 2.2], [1]], | |
[[7.7, 2.6, 6.9, 2.3], [1]], | |
[[6.0, 2.2, 5.0, 1.5], [1]], | |
[[6.9, 3.2, 5.7, 2.3], [1]], | |
[[5.6, 2.8, 4.9, 2.0], [1]], | |
[[7.7, 2.8, 6.7, 2.0], [1]], | |
[[6.3, 2.7, 4.9, 1.8], [1]], | |
[[6.7, 3.3, 5.7, 2.1], [1]], | |
[[7.2, 3.2, 6.0, 1.8], [1]], | |
[[6.2, 2.8, 4.8, 1.8], [1]], | |
[[6.1, 3.0, 4.9, 1.8], [1]], | |
[[6.4, 2.8, 5.6, 2.1], [1]], | |
[[7.2, 3.0, 5.8, 1.6], [1]], | |
[[7.4, 2.8, 6.1, 1.9], [1]], | |
[[7.9, 3.8, 6.4, 2.0], [1]], | |
[[6.4, 2.8, 5.6, 2.2], [1]], | |
[[6.3, 2.8, 5.1, 1.5], [1]], | |
[[6.1, 2.6, 5.6, 1.4], [1]], | |
[[7.7, 3.0, 6.1, 2.3], [1]], | |
[[6.3, 3.4, 5.6, 2.4], [1]], | |
[[6.4, 3.1, 5.5, 1.8], [1]], | |
[[6.0, 3.0, 4.8, 1.8], [1]], | |
[[6.9, 3.1, 5.4, 2.1], [1]], | |
[[6.7, 3.1, 5.6, 2.4], [1]], | |
[[6.9, 3.1, 5.1, 2.3], [1]], | |
[[5.8, 2.7, 5.1, 1.9], [1]], | |
[[6.8, 3.2, 5.9, 2.3], [1]], | |
[[6.7, 3.3, 5.7, 2.5], [1]], | |
[[6.7, 3.0, 5.2, 2.3], [1]], | |
[[6.3, 2.5, 5.0, 1.9], [1]], | |
[[6.5, 3.0, 5.2, 2.0], [1]], | |
[[6.2, 3.4, 5.4, 2.3], [1]], | |
[[5.9, 3.0, 5.1, 1.8], [1]] | |
]; | |
var nn = gnn(iris, 1, 20, 1000, Infinity, error_rmse, 0.00); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment