UNPKG

4.72 kBJavaScriptView Raw
1/**
2 * Created by joonkukang on 2014. 1. 14..
3 */
4var math = require('./utils').math;
5
6MLP = module.exports = function (settings) {
7 var self = this;
8 self.x = settings['input'];
9 self.y = settings['label'];
10 self.sigmoidLayers = [];
11 self.nLayers = settings['hidden_layer_sizes'].length;
12 self.settings = {
13 'log level' : 1 // 0 : nothing, 1 : info, 2: warn
14 };
15 var i;
16 for(i=0 ; i<self.nLayers+1 ; i++) {
17 var inputSize, layerInput;
18 if(i == 0)
19 inputSize = settings['n_ins'];
20 else
21 inputSize = settings['hidden_layer_sizes'][i-1];
22
23 if(i == 0)
24 layerInput = self.x;
25 else
26 layerInput = self.sigmoidLayers[self.sigmoidLayers.length-1].sampleHgivenV();
27
28 var sigmoidLayer;
29 if(i == self.nLayers) {
30 sigmoidLayer = new HiddenLayer({
31 'input' : layerInput,
32 'n_in' : inputSize,
33 'n_out' : settings['n_outs'],
34 'activation' : math.sigmoid,
35 'W' : (typeof settings['w_array'] === 'undefined')? undefined : settings['w_array'][i],
36 'b' : (typeof settings['b_array'] === 'undefined')? undefined : settings['b_array'][i]
37 });
38 } else {
39 sigmoidLayer = new HiddenLayer({
40 'input' : layerInput,
41 'n_in' : inputSize,
42 'n_out' : settings['hidden_layer_sizes'][i],
43 'activation' : math.sigmoid,
44 'W' : (typeof settings['w_array'] === 'undefined')? undefined : settings['w_array'][i],
45 'b' : (typeof settings['b_array'] === 'undefined')? undefined : settings['b_array'][i]
46 });
47 }
48 self.sigmoidLayers.push(sigmoidLayer);
49 }
50};
51
52MLP.prototype.train = function(settings) {
53 var self = this;
54 var lr = 0.6, epochs = 1000;
55 if(typeof settings['lr'] !== 'undefined')
56 lr = settings['lr'];
57 if(typeof settings['epochs'] !== 'undefined')
58 epochs = settings['epochs'];
59
60
61 var epoch;
62 var currentProgress = 1;
63 for(epoch=0 ; epoch < epochs ; epoch++) {
64
65 // Feed Forward
66 var i;
67 var layerInput = [];
68 layerInput.push(self.x);
69 for(i=0; i<self.nLayers+1 ; i++) {
70 layerInput.push(self.sigmoidLayers[i].output(layerInput[i]));
71 }
72 var output = layerInput[self.nLayers+1];
73 // Back Propagation
74 var delta = new Array(self.nLayers + 1);
75 delta[self.nLayers] = m.mulMatElementWise(m.minusMat(self.y, output),
76 m.activateMat(self.sigmoidLayers[self.nLayers].linearOutput(layerInput[self.nLayers]), m.dSigmoid));
77
78 /*
79 self.nLayers = 3 (3 hidden layers)
80 delta[3] : ouput layer
81 delta[2] : 3rd hidden layer, delta[0] : 1st hidden layer
82 */
83 for(i = self.nLayers - 1; i>=0 ; i--) {
84 delta[i] = m.mulMatElementWise(self.sigmoidLayers[i+1].backPropagate(delta[i+1]),
85 m.activateMat(self.sigmoidLayers[i].linearOutput(layerInput[i]), m.dSigmoid));
86 }
87 // Update Weight, Bias
88 for(var i=0; i<self.nLayers+1 ; i++) {
89 var deltaW = m.activateMat(m.mulMat(m.transpose(layerInput[i]),delta[i]),function(x){return 1. * x / self.x.length;})
90 var deltaB = m.meanMatAxis(delta[i],0);
91 self.sigmoidLayers[i].W = m.addMat(self.sigmoidLayers[i].W,deltaW);
92 self.sigmoidLayers[i].b = m.addVec(self.sigmoidLayers[i].b,deltaB);
93 }
94
95 if(self.settings['log level'] > 0) {
96 var progress = (1.*epoch/epochs)*100;
97 if(progress > currentProgress) {
98 console.log("MLP",progress.toFixed(0),"% Completed.");
99 currentProgress+=8;
100 }
101 }
102 }
103 if(self.settings['log level'] > 0)
104 console.log("MLP Final Cross Entropy : ",self.getReconstructionCrossEntropy());
105};
106
107MLP.prototype.getReconstructionCrossEntropy = function() {
108 var self = this;
109 var reconstructedOutput = self.predict(self.x);
110 var a = math.activateTwoMat(self.y,reconstructedOutput,function(x,y){
111 return x*Math.log(y);
112 });
113
114 var b = math.activateTwoMat(self.y,reconstructedOutput,function(x,y){
115 return (1-x)*Math.log(1-y);
116 });
117
118 var crossEntropy = -math.meanVec(math.sumMatAxis(math.addMat(a,b),1));
119 return crossEntropy
120}
121
122MLP.prototype.predict = function(x) {
123 var self = this;
124 var output = x;
125 for(i=0; i<self.nLayers+1 ; i++) {
126 output = self.sigmoidLayers[i].output(output);
127 }
128 return output;
129};
130
131MLP.prototype.set = function(property,value) {
132 var self = this;
133 self.settings[property] = value;
134}
\No newline at end of file