Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Unroll loops and data within toFunction() #68

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 35 additions & 20 deletions lib/neuralnetwork.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,27 +370,42 @@ NeuralNetwork.prototype = {
return this;
},

toFunction: function() {
var json = this.toJSON();
toFunction: function() {
// return standalone function that mimics run()
return new Function("input",
' var net = ' + JSON.stringify(json) + ';\n\n\
for (var i = 1; i < net.layers.length; i++) {\n\
var layer = net.layers[i];\n\
var output = {};\n\
\n\
for (var id in layer) {\n\
var node = layer[id];\n\
var sum = node.bias;\n\
\n\
for (var iid in node.weights) {\n\
sum += node.weights[iid] * input[iid];\n\
}\n\
output[id] = (1 / (1 + Math.exp(-sum)));\n\
}\n\
input = output;\n\
}\n\
return output;');

var layers = this.toJSON().layers;
// we start with 'input', but will use each layer as the next input
var input = 'input';

// NOTE: keys are sorted so as to guarantee a consistent order and matching
// key-to-index, as indexes are used to generate variable names
return new Function(input, [].concat(
_.map(_.keys(layers[0]).sort(), function(iid, i) {
// collect our inputs as variables
// e.g. var input_0 = input['x'];
return 'var ' + input + '_' + i + ' = ' + input + '[' + JSON.stringify(iid) + '];';
}),
_.map(layers.slice(1), function(layer, i) {
var output = 'output' + i;
var result = _.map(_.keys(layer).sort(), function(id, j) {
var node = layer[id];
// e.g. bias + (weight_0 * inputX_0) + (weight_1 * inputX_1) + ...
var sum = [
JSON.stringify(node.bias)
].concat(_.map(_.keys(node.weights).sort(), function(iid, k) {
return JSON.stringify(node.weights[iid]) + ' * ' + input + '_' + k;
})).join(' + ');
return 'var ' + output + '_' + j + ' = (1 / (1 + Math.exp(-(' + sum + '))));';
}).join('\n');
input = output;
return result;
}), [
// finally, return the resultant object, which consists of the values of our last layer
// e.g. return {a: outputX_0, b: outputX_1, c: outputX_2};
'return {' + _.map(_.keys(layers[layers.length - 1]).sort(), function(id, j) {
return JSON.stringify(id) + ': ' + input + '_' + j;
}).join(', ') + '};'
]).join('\n'));
},

// This will create a TrainStream (WriteStream)
Expand Down