// globals var layer_defs, net, trainer; var t = "\ layer_defs = [];\n\ layer_defs.push({type:'input', out_sx:28, out_sy:28, out_depth:1});\n\ layer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\n\ layer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\n\ layer_defs.push({type:'fc', num_neurons:2});\n\ layer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\n\ layer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\n\ layer_defs.push({type:'regression', num_neurons:28*28});\n\ \n\ net = new convnetjs.Net();\n\ net.makeLayers(layer_defs);\n\ \n\ trainer = new convnetjs.SGDTrainer(net, {learning_rate:1, method:'adadelta', batch_size:50, l2_decay:0.001, l1_decay:0.001});\n\ "; // ------------------------ // BEGIN MNIST SPECIFIC STUFF // ------------------------ var sample_training_instance = function() { // find an unloaded batch var bi = Math.floor(Math.random()*loaded_train_batches.length); var b = loaded_train_batches[bi]; var k = Math.floor(Math.random()*3000); // sample within the batch var n = b*3000+k; // load more batches over time if(step_num%5000===0 && step_num>0) { for(var i=0;i3) { // actual weights filters_div.appendChild(document.createTextNode('Weights:')); filters_div.appendChild(document.createElement('br')); for(var j=0;j= 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 + ')'); } 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 + ')'); } var lossGraph = new cnnvis.Graph(); var xLossWindow = new cnnutil.Window(100); var w2LossWindow = new cnnutil.Window(100); var w1LossWindow = new cnnutil.Window(100); var step_num = 0; var colors = ["red", "blue", "green", "orange", "magenta", "cyan", "purple", "silver", "olive", "lime", "yellow"]; var step = function(sample) { // train on it with network var stats = trainer.train(sample.x, sample.x.w); // keep track of stats such as the average training error and loss xLossWindow.add(stats.cost_loss); w1LossWindow.add(stats.l1_decay_loss); w2LossWindow.add(stats.l2_decay_loss); // visualize training status var train_elt = document.getElementById("trainstats"); train_elt.innerHTML = ''; var t = 'Forward time per example: ' + stats.fwd_time + 'ms'; train_elt.appendChild(document.createTextNode(t)); train_elt.appendChild(document.createElement('br')); var t = 'Backprop time per example: ' + stats.bwd_time + 'ms'; train_elt.appendChild(document.createTextNode(t)); train_elt.appendChild(document.createElement('br')); var t = 'Regression loss: ' + f2t(xLossWindow.get_average()); train_elt.appendChild(document.createTextNode(t)); train_elt.appendChild(document.createElement('br')); var t = 'L2 Weight decay loss: ' + f2t(w2LossWindow.get_average()); train_elt.appendChild(document.createTextNode(t)); train_elt.appendChild(document.createElement('br')); var t = 'L1 Weight decay loss: ' + f2t(w1LossWindow.get_average()); train_elt.appendChild(document.createTextNode(t)); train_elt.appendChild(document.createElement('br')); var t = 'Examples seen: ' + step_num; train_elt.appendChild(document.createTextNode(t)); train_elt.appendChild(document.createElement('br')); // visualize activations if(step_num % 100 === 0) { var vis_elt = document.getElementById("visnet"); visualize_activations(net, vis_elt); } // visualize embedding if(step_num % 100 === 0) { var embcanvas = document.getElementById('embedding'); var ctx = embcanvas.getContext("2d"); var EW = embcanvas.width; var EH = embcanvas.height; // propagate a few training examples through the network and grab codes var xcodes = []; var ycodes = []; var ns = embed_samples.length; // number of samples for(var k=0;k= 0 && xw1 >= 0 && xw2 >= 0) { // if they are -1 it means not enough data was accumulated yet for estimates lossGraph.add(step_num, xa + xw1 + xw2); lossGraph.drawSelf(document.getElementById("lossgraph")); } } step_num++; } // user settings var change_lr = function() { trainer.learning_rate = parseFloat(document.getElementById("lr_input").value); update_net_param_display(); } var update_net_param_display = function() { document.getElementById('lr_input').value = trainer.learning_rate; } var toggle_pause = function() { paused = !paused; var btn = document.getElementById('buttontp'); if(paused) { btn.value = 'resume' } else { btn.value = 'pause'; } } var dump_json = function() { document.getElementById("dumpjson").value = JSON.stringify(net.toJSON()); } var clear_graph = function() { lossGraph = new cnnvis.Graph(); // reinit graph too } var reset_all = function() { update_net_param_display(); // reinit windows that keep track of val/train accuracies lossGraph = new cnnvis.Graph(); // reinit graph too step_num = 0; // 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 + ')'); } var load_from_json = function() { var jsonString = document.getElementById("dumpjson").value; var json = JSON.parse(jsonString); net = new convnetjs.Net(); net.fromJSON(json); reset_all(); } var change_net = function() { eval($("#newnet").val()); reset_all(); }