Skip to content

Commit

Permalink
Add ANN
Browse files Browse the repository at this point in the history
  • Loading branch information
U1F30C committed Nov 26, 2020
1 parent 7584a5f commit 42a6a93
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/ai/ann/Layer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Neuron } from "./../utils/Neuron";

function Layer([size, activation]) {
let layer = {
neurons: Array.from(Array(size)).map((_) => Neuron(1, activation)),
error: Infinity,
predict,
};
function predict(inputs) {
layer.output = layer.neurons.map((neuron) => neuron.predict(inputs));
return layer.output;
}
return layer;
}

export { Layer };
25 changes: 25 additions & 0 deletions src/ai/ann/Network.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Layer } from './Layer';
import { delta, mse } from './math';
import { sum } from 'lodash';

function Network(layerDescriptors, learningRate = 0.5) {
let layers = [];
layers = layerDescriptors.map(Layer);

const network = {
layers,
forward,
};

function forward(inputs) {
const layerOutputs = [layers[0].predict(inputs)];
layers.slice(1).forEach(layer => {
layerOutputs.push(layer.predict(layerOutputs.slice(-1)[0]));
});
return layerOutputs.slice(-1)[0];
}

return network;
}

export { Network };
38 changes: 38 additions & 0 deletions src/ai/ann/Neuron.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { dot, activations } from "./math";
import { times } from "lodash";

function Neuron(inputQuantity = 1, type = "linear") {
let weights = times(inputQuantity + 1, Math.random);
let neuron = {
weights,
predict,
adjust,
inputs: null,
output: null,
deltaFunction: activations[type].delta,
};

function _predict(inputs) {
return dot(neuron.weights, inputs);
}

function predict(inputs) {
inputs = [...inputs, -1];
while (inputs.length > neuron.weights.length)
neuron.weights.push(Math.random());
neuron.inputs = inputs;
neuron.output = activations[type].function(_predict(inputs));

return neuron.output;
}

function adjust(delta) {
for (let i = 0; i < neuron.weights.length; i++) {
neuron.weights[i] += delta * neuron.inputs[i];
}
}

return neuron;
}

export { Neuron };
69 changes: 69 additions & 0 deletions src/ai/ann/math.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { sumBy } from "lodash";

function dot(v1, v2) {
let result = 0;
for (let i = 0; i < v1.length; i++) {
result += v1[i] * v2[i];
}
return result;
}

function generateLine(neuron) {
const [w1, w2] = neuron.weights;
const bias = neuron.bias;
// y = b/w2 - w1x1/w2
let leftLimit = -2,
rightLimit = 3;

let p1 = { x: leftLimit, y: bias / w2 - (w1 * leftLimit) / w2 };
let p2 = { x: rightLimit, y: bias / w2 - (w1 * rightLimit) / w2 };
return [p1, p2];
}

function mse(arr) {
return sumBy(arr, (x) => Math.pow(x, 2)) / arr.length;
}

const activations = {
step: {
function: function (output) {
return output > 0 ? 1 : 0;
},
delta: null,
},
sigmoid: {
function: function (output) {
const ex = Math.exp(-output);
return 1 / (ex + 1);
},
delta: function (output, error) {
return output * (1 - output) * error;
},
},
relu: {
function: function (output) {
return Math.max(0, output);
},
delta: function (output, error) {
return (output < 0 ? 0 : 1) * error;
},
},
lrelu: {
function: function (output) {
return Math.max(0.1 * output, output);
},
delta: function (output, error) {
return (output < 0 ? 0.1 : 1) * error;
},
},
linear: {
function: function (output) {
return output;
},
delta: function (output, error) {
return 1 * error;
},
},
};

export { dot, activations, mse };

0 comments on commit 42a6a93

Please sign in to comment.