Skip to content

Commit 3bff650

Browse files
feat(ts): add initial typescript implementation
1 parent a56e41e commit 3bff650

4 files changed

Lines changed: 125 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { sigmoid } from "./utils";
2+
3+
class hidden_layer_neuron {
4+
activation: number;
5+
weights_prev_layer: number[];
6+
bias: number;
7+
constructor(prev_layer_neurons: number) {
8+
this.activation = 0;
9+
this.weights_prev_layer = Array.from({ length: prev_layer_neurons }, () =>
10+
Math.random(),
11+
);
12+
this.bias = 0;
13+
}
14+
calculate_activation(inputs: number[]) {
15+
let z = 0;
16+
inputs.forEach((x, i) => {
17+
z += x * this.weights_prev_layer[i];
18+
});
19+
z += this.bias;
20+
this.activation = sigmoid(z);
21+
}
22+
}
23+
24+
class hidden_layer {
25+
neurons: hidden_layer_neuron[];
26+
constructor(neurons_count: number, prev_layer_neurons: number) {
27+
this.neurons = Array.from(
28+
{ length: neurons_count },
29+
() => new hidden_layer_neuron(prev_layer_neurons),
30+
);
31+
}
32+
33+
forward(input: number[]) {
34+
this.neurons.forEach((neuron) => neuron.calculate_activation(input));
35+
}
36+
get_last_layer_activations() {
37+
return this.neurons.map((n) => n.activation);
38+
}
39+
}
40+
41+
class out_layer_neuron {
42+
activation: number;
43+
z: number;
44+
weights_prev_layer: number[];
45+
bias: number;
46+
47+
constructor(prev_layer_neurons_count: number) {
48+
this.weights_prev_layer = Array.from(
49+
{ length: prev_layer_neurons_count },
50+
() => Math.random(),
51+
);
52+
this.activation = 0;
53+
this.z = 0;
54+
this.bias = 0;
55+
}
56+
57+
calculate_z(input: number[]) {
58+
input.forEach((x, i) => {
59+
this.z += x * this.weights_prev_layer[i];
60+
});
61+
this.z += this.bias;
62+
}
63+
}
64+
65+
class out_layer {
66+
neurons: out_layer_neuron[];
67+
68+
constructor(neurons_count: number, prev_layer_neurons_count: number) {
69+
this.neurons = Array.from(
70+
{ length: neurons_count },
71+
() => new out_layer_neuron(prev_layer_neurons_count),
72+
);
73+
}
74+
75+
calculate_activation(input: number[]) {
76+
let sum_of_z_exp = 0;
77+
this.neurons.forEach((neuron) => {
78+
neuron.calculate_z(input);
79+
sum_of_z_exp += Math.exp(neuron.z);
80+
});
81+
82+
this.neurons.forEach((neuron) => {
83+
neuron.activation = Math.exp(neuron.z) / sum_of_z_exp;
84+
});
85+
}
86+
}
87+
88+
export class MLP {
89+
hidden_layers: hidden_layer[];
90+
output_layer: out_layer;
91+
constructor(
92+
input_layer_size: number,
93+
hidden_layer_sizes: number[],
94+
out_layer_size: number,
95+
) {
96+
this.hidden_layers = hidden_layer_sizes.map(
97+
(size, i) =>
98+
new hidden_layer(size, hidden_layer_sizes[i - 1] || input_layer_size),
99+
);
100+
this.output_layer = new out_layer(
101+
out_layer_size,
102+
hidden_layer_sizes[hidden_layer_sizes.length - 1],
103+
);
104+
}
105+
106+
forward_propogation(input: number[]) {
107+
this.hidden_layers.forEach((layer) => layer.forward(input));
108+
109+
let last_hidden_layer_activations =
110+
this.hidden_layers[
111+
this.hidden_layers.length - 1
112+
].get_last_layer_activations();
113+
this.output_layer.calculate_activation(last_hidden_layer_activations);
114+
return this.output_layer.neurons.map((n) => n.activation);
115+
}
116+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { MLP } from "./NeuralNet";
2+
3+
let model = new MLP(10, [23, 443, 12], 3);
4+
5+
let output = model.forward_propogation([23, 43, 23, 12, 4, 54, 23, 43, 12, 3]);
6+
console.log(output);

try1 (OOP Approach)/typescript/synthetic_data.ts

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function sigmoid(x: number) {
2+
return 1 / (1 + Math.exp(-x));
3+
}

0 commit comments

Comments
 (0)