Skip to content

Commit

Permalink
A major change
Browse files Browse the repository at this point in the history
1. Add demo about dataset
2. Add `prism` for code highlight
3. combine optimizers into a single file for loading efficiently
  • Loading branch information
suquark committed Feb 28, 2017
1 parent 2749da0 commit 9bc5444
Show file tree
Hide file tree
Showing 29 changed files with 1,426 additions and 505 deletions.
130 changes: 103 additions & 27 deletions backend/ops.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import { zeros } from 'util/array.js';
import { gaussRandom } from 'util/random.js';

function uniform_rand(t, floor, ceil) {
let N = t.size, tw = t.w;
let N = t.size,
tw = t.w;
for (let i = 0; i < N; i++) {
tw[i] = Math.random();
}
scale_shift(t, ceil - floor, floor);
}

function normal_rand(t, mu, std) {
let N = t.size, tw = t.w;
let N = t.size,
tw = t.w;
for (let i = 0; i < N; i++) {
tw[i] = gaussRandom();
}
Expand All @@ -20,19 +22,24 @@ function normal_rand(t, mu, std) {



function clip(x, min_value=-1.0, max_value=1.0) {
let N = x.size, w = x.w;
function clip(x, min_value = -1.0, max_value = 1.0) {
let N = x.size,
w = x.w;
for (let i = 0; i < N; i++) {
let wi = w[i];
if (wi > max_value) w[i] = max_value; else if (wi < min_value) w[i] = min_value;
if (wi > max_value) w[i] = max_value;
else if (wi < min_value) w[i] = min_value;
}
}

function clip_pixel(x) {
let N = x.size, w = x.w;
let N = x.size,
w = x.w;
for (let i = 0; i < N; i++) {
let wi = w[i];
if (wi >= 1.0) w[i] = 255; else if (wi <= -1.0) w[i] = 0; else w[i] = Math.round(255 * (wi + 1.0) / 2.0) | 0;
if (wi >= 1.0) w[i] = 255;
else if (wi <= -1.0) w[i] = 0;
else w[i] = Math.round(255 * (wi + 1.0) / 2.0) | 0;
}
}

Expand All @@ -42,10 +49,13 @@ function clip_pixel(x) {
function TensorVectorProduct(ov, m, v) {
let ncol = m.axis(-1) | 0;
let nrow = m.axis(-2) | 0;
let new_shape = m.shape.slice(); new_shape.pop();
let new_shape = m.shape.slice();
new_shape.pop();
let N = (m.size / ncol) | 0;

let mw = m.w, vw = v.w, ow = ov.w;
let mw = m.w,
vw = v.w,
ow = ov.w;
ow.fill(0.);
for (let i = 0; i < N; i++) {
for (let j = 0; j < ncol; j++) {
Expand All @@ -54,13 +64,57 @@ function TensorVectorProduct(ov, m, v) {
}
}


/**
* o = u * v
* shape: [M, N, L] <= [M, K] * [N, K, L]
*/
function matmul(o, u, v) {
o.w.fill(0.);
matmuladd(o, u, v);
}


/**
* o += u * v
* shape: [M, N, L] <= [M, K] * [N, K, L]
*/
function matmuladd(o, u, v) {
let K = u.axis(-1);

let MLen = K;
let M = (u.size / MLen) | 0;

let L = v.axis(-1);

let NLen = (K * L) | 0;
let N = (v.size / NLen) | 0;

let uw = u.w,
vw = v.w,
ow = o.w;

for (let m = 0; m < M; m++) {
for (let n = 0; n < N; n++) {
for (let l = 0; l < L; l++) {
let oindex = (m * N + n) * L + l;
for (let i = 0; i < K; i++) {
ow[oindex] += uw[m * MLen + i] * vw[n * NLen + i * L + l];
}
}
}
}
}



/**
* ov += m' * v
* @param { Tensor } m - tensor to be transposed
* @param { Tensor } v - right-hand-side tensor
*/
function TransposedTensorVectorAddAssign(ov, m, v) {
let ncol = m.axis(-1) | 0;
let ncol = m.axis(-1) | 0;
let nrow = m.axis(-2) | 0;
let new_shape = m.shape.slice();

Expand All @@ -72,7 +126,9 @@ function TransposedTensorVectorAddAssign(ov, m, v) {
let bs = ncol * nrow | 0;
let N = (m.size / bs) | 0;

let mw = m.w, vw = v.w, ow = ov.w;
let mw = m.w,
vw = v.w,
ow = ov.w;
// ow.fill(0.);
for (let z = 0; z < N; z++) {
for (let i = 0; i < nrow; i++) {
Expand All @@ -90,41 +146,47 @@ function TransposedTensorVectorAddAssign(ov, m, v) {
*/
function TensorConstantProduct(x, c) {
let o = x.cloneAndZero();
let N = o.size, ow = o.w, xw = x.w;
let N = o.size,
ow = o.w,
xw = x.w;
for (let i = 0; i < N; i++) {
ow[i] = xw[i] * c;
ow[i] = xw[i] * c;
}
return o;
}


function negative(x) {
let N = x.size, xw = x.w;
let N = x.size,
xw = x.w;
for (let i = 0; i < N; i++) {
xw[i] = -xw[i];
xw[i] = -xw[i];
}
}

function scale(x, c) {
let N = x.size, xw = x.w;
let N = x.size,
xw = x.w;
for (let i = 0; i < N; i++) {
xw[i] *= c;
xw[i] *= c;
}
}


function shift(x, c) {
let N = x.size, xw = x.w;
let N = x.size,
xw = x.w;
for (let i = 0; i < N; i++) {
xw[i] += c;
xw[i] += c;
}
}


function scale_shift(x, a, b) {
let N = x.size, xw = x.w;
let N = x.size,
xw = x.w;
for (let i = 0; i < N; i++) {
xw[i] = xw[i] * a + b;
xw[i] = xw[i] * a + b;
}
}

Expand All @@ -133,15 +195,29 @@ function scale_shift(x, a, b) {
* HadmardProduct apply to self
*/
function HadmardProductAssign(o, x) {
let N = o.size, ow = o.w, xw = x.w;
let N = o.size,
ow = o.w,
xw = x.w;
for (let i = 0; i < N; i++) {
ow[i] *= xw[i];
ow[i] *= xw[i];
}
}

export {
clip, clip_pixel,
scale, shift, scale_shift, negative,
TensorVectorProduct, TransposedTensorVectorAddAssign, HadmardProductAssign,
uniform_rand, normal_rand
clip,
clip_pixel,
scale,
shift,
scale_shift,
negative,
TensorVectorProduct,
TransposedTensorVectorAddAssign,
HadmardProductAssign,
uniform_rand,
normal_rand
};

export {
matmul,
matmuladd
}
12 changes: 12 additions & 0 deletions backend/shapeinf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* return output shape
*/
function matmul(u_shape, v_shape) {
u_shape = u_shape.slice();
v_shape = v_shape.slice();
u_shape.pop();
let tail = v_shape.pop();
v_shape.pop();
v_shape.push(tail);
return u_shape.concat(v_shape);
}
15 changes: 8 additions & 7 deletions backend/tensor.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { assert, isArray } from 'util/assert.js';
import { zeros } from 'util/array.js';
import { zeros, prod } from 'util/array.js';

class Tensor {
constructor(shape = [null], rawdata = undefined) {
this._shape = shape;
this._shape = Array.from(shape);
this._size = 1;
let vacant = -1;
for (let i in this._shape) {
Expand Down Expand Up @@ -93,6 +93,10 @@ class Tensor {
return amax;
}

toNumber() {
return this.w[0];
}

get softmax() {
let N = this.size;
let es = zeros(N);
Expand Down Expand Up @@ -164,11 +168,8 @@ class Tensor {
* @return { Tensor } - the loaded tensor
*/
static load(map, buf) {
let length = 1;
for (let i = 0; i < map.shape.length; i++) {
length *= map.shape[i];
}
let t = new Tensor(map.shape, buf.read(length, 'Float32Array'));
var N = prod(map.shape) | 0;
let t = new Tensor(map.shape, buf.read(N, 'Float32Array'));
t.name = map.name;
return t;
}
Expand Down
1 change: 1 addition & 0 deletions demo/dataset/canvas-nest.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions demo/dataset/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { negative } from 'backend/ops.js';
import { fetch, loadFile2Global } from 'backend/symbols.js';

import { zip } from 'util/functools.js';
import { Tensor2CanvasWithImage } from 'visualize/image.js';

// import { xs2vectors, ys } from 'dataset/mnist_2000.js';
// var xs = xs2vectors().map(x => new Tensor([28, 28, 1], x));
// for (let i of xs) scale_shift(i, 2, -1);
// store('mnist/x', ImageBuffer.fromTensors(xs));
// store('mnist/y', Int32Array.from(ys));
// saveGlobal("mnist2000.json", "mnist2000.raw");

var imgs, labels;

function init() {
return loadFile2Global('../../dataset/mnist2000.json', '../../dataset/mnist2000.raw').then(() => {
imgs = fetch('mnist/x').tensors;
labels = fetch('mnist/y');

return print;
});
}


function print(testbox) {
for (let [img, label] of zip([imgs.slice(0, 700), labels.slice(0, 700)])) {
let a = document.createElement('a');
d3.select(a).attr('data-position', 'top')
.attr('data-delay', '50')
.attr('data-tooltip', label)
.classed('tooltipped', true).style('margin-left', '5px');
negative(img);
let canvas = Tensor2CanvasWithImage(img);
a.appendChild(canvas);
testbox.appendChild(a);
}

}


export { print, init };
55 changes: 55 additions & 0 deletions demo/dataset/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Dataset Demo</title>

<script src="../../transpiler/system.js"></script>
<script src="../sysconf.js"></script>

<script src="../../visualize/jquery.min.js"></script>
<script src="../../visualize/preload-mask.js"></script>

<link rel="stylesheet" href="../../visualize/materialize/css/materialize.min.css" />
<link rel="stylesheet" href="../../visualize/materialize/css/material_icons.css" />
<script src="../../visualize/materialize/js/materialize.min.js"></script>


<script src="../../visualize/d3.min.js"></script>
</head>

<body>
<div class="container">
<div class='row'>
<div class='col s12'>
<h1>Dataset Demo - MNIST</h1>
<blockquote>
This demo illustrated about
</blockquote>
</div>
<div class='col s12' id="testbox"></div>
</div>
</div>
</body>

<script type="text/javascript">
set_preload_mask();
var testbox = document.getElementById("testbox");
SystemJS.import('./demo.js').then(demo => demo.init()).then(print => {
print(testbox);
disable_preload_mask();

$('.tooltipped').tooltip({
delay: 50
});
});
// $(document).ready(function() {

// });
</script>

<script type="text/javascript" color="120,190,250" opacity="0.9" count="500" src="canvas-nest.min.js"></script>

</html>
Loading

0 comments on commit 9bc5444

Please sign in to comment.