Skip to content

Instantly share code, notes, and snippets.

@razorthink-com
Last active September 25, 2015 20:23
Show Gist options
  • Save razorthink-com/78367c254e3210d461e8 to your computer and use it in GitHub Desktop.
Save razorthink-com/78367c254e3210d461e8 to your computer and use it in GitHub Desktop.
var input = [ 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0 ];
var expected = [ 1, 0, 1, 0, 0, 0, 1, 1, 1 ];
var hiddenLayers = initHiddenLayers([ 18, 17, 15, 6, expected.length ]);
var neuralLayers = flatten([ [ input ], hiddenLayers ]);
var count = 0;
var start = Date.now();
var neuralNetwork = computeNeuralNet( neuralLayers, expected, [], 0 );
console.log( 'Runtime: ', Date.now() - start, 'ms' );
console.log( 'Layers Computed: ', count );
drawNeuralNetwork( neuralNetwork );
/*----------------------------------------------------*/
function computeNeuralNet( neuralLayers, expectedLayer, weightMatrixStack, stage ) {
count ++;
if ( stage + 1 == neuralLayers.length ) {
return computeNeuralNet( neuralLayers, expectedLayer, weightMatrixStack, 0 );
}
var inputLayer = neuralLayers[ stage ];
var nextLayerInit = neuralLayers[ stage + 1 ];
var weightMatrix = createWeightMatrix( nextLayerInit.length, inputLayer.length );
var nextLayer = weightMatrix.map( function ( weights ) {
return Math.round( sigmoid( neuronWeight( weights, inputLayer ) ) );
});
neuralLayers[ stage + 1 ] = nextLayer;
weightMatrixStack[ stage ] = weightMatrix;
if ( arrayCompare( neuralLayers[ neuralLayers.length - 1 ], expectedLayer ) ) {
return { layers: neuralLayers, weights: weightMatrixStack };
}
return computeNeuralNet( neuralLayers, expectedLayer, weightMatrixStack, stage + 1 );
}
function flatten( arr ) {
return [].concat.apply( [], arr )
}
function arrayOfSize( size, n ) {
n = n || 0;
return ( new Array(size + 1) ).join('0').split('')
.map(function (_) {
return n
});
}
function createMatrix( m, n, fn ) {
return arrayOfSize( m ).map( function ( row, rowIndex ) {
return arrayOfSize( n ).map( function ( col, colIndex ) {
return fn() || 0;
} );
} );
}
function arrayCompare(arr1, arr2) {
return arr1.every(function (n, index) {
return ( n == arr2[index] );
});
}
function randomNumber() {
var n = Math.round(Math.random() * 100) / 10;
return Math.round(Math.random() * 10) * ( Math.round(n) % 2 == 0 ) ? n : -n;
}
function initHiddenLayers(hiddenLayerCounts) {
return arrayOfSize(hiddenLayerCounts.length)
.map(function (__, index) {
return arrayOfSize(hiddenLayerCounts[index], 0);
});
}
function sigmoid(n) {
return 1 / ( 1 + Math.pow(Math.E, -n) )
}
function neuronWeight(weights, layer) {
return weights.reduce(function (sum, weight, index) {
return sum + ( weight * layer[index] )
}, 0);
}
function createWeightMatrix(m, n) {
return createMatrix(m, n, randomNumber);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Runner</title>
<script src="d3.v3.min.js"></script>
<style>
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<script src="neural-network-graph.js"></script>
<script src="assisted-learning.js"></script>
</body>
</html>
function drawNeuralNetwork( neuralNetwork ) {
var h = window.innerHeight;
var w = window.innerWidth;
var svg = d3.select( 'body' )
.append( 'svg' )
.attr( 'height', h * 2 )
.attr( 'width', w * 2 );
var layers = neuralNetwork.layers;
var weights = neuralNetwork.weights;
layers.forEach( function ( layer, layerIndex ) {
svg.selectAll( 'svg' )
.data( layer )
.enter()
.append( 'circle' )
.attr( 'class', 'node' )
.attr( 'cx', function ( __, i ) { return ( i + 1 ) * 50 } )
.attr( 'cy', function ( __, i ) { return ( layerIndex + 1 ) * 50 } )
.attr( 'r', 15 )
.attr( 'fill', function ( d ) { return ( d ? '#BDDC36' : '#C5C5C5' ) } )
.on( 'mouseover', function ( d, itemIndex ) {
if ( layerIndex == 0 ) return;
d3.select(this).transition().duration(150).attr('r', 17);
drawWeights( weights[ layerIndex - 1 ][ itemIndex ], layerIndex );
} )
.on( 'mouseout', function ( d ) {
svg.selectAll( 'text' ).remove();
d3.select(this).transition().duration(150).attr('r', 15);
} )
} );
function drawWeights( weights, layerIndex ) {
svg.selectAll( 'text' )
.data( weights )
.enter()
.append( 'text' )
.text( function ( d ) { return d } )
.attr( 'x', function ( __, i ) { return ( ( i + 1 ) * 50 ) - 10 } )
.attr( 'y', function ( __, i ) { return ( layerIndex * 50 ) + 5 } )
.attr("font-family", "sans-serif")
.attr("font-size", "13px")
.attr("fill", "black")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment