Skip to content

Commit

Permalink
nn package
Browse files Browse the repository at this point in the history
  • Loading branch information
Maniae committed Feb 21, 2018
1 parent a9b7670 commit 30f2c76
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Network } from "./neural-network/network";

const mainDiv = document.getElementById("main");
if (mainDiv) {
mainDiv.innerHTML = "Hello World !";
mainDiv.innerHTML = "" + Network.perceptron([3, 4, 1]).activate([1, 0, 1])[0];
}
47 changes: 47 additions & 0 deletions src/neural-network/layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Neuron, NeuronOptions } from "./neuron";

interface LayerOption {
neurons?: Neuron[];
size?: number;
inputsSize?: number;
isInputLayer?: boolean;
}
export class Layer {
private neurons: Neuron[];
private isInputLayer: boolean;

constructor(options: LayerOption = {}) {
this.neurons = options.neurons || [];
this.isInputLayer = options.isInputLayer || false;
if (options.size) {
if (this.neurons.length > 0) {
throw Error("Layer constructor should be called either with a Neuron array OR with a layer size");
}
for (let i = 0; i < options.size; i++) {
const neuronOptions: NeuronOptions = options.isInputLayer ? {weights: [1], activationFunction: (x => x)} : {};
if (options.inputsSize) {
if (options.isInputLayer) {
throw Error("Can't specify neurons inputs size for an input layer");
}
neuronOptions.inputsSize = options.inputsSize;
}
this.neurons.push(new Neuron(neuronOptions));
}
}
}

get size(): number {
return this.neurons.length;
}

activate = (inputs: number[]): number[] => {
if (this.isInputLayer) {
return inputs;
}
const outputs = [];
for (const neuron of this.neurons) {
outputs.push(neuron.activate(inputs));
}
return outputs;
}
}
32 changes: 32 additions & 0 deletions src/neural-network/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Layer } from "./layer";

interface NetworkOption {
layers: Layer[];
}
export class Network {
private layers: Layer[];

static perceptron(layersSizes: number[]) {
return new Network({
layers: layersSizes.reduce((layers: Layer[], size, index: number) => {
layers.push(new Layer({
size,
isInputLayer: index === 0,
inputsSize: index > 0 ? layers[index - 1].size : undefined
}));
return layers;
}, [])
});
}

constructor(options: NetworkOption) {
this.layers = options.layers || [];
}

activate = (inputs: number[]): number[] => {
if (inputs.length !== this.layers[0].size) {
throw Error("Network inputs lenght should match first layer size");
}
return this.layers.reduce((prevOutput: number[], layer) => layer.activate(prevOutput), inputs);
}
}
32 changes: 23 additions & 9 deletions src/neural-network/neuron.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
interface NeuronOptions {

export interface NeuronOptions {
weights?: number[];
activationFunction?: (x: number) => number;
inputsSize?: number;
}

export class Neuron {
private weights: number[] = [];

constructor(options: NeuronOptions) {}
private weights: number[];
private activationFunction: (x: number) => number;

constructor(options: NeuronOptions = {}) {
this.weights = options.weights || [];
this.activationFunction = options.activationFunction || (x => x);
if (options.inputsSize) {
if (options.weights) {
throw Error("Neuron constructor should be called with either a weight array OR with an input size");
}
for (let i = 0; i < options.inputsSize; i++) {
this.setWeight(i, Math.random());
}
}
}

private activate = (inputs: number[]) => {
activate = (inputs: number[]): number => {
if (inputs.length !== this.weights.length) {
throw Error(`expecting an input array of length ${this.weights.length} but array length is ${inputs.length}`)
throw Error(`expecting an input array of length ${this.weights.length} but array length is ${inputs.length}`);
}
const untransferedOutput = inputs.reduce((acc, input, i) => {
return acc + input * this.weights[i];
})
});
return this.activationFunction(untransferedOutput);
}

setWeight = (index: number, weight: number) => {
this.weights[index] = weight;
}
}
}

0 comments on commit 30f2c76

Please sign in to comment.