var data, labels, N; var ss = 50.0; // scale for drawing // create neural net var layer_defs, net, trainer; var t = "\n\ layer_defs = [];\n\ layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:2});\n\ layer_defs.push({type:'fc', num_neurons:6, activation: 'tanh'});\n\ layer_defs.push({type:'fc', num_neurons:2, activation: 'tanh'});\n\ layer_defs.push({type:'softmax', num_classes:2});\n\ \n\ net = new convnetjs.Net();\n\ net.makeLayers(layer_defs);\n\ \n\ trainer = new convnetjs.SGDTrainer(net, {learning_rate:0.01, momentum:0.1, batch_size:10, l2_decay:0.001});\n\ "; function reload() { eval($("#layerdef").val()); // enter buttons for layers var t = ''; for(var i=1;i"; } $("#layer_ixes").html(t); $("#button"+lix).css('background-color', '#FFA'); $("#cyclestatus").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer with index ' + lix + ' (' + net.layers[lix].layer_type + ')'); } function updateLix(newlix) { $("#button"+lix).css('background-color', ''); // erase highlight lix = newlix; d0 = 0; d1 = 1; // reset these $("#button"+lix).css('background-color', '#FFA'); $("#cyclestatus").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer with index ' + lix + ' (' + net.layers[lix].layer_type + ')'); } function myinit() { } function random_data(){ data = []; labels = []; for(var k=0;k<40;k++) { data.push([convnetjs.randf(-3,3), convnetjs.randf(-3,3)]); labels.push(convnetjs.randf(0,1) > 0.5 ? 1 : 0); } N = labels.length; } function original_data(){ data = []; labels = []; data.push([-0.4326 , 1.1909 ]); labels.push(1); data.push([3.0, 4.0]); labels.push(1); data.push([0.1253 , -0.0376 ]); labels.push(1); data.push([0.2877 , 0.3273 ]); labels.push(1); data.push([-1.1465 , 0.1746 ]); labels.push(1); data.push([1.8133 , 1.0139 ]); labels.push(0); data.push([2.7258 , 1.0668 ]); labels.push(0); data.push([1.4117 , 0.5593 ]); labels.push(0); data.push([4.1832 , 0.3044 ]); labels.push(0); data.push([1.8636 , 0.1677 ]); labels.push(0); data.push([0.5 , 3.2 ]); labels.push(1); data.push([0.8 , 3.2 ]); labels.push(1); data.push([1.0 , -2.2 ]); labels.push(1); N = labels.length; } function circle_data() { data = []; labels = []; for(var i=0;i<50;i++) { var r = convnetjs.randf(0.0, 2.0); var t = convnetjs.randf(0.0, 2*Math.PI); data.push([r*Math.sin(t), r*Math.cos(t)]); labels.push(1); } for(var i=0;i<50;i++) { var r = convnetjs.randf(3.0, 5.0); //var t = convnetjs.randf(0.0, 2*Math.PI); var t = 2*Math.PI*i/50.0 data.push([r*Math.sin(t), r*Math.cos(t)]); labels.push(0); } N = data.length; } function spiral_data() { data = []; labels = []; var n = 100; for(var i=0;i= selected_layer.out_depth) d1 = 0; // and wrap if(d0 >= selected_layer.out_depth) d0 = 0; // and wrap $("#cyclestatus").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer #' + lix + ' (' + net.layers[lix].layer_type + ')'); } var lix = 4; // layer id to track first 2 neurons of var d0 = 0; // first dimension to show visualized var d1 = 1; // second dimension to show visualized function draw(){ ctx.clearRect(0,0,WIDTH,HEIGHT); var netx = new convnetjs.Vol(1,1,2); // draw decisions in the grid var density= 5.0; var gridstep = 2; var gridx = []; var gridy = []; var gridl = []; for(var x=0.0, cx=0; x<=WIDTH; x+= density, cx++) { for(var y=0.0, cy=0; y<=HEIGHT; y+= density, cy++) { //var dec= svm.marginOne([(x-WIDTH/2)/ss, (y-HEIGHT/2)/ss]); netx.w[0] = (x-WIDTH/2)/ss; netx.w[1] = (y-HEIGHT/2)/ss; var a = net.forward(netx, false); if(a.w[0] > a.w[1]) ctx.fillStyle = 'rgb(250, 150, 150)'; else ctx.fillStyle = 'rgb(150, 250, 150)'; //ctx.fillStyle = 'rgb(150,' + Math.floor(a.w[0]*105)+150 + ',150)'; //ctx.fillStyle = 'rgb(' + Math.floor(a.w[0]*255) + ',' + Math.floor(a.w[1]*255) + ', 0)'; ctx.fillRect(x-density/2-1, y-density/2-1, density+2, density+2); if(cx%gridstep === 0 && cy%gridstep===0) { // record the transformation information var xt = net.layers[lix].out_act.w[d0]; // in screen coords var yt = net.layers[lix].out_act.w[d1]; // in screen coords gridx.push(xt); gridy.push(yt); gridl.push(a.w[0] > a.w[1]); // remember final label as well } } } // draw axes ctx.beginPath(); ctx.strokeStyle = 'rgb(50,50,50)'; ctx.lineWidth = 1; ctx.moveTo(0, HEIGHT/2); ctx.lineTo(WIDTH, HEIGHT/2); ctx.moveTo(WIDTH/2, 0); ctx.lineTo(WIDTH/2, HEIGHT); ctx.stroke(); // draw representation transformation axes for two neurons at some layer var mmx = cnnutil.maxmin(gridx); var mmy = cnnutil.maxmin(gridy); visctx.clearRect(0,0,visWIDTH,visHEIGHT); visctx.strokeStyle = 'rgb(0, 0, 0)'; var n = Math.floor(Math.sqrt(gridx.length)); // size of grid. Should be fine? var ng = gridx.length; var c = 0; // counter visctx.beginPath() for(var x=0;x= 0 && ix2 >= 0 && ix1 < ng && ix2 < ng && y= 0 && ix2 >= 0 && ix1 < ng && ix2 < ng && x =0) { console.log('splicing ' + mink); data.splice(mink, 1); labels.splice(mink, 1); N -= 1; } } else { // add datapoint at location of click data.push([xt, yt]); labels.push(shiftPressed ? 1 : 0); N += 1; } } function keyDown(key){ } function keyUp(key) { } $(function() { // note, globals viscanvas = document.getElementById('viscanvas'); visctx = viscanvas.getContext('2d'); visWIDTH = viscanvas.width; visHEIGHT = viscanvas.height; circle_data(); $("#layerdef").val(t); reload(); NPGinit(20); });