forked from chesles/perceptron
-
Notifications
You must be signed in to change notification settings - Fork 0
/
perceptron.js
92 lines (77 loc) · 2.3 KB
/
perceptron.js
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
function Perceptron(opts) {
if (this === global) return new Perceptron(opts);
if (!opts) opts = {}
var debug = 'debug' in opts ? opts.debug : false;
var weights = 'weights' in opts
? opts.weights.slice()
: []
var threshold = 'threshold' in opts
? opts.threshold
: 1
var learningrate;
if (!('learningrate' in opts)) {
learningrate = 0.1
}
else {
learningrate = opts.learningrate
}
var data = []
var api = {
weights: weights,
retrain: function() {
var length = data.length
var success = true
for(var i=0; i<length; i++) {
var training = data.shift()
success = api.train(training.input, training.target) && success
}
return success
},
train: function(inputs, expected) {
while (weights.length < inputs.length) {
weights.push(Math.random())
}
// add a bias weight for the threshold
if (weights.length == inputs.length) {
weights.push('bias' in opts ? opts.bias : 1)
}
var result = api.perceive(inputs)
data.push({input: inputs, target: expected, prev: result})
if (debug) console.log('> training %s, expecting: %s got: %s', inputs, expected, result)
if (result == expected) {
return true
}
else {
if (debug) console.log('> adjusting weights...', weights, inputs);
for(var i=0; i < weights.length; i++) {
var input = (i == inputs.length)
? threshold
: inputs[i]
api.adjust(result, expected, input, i)
}
if (debug) console.log(' -> weights:', weights)
return false
}
},
adjust: function(result, expected, input, index) {
var d = api.delta(result, expected, input, learningrate);
weights[index] += d;
if (isNaN(weights[index])) throw new Error('weights['+index+'] went to NaN!!')
},
delta: function(actual, expected, input, learnrate) {
return (expected - actual) * learnrate * input
},
perceive: function(inputs, net) {
var result = 0
for(var i=0; i<inputs.length; i++) {
result += inputs[i] * weights[i]
}
result += threshold * weights[weights.length - 1]
return net
? result
: result > 0 ? 1 : 0
},
}
return api;
}
module.exports = Perceptron