Skip to content

Commit

Permalink
A major fix
Browse files Browse the repository at this point in the history
1. Fix bugs in module loading
2. Add transpiler (SystemJS+traceur) for ES6 support in browser
3. Add Deconvolution Layer
  • Loading branch information
suquark committed Jan 24, 2017
1 parent 006c3f6 commit 242c4c6
Show file tree
Hide file tree
Showing 26 changed files with 72,702 additions and 103 deletions.
6 changes: 3 additions & 3 deletions convnet.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Vol } from 'vol';
import { assert, indexOfMax } from 'util';
import { get_layer } from 'layers/layer_export'
import { Vol } from 'vol.js';
import { assert, indexOfMax } from 'util.js';
import { get_layer } from 'layers/layer_export.js';

// Net manages a set of layers
// For now constraints: Simple linear order of layers, first layer input last layer a cost layer
Expand Down
206 changes: 206 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>DCGAN face generator demo</title>

<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/vis.js"></script>
<script src="js/util.js"></script>
<script src="js/convnet.js"></script>
<script src="js/gen_layers.js"></script>
<script src="js/zws5.js"></script>


<script src="js/image-helpers.js"></script>
<script src="js/pica.js"></script>

<style type="text/css">
<!--
.box{
float: left;
width: 200px;
}

-->
</style>
<script>
// ant -lib yuicompressor-2.4.8.jar -f build.xml


var clip_pixel = function(x){
if(x>1) return 255;
else if(x<-1) return 0;
else return 255*(x+1.0)/2.0;
}

var draw_activations_COLOR = function(elt, A, scale, grads) {

var s = scale || 1; // scale
var draw_grads = false;
if(typeof(grads) !== 'undefined') draw_grads = grads;

// get max and min activation to scale the maps automatically
var w = draw_grads ? A.dw : A.w;
var mm = cnnutil.maxmin(w);

var canv = document.createElement('canvas');
canv.className = 'actmap';
var W = A.sx * s;
var H = A.sy * s;
canv.width = W;
canv.height = H;
var ctx = canv.getContext('2d');
var g = ctx.createImageData(W, H);
for(var d=0;d<3;d++) {
for(var x=0;x<A.sx;x++) {
for(var y=0;y<A.sy;y++) {
if(draw_grads) {
var dval = Math.floor((A.get_grad(x,y,d)-mm.minv)/mm.dv*255);
} else {
//var dval = Math.floor((A.get(x,y,d)-mm.minv)/mm.dv*255);
var dval = clip_pixel(A.get(x,y,d));
}
for(var dx=0;dx<s;dx++) {
for(var dy=0;dy<s;dy++) {
var pp = ((W * (y*s+dy)) + (dx + x*s)) * 4;
g.data[pp + d] = dval;
if(d===0) g.data[pp+3] = 255; // alpha channel
}
}
}
}
}
ctx.putImageData(g, 0, 0);
elt.appendChild(canv);
}

</script>
<script type="text/javascript">

var layer_defs, net;
layer_defs = [];
layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:100});
layer_defs.push({type:'deconv', sx:6, filters:512, stride:1, pad:0, activation:'relu'});
layer_defs.push({type:'deconv', sx:4, filters:256, stride:2, pad:1, activation:'relu'});
layer_defs.push({type:'deconv', sx:4, filters:128, stride:2, pad:1, activation:'relu'});
layer_defs.push({type:'deconv', sx:4, filters:64, stride:2, pad:1, activation:'relu'});
layer_defs.push({type:'deconv', sx:4, filters:3, stride:2, pad:1});

net = new convnetjs.Net();
net.makeLayers(layer_defs);

net.layers[1].fromJSON(layer_0);
net.layers[3].fromJSON(layer_1);
net.layers[5].fromJSON(layer_2);
net.layers[7].fromJSON(layer_3);
net.layers[9].fromJSON(layer_4);

var sliders = [];
var strength = []
var z0 = [];

var num_tags = 123;

var initialize = function(){
var doms = [];
dom = document.createElement('div');
//dom.className = "box";
dom.innerHTML = "noise_strength" + "<br>";
doms.push(dom);
document.getElementById('z').appendChild(doms[0]);
strength.push(document.createElement('input'));
strength[0].type="range";
strength[0].value=100;
strength[0].min='0';
strength[0].max='100';
strength[0].step='1';
doms[0].appendChild(strength[0]);
for(var i=0; i<num_tags; i++){
dom = document.createElement('div');
dom.className = "box";
dom.innerHTML = zws['w'][i]['name'] + "<br>";
doms.push(dom);
document.getElementById('z').appendChild(doms[i]);
}
for(var i=0; i<num_tags; i++){
sliders.push(document.createElement('input'));
sliders[i].type="range";
sliders[i].value=0;
sliders[i].min='-100';
sliders[i].max='100';
sliders[i].step='1';
doms[i+1].appendChild(sliders[i]);
}
for(var i=0; i<100; i++){
z0.push(Math.random()*2.0-1.0);
}
test();
}

