-
Notifications
You must be signed in to change notification settings - Fork 0
/
Network.js
103 lines (79 loc) · 3.44 KB
/
Network.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
93
94
95
96
97
98
99
100
101
102
103
const sigmoidPrime = require("sigmoid-prime");
const matrix = require("node-matrix");
const fs = require("fs");
const imageParser = require("./imageParser");
module.exports = class Network {
constructor(layers) {
this.layers = layers;
this.outputLayer = this.layers[this.layers.length - 1];
this.hiddenLayer = this.layers[0];
this.rate = 0.07;
}
run(inputs) {
let currentInput = inputs;
this.layers.forEach(layer => {
currentInput = layer.run(currentInput);
});
return currentInput;
}
train(inputs, desiredOutput) {
const output = this.run(inputs);
const error = output.map((o, i) => desiredOutput[i] - o);
let deltaHiddenLayer = this.outputLayer.neurons.map((n, i) => n.weights.map(w => w * error[i]));
let deltaHiddenLayerSum = [];
deltaHiddenLayer[0].forEach((x, i) => {
deltaHiddenLayerSum[i] = 0;
deltaHiddenLayer.forEach((a, b) => {
deltaHiddenLayerSum[i] += deltaHiddenLayer[b][i];
});
});
let hiddenWeights = this.hiddenLayer.neurons.map((n, neuronIndex) => n.weights.map((w, weightIndex) => w + this.rate * deltaHiddenLayerSum[neuronIndex] * sigmoidPrime(n.neuronSum) * inputs[weightIndex]));
let outputWeights = this.outputLayer.neurons.map((n, neuronIndex) => n.weights.map((w, weightIndex) => w + this.rate * error[neuronIndex] * sigmoidPrime(n.neuronSum) * this.hiddenLayer.getResults()[weightIndex]));
for(let i = 0; i < this.hiddenLayer.neurons.length; i++) {
this.hiddenLayer.neurons[i].weights = hiddenWeights[i];
}
for(let i = 0; i < this.outputLayer.neurons.length; i++) {
this.outputLayer.neurons[i].weights = outputWeights[i];
}
return {
error: error.reduce((a, b) => a + b) / error.length
};
}
save(iteration) {
const networkConfig = {
rate: this.rate,
hidden: {
weights: this.hiddenLayer.neurons.map(n => n.weights),
biases: this.hiddenLayer.neurons.map(n => n.bias)
},
output: {
weights: this.outputLayer.neurons.map(n => n.weights),
biases: this.outputLayer.neurons.map(n => n.bias)
},
iteration: iteration
};
fs.writeFileSync("config.json", JSON.stringify(networkConfig));
}
test() {
const testImages = imageParser.parse(false);
let errorsNumber = 0;
for(let i = 0; i < testImages.length; i++) {
console.log(" Entry: " + i + " of " + testImages.length + " Errors: " + errorsNumber);
let result = this.run(testImages[i].entry).map(x => Math.round(x)).findIndex(x => x === 1);
if(result !== testImages[i].result) errorsNumber += 1;
}
return errorsNumber;
}
load() {
const config = JSON.parse(fs.readFileSync("config.json", "utf8"));
this.hiddenLayer.neurons.forEach((n,ni) => {
this.hiddenLayer.neurons[ni].weights = config.hidden.weights[ni];
this.hiddenLayer.neurons[ni].bias = config.hidden.biases[ni];
});
this.outputLayer.neurons.forEach((n,ni) => {
this.outputLayer.neurons[ni].weights = config.output.weights[ni];
this.outputLayer.neurons[ni].bias = config.output.biases[ni];
});
return config.iteration;
}
};