6
6
* license: MIT (http://opensource.org/licenses/MIT)
7
7
* author: Heather Arthur <
[email protected] >
8
8
* homepage: https://github.com/brainjs/brain.js#readme
9
- * version: 1.0.0
9
+ * version: 1.0.1
10
10
*
11
11
* acorn:
12
12
* license: MIT (http://opensource.org/licenses/MIT)
@@ -451,15 +451,14 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
451
451
452
452
/**
453
453
*
454
- * @param {} sizes
455
- * @param {Boolean} keepNetworkIntact
454
+ * @param {Number[]} sizes
456
455
*/
457
456
458
457
459
458
_createClass(NeuralNetworkGPU, [{
460
459
key: 'initialize',
461
- value: function initialize(sizes, keepNetworkIntact ) {
462
- _get(NeuralNetworkGPU.prototype.__proto__ || Object.getPrototypeOf(NeuralNetworkGPU.prototype), 'initialize', this).call(this, sizes, keepNetworkIntact );
460
+ value: function initialize(sizes) {
461
+ _get(NeuralNetworkGPU.prototype.__proto__ || Object.getPrototypeOf(NeuralNetworkGPU.prototype), 'initialize', this).call(this, sizes);
463
462
this.buildRunInput();
464
463
this.buildCalculateDeltas();
465
464
this.buildGetChanges();
@@ -514,14 +513,13 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
514
513
}
515
514
516
515
for (var layer = 1; layer <= this.outputLayer; layer++) {
517
- var kernel = this.gpu.createKernelMap({ weightedSum: _gpu2.default.alias('weightedSum', weightedSum) }, function (weights, biases, inputs) {
518
- return weightedSum(weights, biases, this.thread.x, inputs);
519
- }, {
516
+ this.forwardPropagate[layer] = this.gpu.createKernel( weightedSum, {
517
+ output: [ this.sizes[layer]],
518
+ outputToTexture: true,
520
519
constants: {
521
520
size: this.sizes[layer - 1]
522
521
}
523
- }).setOutput([this.sizes[layer]]).setOutputToTexture(true);
524
- this.forwardPropagate[layer] = kernel;
522
+ });
525
523
}
526
524
}
527
525
@@ -537,7 +535,7 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
537
535
var output = void 0;
538
536
this.outputs[0] = input;
539
537
for (var layer = 1; layer <= this.outputLayer; layer++) {
540
- this.outputs[layer] = this.forwardPropagate[layer](this.weights[layer], this.biases[layer], input).result ;
538
+ this.outputs[layer] = this.forwardPropagate[layer](this.weights[layer], this.biases[layer], input);
541
539
542
540
output = input = this.outputs[layer];
543
541
}
@@ -567,29 +565,30 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
567
565
568
566
for (var layer = this.outputLayer; layer > 0; layer--) {
569
567
if (layer === this.outputLayer) {
570
- var kernel = this.gpu.createKernelMap({
571
- error: _gpu2.default.alias('calcError ', calcError ),
568
+ this.backwardPropagate[layer] = this.gpu.createKernelMap({
569
+ error: _gpu2.default.alias('calcErrorOutput ', calcErrorOutput ),
572
570
deltas: _gpu2.default.alias('calcDeltas', calcDeltas)
573
- }, function (outputs, target ) {
571
+ }, function (outputs, targets ) {
574
572
var output = outputs[this.thread.x];
575
- return calcDeltas(calcError(output, target), output);
576
- }).setOutput([this.sizes[layer]]).setOutputToTexture(true);
577
-
578
- this.backwardPropagate[layer] = kernel;
573
+ return calcDeltas(calcErrorOutput(output, targets), output);
574
+ }, {
575
+ output: [this.sizes[layer]],
576
+ outputToTexture: true
577
+ });
579
578
} else {
580
- var _kernel = this.gpu.createKernelMap({
581
- error: _gpu2.default.alias('calcErrorOutput ', calcErrorOutput ),
579
+ this.backwardPropagate[layer] = this.gpu.createKernelMap({
580
+ error: _gpu2.default.alias('calcError ', calcError ),
582
581
deltas: _gpu2.default.alias('calcDeltas', calcDeltas)
583
582
}, function (nextWeights, outputs, nextDeltas) {
584
583
var output = outputs[this.thread.x];
585
- return calcDeltas(calcErrorOutput (nextWeights, nextDeltas), output);
584
+ return calcDeltas(calcError (nextWeights, nextDeltas), output);
586
585
}, {
586
+ output: [this.sizes[layer]],
587
+ outputToTexture: true,
587
588
constants: {
588
589
size: this.deltas[layer + 1].length
589
590
}
590
- }).setOutput([this.sizes[layer]]).setOutputToTexture(true);
591
-
592
- this.backwardPropagate[layer] = _kernel;
591
+ });
593
592
}
594
593
}
595
594
}
@@ -604,27 +603,28 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
604
603
output = this.backwardPropagate[layer](this.weights[layer + 1], this.outputs[layer], this.deltas[layer + 1]);
605
604
}
606
605
607
- this.deltas[layer] = output.result ;
606
+ this.deltas[layer] = output.deltas ;
608
607
this.errors[layer] = output.error;
609
608
}
610
609
}
611
610
}, {
612
611
key: 'buildGetChanges',
613
612
value: function buildGetChanges() {
614
613
for (var layer = 1; layer <= this.outputLayer; layer++) {
615
- var kernel = this.gpu.createKernelMap({
616
- addWeights: addWeights, calcChanges: calcChanges }, function (previousOutputs, deltas, weights, changes, learningRate, momentum) {
617
- var delta = deltas[this.thread.y];
618
- var change = calcChanges(changes, delta, previousOutputs, learningRate, momentum, this.thread.x, this.thread.y);
614
+ this.changesPropagate[layer] = this.gpu.createKernelMap({
615
+ weights: _gpu2.default.alias('addWeights', addWeights),
616
+ changes: _gpu2.default.alias('calcChanges', calcChanges)
617
+ }, function (previousOutputs, deltas, weights, changes, learningRate, momentum) {
618
+ var change = calcChanges(changes, deltas, previousOutputs, learningRate, momentum);
619
619
620
- return addWeights(change, weights, this.thread.x, this.thread.y );
620
+ return addWeights(change, weights);
621
621
}, {
622
+ output: [this.sizes[layer - 1], this.sizes[layer]],
623
+ outputToTexture: true,
622
624
constants: {
623
625
size: this.outputs[layer - 1].length
624
626
}
625
- }).setOutput([this.sizes[layer - 1], this.sizes[layer]]).setOutputToTexture(true);
626
-
627
- this.changesPropagate[layer] = kernel;
627
+ });
628
628
}
629
629
}
630
630
}, {
@@ -633,41 +633,36 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
633
633
for (var layer = 1; layer <= this.outputLayer; layer++) {
634
634
var output = this.changesPropagate[layer](this.outputs[layer - 1], this.deltas[layer], this.weights[layer], this.changes[layer], learningRate, this.momentum);
635
635
636
- this.changes[layer] = output.calcChanges ;
637
- this.weights[layer] = output.result ;
636
+ this.changes[layer] = output.changes ;
637
+ this.weights[layer] = output.weights ;
638
638
}
639
639
}
640
640
}, {
641
641
key: 'buildChangeBiases',
642
642
value: function buildChangeBiases() {
643
643
for (var layer = 1; layer <= this.outputLayer; layer++) {
644
- var kernel = this.gpu.createKernelMap({
645
- addBiases: addBiases
646
- }, function (biases, deltas, learningRate) {
647
- return addBiases(biases, deltas, learningRate, this.thread.x);
648
- }).setOutput([this.sizes[layer]]).setOutputToTexture(true);
649
-
650
- this.biasesPropagate[layer] = kernel;
644
+ this.biasesPropagate[layer] = this.gpu.createKernel(addBiases, {
645
+ output: [this.sizes[layer]],
646
+ outputToTexture: true
647
+ });
651
648
}
652
649
}
653
650
}, {
654
651
key: 'changeBiases',
655
652
value: function changeBiases(learningRate) {
656
653
for (var layer = 1; layer <= this.outputLayer; layer++) {
657
- var output = this.biasesPropagate[layer](this.biases[layer], this.deltas[layer], learningRate);
658
- this.biases[layer] = output.result;
654
+ this.biases[layer] = this.biasesPropagate[layer](this.biases[layer], this.deltas[layer], learningRate);
659
655
}
660
656
}
661
657
}, {
662
658
key: 'buildGetMSE',
663
659
value: function buildGetMSE() {
664
- var kernel = this.gpu.createKernel(mse, {
660
+ this.getMSE = this.gpu.createKernel(mse, {
665
661
output: [1],
666
662
constants: {
667
663
size: this.outputLayer
668
664
}
669
665
});
670
- this.getMSE = kernel;
671
666
}
672
667
673
668
/**
@@ -747,44 +742,44 @@ var NeuralNetworkGPU = function (_NeuralNetwork) {
747
742
exports.default = NeuralNetworkGPU;
748
743
749
744
750
- function weightedSumSigmoid(weights, biases, x, inputs) {
751
- var sum = biases[x];
745
+ function weightedSumSigmoid(weights, biases, inputs) {
746
+ var sum = biases[this.thread. x];
752
747
for (var k = 0; k < this.constants.size; k++) {
753
- sum += weights[x][k] * inputs[k];
748
+ sum += weights[this.thread. x][k] * inputs[k];
754
749
}
755
750
//sigmoid
756
751
return 1 / (1 + Math.exp(-sum));
757
752
}
758
753
759
- function weightedSumRelu(weights, biases, x, inputs) {
760
- var sum = biases[x];
754
+ function weightedSumRelu(weights, biases, inputs) {
755
+ var sum = biases[this.thread. x];
761
756
for (var k = 0; k < this.constants.size; k++) {
762
- sum += weights[x][k] * inputs[k];
757
+ sum += weights[this.thread. x][k] * inputs[k];
763
758
}
764
759
//relu
765
760
return sum < 0 ? 0 : sum;
766
761
}
767
762
768
- function weightedSumLeakyRelu(weights, biases, x, inputs) {
769
- var sum = biases[x];
763
+ function weightedSumLeakyRelu(weights, biases, inputs) {
764
+ var sum = biases[this.thread. x];
770
765
for (var k = 0; k < this.constants.size; k++) {
771
- sum += weights[x][k] * inputs[k];
766
+ sum += weights[this.thread. x][k] * inputs[k];
772
767
}
773
768
//leaky relu
774
769
return sum < 0 ? 0 : 0.01 * sum;
775
770
}
776
771
777
- function weightedSumTanh(weights, biases, x, inputs) {
778
- var sum = biases[x];
772
+ function weightedSumTanh(weights, biases, inputs) {
773
+ var sum = biases[this.thread. x];
779
774
for (var k = 0; k < this.constants.size; k++) {
780
- sum += weights[x][k] * inputs[k];
775
+ sum += weights[this.thread. x][k] * inputs[k];
781
776
}
782
777
//tanh
783
778
return Math.tanh(sum);
784
779
}
785
780
786
- function calcError(outputs, target ) {
787
- return target [this.thread.x] - outputs ;
781
+ function calcErrorOutput(output, targets ) {
782
+ return targets [this.thread.x] - output ;
788
783
}
789
784
790
785
function calcDeltasSigmoid(error, output) {
@@ -807,28 +802,24 @@ function calcDeltasTanh(error, output) {
807
802
return (1 - output * output) * error;
808
803
}
809
804
810
- function calcErrorOutput (nextWeights, nextDeltas) {
805
+ function calcError (nextWeights, nextDeltas) {
811
806
var error = 0;
812
807
for (var k = 0; k < this.constants.size; k++) {
813
808
error += nextDeltas[k] * nextWeights[k][this.thread.x];
814
809
}
815
810
return error;
816
811
}
817
812
818
- function calcChanges(previousChange, deltas, previousOutputs, learningRate, momentum, x, y) {
819
- var sum = 0;
820
- for (var i = 0; i < this.constants.size; i++) {
821
- sum += learningRate * deltas * previousOutputs[x] + momentum * previousChange[y][i];
822
- }
823
- return sum;
813
+ function calcChanges(previousChanges, deltas, previousOutputs, learningRate, momentum) {
814
+ return learningRate * deltas[this.thread.y] * previousOutputs[this.thread.x] + momentum * previousChanges[this.thread.y][this.thread.x];
824
815
}
825
816
826
- function addWeights(change, weights, x, y ) {
827
- return change + weights[y][x];
817
+ function addWeights(change, weights) {
818
+ return change + weights[this.thread. y][this.thread. x];
828
819
}
829
820
830
- function addBiases(biases, deltas, learningRate, x ) {
831
- return biases[x] + deltas[x] * learningRate;
821
+ function addBiases(biases, deltas, learningRate) {
822
+ return biases[this.thread. x] + deltas[this.thread. x] * learningRate;
832
823
}
833
824
834
825
// mean squared error, reimplemented for GPU
@@ -947,7 +938,7 @@ var NeuralNetwork = function () {
947
938
948
939
/**
949
940
*
950
- * @param {} sizes
941
+ * @param {Number[] } sizes
951
942
*/
952
943
953
944
@@ -1559,7 +1550,13 @@ var NeuralNetwork = function () {
1559
1550
}
1560
1551
}
1561
1552
}
1562
- return { layers: layers, outputLookup: !!this.outputLookup, inputLookup: !!this.inputLookup, activation: this.activation };
1553
+ return {
1554
+ sizes: this.sizes,
1555
+ layers: layers,
1556
+ outputLookup: !!this.outputLookup,
1557
+ inputLookup: !!this.inputLookup,
1558
+ activation: this.activation
1559
+ };
1563
1560
}
1564
1561
1565
1562
/**
@@ -1571,13 +1568,7 @@ var NeuralNetwork = function () {
1571
1568
}, {
1572
1569
key: 'fromJSON',
1573
1570
value: function fromJSON(json) {
1574
- var size = json.layers.length;
1575
- this.outputLayer = size - 1;
1576
-
1577
- this.sizes = new Array(size);
1578
- this.weights = new Array(size);
1579
- this.biases = new Array(size);
1580
- this.outputs = new Array(size);
1571
+ this.initialize(json.sizes);
1581
1572
1582
1573
for (var i = 0; i <= this.outputLayer; i++) {
1583
1574
var layer = json.layers[i];
@@ -1586,17 +1577,14 @@ var NeuralNetwork = function () {
1586
1577
} else if (i === this.outputLayer && (!layer[0] || json.outputLookup)) {
1587
1578
this.outputLookup = _lookup2.default.lookupFromHash(layer);
1588
1579
}
1589
-
1590
- var nodes = Object.keys(layer);
1591
- this.sizes[i] = nodes.length;
1592
- this.weights[i] = [];
1593
- this.biases[i] = [];
1594
- this.outputs[i] = [];
1595
-
1596
- for (var j in nodes) {
1597
- var node = nodes[j];
1598
- this.biases[i][j] = layer[node].bias;
1599
- this.weights[i][j] = (0, _toArray2.default)(layer[node].weights);
1580
+ if (layer > 0) {
1581
+ var nodes = Object.keys(layer);
1582
+ this.sizes[i] = nodes.length;
1583
+ for (var j in nodes) {
1584
+ var node = nodes[j];
1585
+ this.biases[i] = layer[node].bias;
1586
+ this.weights[i][j] = (0, _toArray2.default)(layer[node].weights);
1587
+ }
1600
1588
}
1601
1589
}
1602
1590
0 commit comments