-
Notifications
You must be signed in to change notification settings - Fork 0
/
neuron.ts
64 lines (54 loc) · 2.03 KB
/
neuron.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { ActFunc } from "./types";
export default class Neuron {
actFunc: ActFunc;
weights: number[];
bias: number;
constructor(actFunc: ActFunc, initialWeights: number[], bias: number) {
this.actFunc = actFunc;
this.weights = initialWeights;
this.bias = bias;
}
/** The value our neuron gives when firing, given these inputs */
eval(inputs: number[]) {
// TODO Validate that inputs.length is same as weights.length
const weightedSumOfInputs = this.weightedSumOfInputs(inputs);
return this.actFunc(weightedSumOfInputs);
}
weightedSumOfInputs(inputs: number[]): number {
return this.weights.reduce(
(acc: number, weight: number, index: number) => (
acc + (weight * inputs[index])
),
0,
) + this.bias;
}
/** See img/math.jpg for the math of what's going on here */
backprop(inputs: number[], desiredOutput: number): number[] {
// (dCost/dWeight)[], slope of our function, where we want it to be 0
const gradientArray: number[] = [];
const actualOutput = this.eval(inputs);
const weightedSum = this.weightedSumOfInputs(inputs);
const actualOutputPerWeightedSum = Math.exp(weightedSum) /
Math.pow(1 + Math.exp(weightedSum), 2);
const costPerActualOutput = 2 * (actualOutput - desiredOutput);
const weightedSumPerBias = 1;
const costPerBias = costPerActualOutput * actualOutputPerWeightedSum *
weightedSumPerBias;
gradientArray.push(costPerBias);
inputs.forEach((input) => {
const weightedSumPerWeight = input;
const costPerWeight = costPerActualOutput * actualOutputPerWeightedSum *
weightedSumPerWeight;
gradientArray.push(costPerWeight);
});
return gradientArray;
}
update(inputs: number[], desiredOutput: number) {
const gradientArray = this.backprop(inputs, desiredOutput);
const [biasGradient, ...weightGradientArray] = gradientArray;
this.bias -= biasGradient * 0.1;
weightGradientArray.forEach((gradient, index) => {
this.weights[index] -= gradient * 0.1;
});
}
}