var shuffle = function(){
for(var i=0; i<100; i++){
//sliders[i].value=Math.random()*100;
z0[i] = (Math.random()*2.0-1.0);
}
test();

}

var reset_value = function(){
for(var i=0; i<num_tags; i++){
sliders[i].value=0;
}
}



var test = function(){

//document.getElementById("json_net").inner_HTML = JSON.stringify(net.toJSON());
x = new convnetjs.Vol(1,1,100,0.0);
for(var i=0; i<100; i++){
// x.set(0,0,i,Math.random()*2.0-1.0);
// x.set(0,0,i,sliders[i].value/50.0-1.0);
var z = strength[0].value/100.0*z0[i];
for(var j=0; j<num_tags; j++){
z += sliders[j].value/200.0 * zws['w'][j]['v'][i];
}
if(z>1) z=1;
else if(z<-1) z=-1;
x.set(0,0,i,z);
}
img = net.forward(x);
draw_activations_COLOR(document.getElementById('hoge'), img);
//console.log(JSON.stringify(net.toJSON()));
}
// ------------------------
// END CIFAR-10 SPECIFIC STUFF
// ------------------------
</script>

</head>
<body onload="initialize()">
<div style="margin:5px; padding:10px; border: solid 1px;">
<li>各タグベクトルに強度を掛けた総和 + ノイズ を元に、ニューラルネットが画像を生成します</li>
<li>noise strengthスライダーでノイズ強度を調整できます。変な画像が多いときは下げて、似たような画像ばかり出るときは上げましょう</li>
<li>各タグ強度の初期値は0で、右に動かすとプラスに、左に動かすとマイナスになります</li>
<li>draw!ボタンを押すと、ノイズはそのままにタグ強度の更新を反映します</li>
<li>shuffle!ボタンを押すと、タグ強度の更新を反映し、ノイズも再サンプルします</li>
<li>reset!ボタンは各タグ強度を0にリセットするだけです</li>
<li>Chainer-DCGANで生成された画像は自由に使用することができます。使用により生じた一切の損害に対し、Chainer-DCGANの開発者は責任を負いません。</li>
</div>
<div id="hoge">

</div>
<input type="button" value="draw!" onclick="test();">
<input type="button" value="shuffle!" onclick="shuffle();">
<input type="button" value="reset!" onclick="reset_value();">
<div id="z">
</div>
<div id="param"></div>
</body>
</html>


12 changes: 6 additions & 6 deletions layers/activation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { zeros, indexOfMax } from 'convnet_util';
import Layer from 'layer'
import { indexOfMax } from 'util.js';
import { Layer } from 'layers/layer.js'

class ReluLayer extends Layer {
// Implements ReLU nonlinearity elementwise
Expand All @@ -22,7 +22,7 @@ class ReluLayer extends Layer {
var V = this.in_act; // we need to set dw of this
var V2 = this.out_act;
var N = V.length;
V.dw = zeros(N); // zero out gradient wrt data
V.dw.fill(0.); // zero out gradient wrt data
for (var i = 0; i < N; i++) {
V.dw[i] = V2.w[i] <= 0 ? 0 : V2.dw[i]; // threshold
}
Expand Down Expand Up @@ -54,7 +54,7 @@ class SigmoidLayer extends Layer {
var V = this.in_act; // we need to set dw of this
var V2 = this.out_act;
var N = V.length;
V.dw = zeros(N); // zero out gradient wrt data
V.dw.fill(0.); // zero out gradient wrt data
for (let i = 0; i < N; i++) {
let v2wi = V2.w[i];
V.dw[i] = v2wi * (1.0 - v2wi) * V2.dw[i];
Expand Down Expand Up @@ -85,7 +85,7 @@ class TanhLayer extends Layer {
var V = this.in_act; // we need to set dw of this
var V2 = this.out_act;
var N = V.length;
V.dw = zeros(N); // zero out gradient wrt data
V.dw.fill(0.); // zero out gradient wrt data
for (let i = 0; i < N; i++) {
let v2wi = V2.w[i];
V.dw[i] = (1.0 - v2wi * v2wi) * V2.dw[i];
Expand Down Expand Up @@ -163,7 +163,7 @@ class MaxoutLayer extends Layer {
var V = this.in_act; // we need to set dw of this
var V2 = this.out_act;
var N = this.out_depth;
V.dw = global.zeros(V.w.length); // zero out gradient wrt data
V.dw.fill(0.); // zero out gradient wrt data

// pass the gradient through the appropriate switch
if(this.out_sx === 1 && this.out_sy === 1) {
Expand Down
Loading

0 comments on commit 242c4c6

Please sign in to comment.