Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 3 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Showing with 158 additions and 549 deletions.
  1. +106 −472 index.html
  2. +0 −77 indexnew.html
  3. +1 −0 js/main.js
  4. +51 −0 js/netgui.js
View
578 index.html
@@ -1,488 +1,122 @@
<!doctype html>
-<html>
-<head>
- <title>Neural Networks</title>
- <meta charset="utf-8" />
- <style>
- #c { border : 1px solid #000;}
- #input { width: 600px; height: 200px;}
- </style>
- <script src="js/neury.js"></script>
-</head>
-<body>
-<button onclick="toggleComputation()">Pause/Run</button>
-<br />
-<canvas id="view"></canvas>
-<br />
-<textarea id="input">
-# output nodes ~ input nodes
-h1 ~ 1000x - 333
-h2 ~ -1000x - 333
-h3 ~ 1000y - 333
-h4 ~ -1000y - 333
-c1 ~ -1000h[1..4]
-c2 ~ 1000h[1..4] - 2000
-out ~ -10c[1..2] + 1
-
-!x:horz
-!y:vert
-
-## output nodes ~ input nodes
-#y ~ -2x
-#z ~ -3.5y
-#w ~ -25z
-#y ~ -7.6w
-#
-#!x:horz
-</textarea>
-<br />
-<button onclick="processInput()">Process</button>
-
- <script>
- var body = document.body;
- var canvas = document.getElementsByTagName('canvas')[0];
- var ctx = canvas.getContext('2d');
- document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218
- </script>
- <script>
-
-tau = Math.PI * 2;
-abs = Math.abs;
-
-main = {
- size : {x:600, y:600},
- zoom : 4,
- offset : {x:0,y:0},
- changed : true,
- drag : false,
- dragDelta : {x:0,y:0},
- activeLinks : []
-};
-
-main.to = function(item, result){
- result.pos.x = (item.pos.x + this.offset.x) * this.zoom,
- result.pos.y = (item.pos.y + this.offset.y) * this.zoom,
- result.size = item.size * this.zoom;
-}
-
-main.from = function(item, result){
- result.pos.x = item.pos.x / this.zoom - this.offset.x,
- result.pos.y = item.pos.y / this.zoom - this.offset.y;
-}
-
-CPU = {
- hotness : 1.0,
- paused : false,
- cur : {},
- next : {changed:false},
-};
-
-canvas.width = main.size.x;
-canvas.height = main.size.y;
-
-mouse = {pos:{x:0,y:0},size:5, view:{pos:{x:0,y:0}, size:5}, down:false};
-mouse.render = function(){
- ctx.beginPath();
- ctx.fillStyle = this.down ? "#fdb" : "#adb";
- ctx.arc(this.view.pos.x, this.view.pos.y, 3, 0, tau, 0);
- ctx.fill();
-}
-mouse.setPos = function(e){
- this.view.pos.x = e.pageX - canvas.offsetLeft;
- this.view.pos.y = e.pageY - canvas.offsetTop;
- main.from(this.view, this);
-}
-
-window.requestAnimFrame = (function(){
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function( callback ){ window.setTimeout(callback, 1000 / 60);};
-})();
-
-indexer = (function(){var idx=0; return function(){idx+=1;return idx+"";} })();
-function diff(from, to, result){result.x = from.x - to.x; result.y = from.y - to.y;}
-function avg(from, to, result){ result.x = (from.x + to.x)/2; result.y = (from.y + to.y)/2;}
-function isInside(a,b,size){return (Math.abs(a.x - b.x) < size) && (Math.abs(a.y - b.y) < size)}
-function sigmoid(a){return 1/(1+Math.exp(-a));}
-
-function NeuronValue(size){
- this.size = {x:size.x, y:size.y};
- this.count = size.x * size.y;
- this.value = new Float32Array(this.count);
- this.changed = true;
- this.imageData = ctx.createImageData(size.x, size.y);
-}
-
-NeuronValue.prototype.clear = function(value){
- value = value || 0;
- for(var i = 0; i < this.value.length; i+=1){
- this.value[i] = value;
- }
-}
-
-NeuronValue.prototype.assign = function(other){
- for(var i = 0; i < this.value.length; i+=1){
- this.value[i] = other.value[i];
- }
-}
-
-NeuronValue.prototype.add = function(other, mul){
- for(var i = 0; i < this.value.length; i+=1){
- this.value[i] += other.value[i] * mul;
- }
-}
-
-NeuronValue.prototype.addBias = function(bias){
- for(var i = 0; i < this.value.length; i+=1){
- this.value[i] += bias;
- }
-}
-
-NeuronValue.prototype.same = function(other){
- var diff = 0;
- for(var i = 0; i < this.value.length; i+=1){
- diff += Math.abs(this.value[i] - other.value[i]);
- }
- return diff < 0.01;
-}
-
-NeuronValue.prototype.calculate = function(){
- for(var i = 0; i < this.value.length; i+=1){
- this.value[i] = sigmoid(this.value[i]);
- }
- this.changed = true;
-}
-
-NeuronValue.prototype.renderToImage = function(){
- if(!this.changed)
- return;
- var k = 0,
- data = this.imageData.data;
- for(var i = 0; i < data.length; i+=4){
- var v = this.value[k];
- k += 1;
- v = (v+1) / 2;
- v = v > 1 ? 255 : v < 0 ? 0 : (v*255)|0;
- data[i] = v;
- data[i+1] = v;
- data[i+2] = v;
- data[i+3] = 255;
- }
-}
-
-NeuronValue.prototype.render = function(x, y){
- this.renderToImage();
- ctx.putImageData(this.imageData, x, y);
-}
-
-function Neuron(name, pos){
- this.idx = indexer();
- this.name = name;
- this.pos = pos || {x:0, y:0};
- this.size = 5;
- this.inputs = [];
- this.outputs = [];
- this.changed = true;
- this.view = { pos : {x:0, y:0}, size:5, hover:false, drag:false, dragDelta: {x:0, y:0} };
- this.bias = 0;
- this.value = new NeuronValue({x:50, y:50});
- this.next_value = new NeuronValue({x:50, y:50});
-}
-
-Neuron.prototype.recalcView = function(force){
- if(!this.changed && !force) return;
- main.to(this, this.view);
- this.changed = false;
-}
-
-Neuron.prototype.recalcLinks = function(force){
- for(var i = 0; i < this.inputs.length; i += 1){
- var link = this.inputs[i];
- avg(link.from.view.pos, this.view.pos, link.center);
- }
-}
-
-Neuron.prototype.compute = function(){
- if(this.inputs.length <= 0){
- return;
- }
- var result = this.next_value;
- result.clear();
+<title>Neural Networks</title>
- for(var i = 0; i < this.inputs.length; i += 1){
- var link = this.inputs[i];
- result.add( link.from.value, link.weight );
- }
-
- result.addBias(this.bias);
- result.calculate();
-
- this.next_value = result;
- if(this.next_value.same(this.value)) return;
-
- this.changed = true;
- this.triggerOut();
-}
-
-Neuron.prototype.tick = function(){
- this.value.assign(this.next_value);
-}
-
-Neuron.prototype.trigger = function(){
- CPU.next[this.idx] = this;
- CPU.next.changed = true;
-}
-
-Neuron.prototype.triggerOut = function(){
- for(var i = 0; i < this.outputs.length; i += 1)
- this.outputs[i].to.trigger();
-}
-
-Neuron.prototype.set = function(value){
- this.value = value;
- this.next_value.assign(value);
- this.triggerOut();
-}
+<meta charset="utf-8" />
-Neuron.prototype.render = function(){
- var view = this.view;
- ctx.fillStyle = view.hover ? "#ecd" : "#dab";
- ctx.beginPath();
- ctx.arc(view.pos.x, view.pos.y, view.size, 0, tau, 0);
- ctx.fill();
-
- ctx.fillStyle = "#000";
- ctx.font = 7 * main.zoom + "px sans-serif";
- tm = ctx.measureText(this.name)
- tm.height = 4 * main.zoom;
- ctx.fillText(this.name,
- view.pos.x - tm.width/2,
- view.pos.y + tm.height/2);
- this.value.render(this.view.pos.x + this.view.size, this.view.pos.y);
-}
-
-Neuron.prototype.renderConnections = function(){
- if(this.inputs.length == 0){
- ctx.beginPath();
- ctx.moveTo(0, this.view.pos.y);
- ctx.lineTo(this.view.pos.x, this.view.pos.y);
- ctx.strokeStyle = "#999";
- ctx.stroke();
- } else {
- var center = {x:0,y:0};
- for(var i = 0; i < this.inputs.length; i += 1){
- var link = this.inputs[i];
- // draw line
- ctx.strokeStyle = link.down ? "#f00" : "#999";
- ctx.beginPath();
- ctx.moveTo(link.from.view.pos.x, link.from.view.pos.y);
- ctx.lineTo(this.view.pos.x, this.view.pos.y);
- ctx.stroke();
- // draw text
- ctx.font = 3.5 * main.zoom + "px sans-serif";
- ctx.beginPath();
-
- ctx.fillStyle = "rgba(100,200,200,0.3)";
- ctx.arc(link.center.x, link.center.y, 10, 0, tau, 0);
- ctx.fill();
-
- ctx.fillStyle = "#000";
- ctx.fillText(link.weight.toFixed(2), link.center.x, link.center.y);
- }
+<style href="css/reset.css"></style>
+<style>
+ #view {
+ border : 1px solid #000;
+ cursor: crosshair;
+ -webkit-user-select: none;
}
-
- if(this.outputs.length == 0){
- ctx.strokeStyle = "#999";
- ctx.beginPath();
- ctx.moveTo(this.view.pos.x, this.view.pos.y);
- ctx.lineTo(main.size.x, this.view.pos.y);
- ctx.stroke();
+ #input {
+ width: 600px;
+ height: 480px;
+ float: left;
}
-}
-
-Neuron.prototype.mouseDown = function(e){
- if(this.view.hover){
- this.view.drag = true;
- diff(this.pos, mouse.pos, this.view.dragDelta);
- return true;
- }
- return false;
-}
-
-Neuron.prototype.mouseLinkDown = function(e){
- for(var i = 0; i < this.inputs.length; i += 1){
- var link = this.inputs[i];
- if( isInside(mouse.view.pos, link.center, 10) ){
- link.down = true;
- main.activeLinks.push(link);
- return true;
- }
- }
- return false;
-}
-
-Neuron.prototype.mouseUp = function(e){
- this.view.drag = false;
- return false;
-}
-
-Neuron.prototype.mouseMove = function(e){
- this.view.hover = isInside(this.view.pos, mouse.view.pos, this.view.size);
- if(this.view.drag){
- this.pos.x = mouse.pos.x + this.view.dragDelta.x;
- this.pos.y = mouse.pos.y + this.view.dragDelta.y;
- this.changed = true;
- }
-}
-
-//====================================
-
-makeLink = function(X,Y, weight){
- var link = {from:X, to:Y, weight: weight, center:{x:0, y:0}, down: false};
- X.outputs.push(link);
- Y.inputs.push(link);
-}
-
-X = new Neuron("x", {x:20, y:30});
-Y = new Neuron("y", {x:20, y:60});
-Z = new Neuron("z", {x:70, y:40});
-W = new Neuron("w", {x:120, y:40});
-//====================================
+ button {
+ width : 70px;
+ height: 30px;
+ float: left;
+ }
-function tick(){
- for(var i = 0; i < neurons.length; i += 1)
- neurons[i].tick();
-}
+ #log {
+ height: 10px;
+ font: "10px Courier New";
+ }
+</style>
-function forceUpdate(){
- for(var i = 0; i < neurons.length; i += 1)
- neurons[i].trigger();
- CPU.cur = {};
- for(var idx in CPU.next){
- if(!CPU.next.hasOwnProperty(idx)) continue;
- CPU.cur[idx] = CPU.next[idx];
- }
- delete CPU.cur["changed"];
-}
-
-function compute(){
- var processed = false;
- CPU.hotness *= 0.8;
- if(CPU.paused) return;
-
- for(var idx in CPU.cur){
- if(!CPU.cur.hasOwnProperty(idx)) continue;
- CPU.cur[idx].compute();
- delete CPU.cur[idx];
- processed = true;
- }
-
- if(processed || CPU.next.changed){
- tick();
- CPU.cur = CPU.next;
- delete CPU.cur["changed"];
- CPU.next = {changed:false};
- }
-
- if(processed){
- CPU.hotness = 1.0;
- };
-}
-
-function updateDrag(){
- for(var i = 0; i < main.activeLinks.length; i += 1){
- var link = main.activeLinks[i];
- link.weight += (main.dragDelta.y*main.zoom - mouse.view.pos.y)/1000;
- link.to.trigger();
- }
-}
-
-function toggleComputation(){
- CPU.paused = !CPU.paused;
-}
-
-function render(){
- compute();
- updateDrag();
- ctx.clearRect(0,0,main.size.x, main.size.y);
-
- ctx.beginPath();
- ctx.fillStyle = "rgba(230, 150, 150, " + CPU.hotness.toFixed(1) + ")";
- ctx.arc(30, 30, 10, 0, tau, 0);
- ctx.fill();
+<canvas id="view"></canvas>
+<textarea id="input">
+# output nodes ~ input nodes
+h.1 ~ 10x - 3
+h.2 ~ -10x - 3
+h.3 ~ 10y - 3
+h.4 ~ -10y - 3
+c.1 ~ -10h[1..4] + 10
+c.2 ~ 10h[1..4] - 20
+out ~ -25c.1 - 10c.2 + 1
+
+# define layers
+= x y
+= h[1..4]
+= c[1..2]
+= out
+
+# define properties
+x : value = horz
+y : value = vert
+</textarea>
+<br />
+<div id="log">
+</div>
- for(var i = 0; i < neurons.length; i += 1)
- neurons[i].recalcView(amin.changed);
- for(var i = 0; i < neurons.length; i += 1)
- neurons[i].recalcLinks(main.changed);
- for(var i = 0 ; i < neurons.length; i+=1)
- neurons[i].renderConnections();
- for(var i = 0 ; i < neurons.length; i+=1)
- neurons[i].render();
- mouse.render();
+<select id="select-example">
+</select>
- main.changed = false;
- window.requestAnimFrame(render);
-}
-render();
+<button id="load">Load</button>
+<button id="step">Step</button>
+<button id="run">Run</button>
+<button id="stop">Stop</button>
-canvas.onmousemove=function(e){
- mouse.setPos(e)
- if( main.drag ){
- main.offset.x = mouse.view.pos.x / main.zoom - main.dragDelta.x;
- main.offset.y = mouse.view.pos.y / main.zoom - main.dragDelta.y;
- main.changed = true;
- }
- for(var i = 0; i < neurons.length; i += 1)
- neurons[i].mouseMove(e);
- e.preventDefault();
-};
+<script src="js/def.js"></script>
+<script src="js/math.js"></script>
+<script src="js/vector.js"></script>
+<script src="js/matrix.js"></script>
+<script src="js/canvas.js"></script>
+<script src="js/grid.js"></script>
+<script src="js/hudstack.js"></script>
-canvas.onmousedown=function(e){
- e.preventDefault();
- mouse.down = true;
- mouse.setPos(e)
- var hit = false
- for(var i = 0; !hit && (i < neurons.length); i += 1)
- hit = neurons[i].mouseDown(e) || hit;
- for(var i = 0; !hit && (i < neurons.length); i += 1)
- hit = neurons[i].mouseLinkDown(e) || hit;
- main.dragDelta.x = mouse.view.pos.x / main.zoom - main.offset.x;
- main.dragDelta.y = mouse.view.pos.y / main.zoom - main.offset.y;
-
- if (hit) return;
- main.drag = true;
-}
+<script src="js/neury.js"></script>
-canvas.onmouseup=function(e){
- e.preventDefault();
- main.drag = false;
- mouse.down = false;
- mouse.setPos(e)
- for(var i = 0; i < neurons.length; i += 1)
- neurons[i].mouseUp(e);
- for(var i = 0; i < main.activeLinks.length; i += 1){
- main.activeLinks[i].down = false;
- }
- main.activeLinks = [];
-}
+<script src="js/net.js"></script>
+<script src="js/netgui.js"></script>
-canvas.onmousewheel=function(e){
- e.preventDefault();
- main.offset.x -= mouse.view.pos.x / main.zoom;
- main.offset.y -= mouse.view.pos.y / main.zoom;
- main.zoom *= e.wheelDelta > 0 ? 1.2 : 1/1.2;
- main.offset.x += mouse.view.pos.x / main.zoom;
- main.offset.y += mouse.view.pos.y / main.zoom;
- main.changed = true;
-}
+<script src="js/main.js"></script>
+<script src="js/bindings.js"></script>
+<script src="js/buttons.js"></script>
-// end of submission //
- </script>
-</body>
-</html>
+<div id="examples" style="visibility: hidden; display: none">
+<script type="neury" caption="empty"></script>
+<script type="neury" caption="circles">
+# output nodes ~ input nodes
+h.1 ~ 10x - 3
+h.2 ~ -10x - 3
+h.3 ~ 10y - 3
+h.4 ~ -10y - 3
+c.1 ~ -10h[1..4] + 10
+c.2 ~ 10h[1..4] - 20
+out ~ -25c.1 - 10c.2 + 1
+
+# define layers
+= x y
+= h[1..4]
+= c[1..2]
+= out
+
+# define properties
+x : value = horz
+y : value = vert
+</script>
+<script type="neury" caption="feedback">
+y ~ -2x
+z ~ -3.5y
+w ~ -25z
+y ~ -7.6w
+z ~ t
+u ~ x + t
+w ~ u
+
+# define layers
+= x t
+= u
+= z w
+= y
+
+x : value = horz
+t : value = vert
+</script>
+</div>
View
77 indexnew.html
@@ -1,77 +0,0 @@
-<!doctype html>
-
-<title>Neural Networks</title>
-
-<meta charset="utf-8" />
-
-<style href="css/reset.css"></style>
-<style>
- #view {
- border : 1px solid #000;
- cursor: crosshair;
- -webkit-user-select: none;
- }
- #input {
- width: 600px;
- height: 480px;
- float: left;
- }
-
- button {
- width : 70px;
- height: 30px;
- float: left;
- }
-
- #log {
- height: 10px;
- font: "10px Courier New";
- }
-</style>
-
-<canvas id="view"></canvas>
-<textarea id="input">
-# output nodes ~ input nodes
-h.1 ~ 10x - 3
-h.2 ~ -10x - 3
-h.3 ~ 10y - 3
-h.4 ~ -10y - 3
-c.1 ~ -10h[1..4] + 10
-c.2 ~ 10h[1..4] - 20
-out ~ -25c.1 - 10c.2 + 1
-
-# define layers
-= x y
-= h[1..4]
-= c[1..2]
-= out
-
-# define properties
-x : value = horz
-y : value = vert
-</textarea>
-<br />
-<div id="log">
-</div>
-
-<button id="load">Load</button>
-<button id="step">Step</button>
-<button id="run">Run</button>
-<button id="stop">Stop</button>
-
-<script src="js/def.js"></script>
-<script src="js/math.js"></script>
-<script src="js/vector.js"></script>
-<script src="js/matrix.js"></script>
-<script src="js/canvas.js"></script>
-<script src="js/grid.js"></script>
-<script src="js/hudstack.js"></script>
-
-<script src="js/neury.js"></script>
-
-<script src="js/net.js"></script>
-<script src="js/netgui.js"></script>
-
-<script src="js/main.js"></script>
-<script src="js/bindings.js"></script>
-<script src="js/buttons.js"></script>
View
1 js/main.js
@@ -51,6 +51,7 @@ main.huds.add(new NetUI());
main.huds.add(new NetMover());
main.huds.add(new WireAdjuster());
main.huds.add(new BiasAdjuster());
+main.huds.add(new WireDrawer());
setTimeout(function(){load.click();}, 1000);
View
51 js/netgui.js
@@ -270,4 +270,55 @@ BiasAdjuster.methods({
this.selection.setBias(bias);
V.set(this.last, e.scroll);
}
+});
+
+function WireDrawer(){
+ NetAdjuster.call(this);
+ this.from = {x:0, y:0};
+ this.to = {x:0, y:0};
+}
+
+WireDrawer.inherit(NetAdjuster);
+WireDrawer.methods({
+ render : function(ctx){
+ if(!this.adjusting)
+ return;
+ ctx.lineWidth = 5;
+ ctx.strokeStyle = "#d44";
+ ctx.beginPath();
+ ctx.moveTo(this.from.x, this.from.y);
+ ctx.lineTo(this.to.x, this.to.y);
+ ctx.stroke();
+ },
+ findItem : function(action, e){
+ var net = this.getNet(),
+ keys = Object.keys(net.nodes);
+ for(var i = keys.length - 1; i >= 0; i -= 1){
+ var node = net.nodes[keys[i]];
+ if (node.view == null)
+ continue;
+ var p = { x : node.view.pos.x, y : node.view.pos.y + node.view.header + node.view.param };
+ var inside = V.pointInsideRect(e.scroll, p, {x:node.view.width, y:node.view.param});
+ if(inside)
+ return node;
+ }
+ },
+ adjustItem : function(action, e, item){
+ if(action == "start")
+ V.set(this.from, e.scroll);
+ if(action == "move")
+ V.set(this.to, e.scroll)
+
+ if(action == "end"){
+
+ }
+ /*
+ var bias = this.selection.bias,
+ dy = e.scroll.y - this.last.y,
+ dx = e.scroll.x - this.last.x;
+ bias += dy / 4;
+ bias += dx / 10;
+ this.selection.setBias(bias);
+ V.set(this.last, e.scroll);*/
+ }
});

No commit comments for this range

Something went wrong with that request. Please try again.