├── .gitignore ├── .npmignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── AUTHORS.txt ├── LICENSE ├── README.md ├── apidoc └── index.md ├── bench ├── bench_base.ts ├── conv.ts ├── index.ts └── mtimes.ts ├── browser ├── header.js └── run.html ├── do_browserify.sh ├── docs ├── .nojekyll ├── api │ ├── assets │ │ ├── css │ │ │ ├── main.css │ │ │ └── main.css.map │ │ ├── images │ │ │ ├── icons.png │ │ │ ├── icons@2x.png │ │ │ ├── widgets.png │ │ │ └── widgets@2x.png │ │ └── js │ │ │ ├── main.js │ │ │ └── search.js │ ├── classes │ │ ├── accuracylayer.html │ │ ├── arrayserializer.html │ │ ├── batchnormalizationlayer.html │ │ ├── benchbase.html │ │ ├── blobdatalayer.html │ │ ├── branchlayer.html │ │ ├── conv.html │ │ ├── convolution2dlayer.html │ │ ├── dataaugmentationlayer.html │ │ ├── datalayer.html │ │ ├── dropoutlayer.html │ │ ├── forwardconfiguration.html │ │ ├── layer.html │ │ ├── layerfactory.html │ │ ├── linearlayer.html │ │ ├── losslayer.html │ │ ├── mnistdatalayer.html │ │ ├── mtimes.html │ │ ├── network.html │ │ ├── optimizer.html │ │ ├── optimizersgd.html │ │ ├── pluslayer.html │ │ ├── pooling2dlayer.html │ │ ├── relulayer.html │ │ └── softmaxcrossentropylayer.html │ ├── globals.html │ └── index.html ├── css │ └── main.css ├── examples │ ├── camera │ │ ├── camera_demo.js │ │ ├── index.html │ │ └── lenet_weight.js │ └── mnist │ │ ├── index.html │ │ ├── mnist_demo.css │ │ ├── mnist_demo.js │ │ ├── network_shape.png │ │ └── network_shape_rot.png ├── feed.xml ├── images │ └── ss_camerademo.png ├── index.html ├── js │ ├── jquery-3.1.1.min.js │ ├── milsukiyaki2.js │ ├── milsushi2.js │ ├── milsushi2_cl.js │ └── setImmediate.js └── setup.html ├── docs_raw └── jekyll │ ├── .gitignore │ ├── Gemfile │ ├── Gemfile.lock │ ├── _config.yml │ ├── _includes │ ├── footer.html │ ├── head.html │ └── header.html │ ├── _layouts │ ├── default.html │ ├── page.html │ └── post.html │ ├── _sass │ ├── _base.scss │ ├── _layout.scss │ └── _syntax-highlighting.scss │ ├── css │ └── main.scss │ ├── examples │ ├── camera │ │ ├── camera_demo.js │ │ ├── index.html │ │ └── lenet_weight.js │ └── mnist │ │ ├── index.html │ │ ├── mnist_demo.css │ │ ├── mnist_demo.js │ │ ├── network_shape.png │ │ └── network_shape_rot.png │ ├── feed.xml │ ├── images │ └── ss_camerademo.png │ ├── index.html │ ├── js │ ├── jquery-3.1.1.min.js │ ├── milsukiyaki2.js │ ├── milsushi2.js │ ├── milsushi2_cl.js │ └── setImmediate.js │ └── setup.md ├── example └── mnist │ ├── data │ └── .gitkeep │ ├── lenet.json │ ├── model │ └── .gitkeep │ ├── prepare.py │ └── train.sh ├── imagenet_mean.npy ├── index.ts ├── main.ts ├── netdef ├── lenet.json ├── lenet_invert.json ├── resnet101.json ├── resnet152.json ├── resnet50.json ├── vgg11.json └── vgg16.json ├── package.json ├── run ├── classify_node.ts └── train_node.ts ├── spec ├── data_augmentation.spec.ts ├── fixture │ ├── data_augmentation │ │ ├── bottom.npy │ │ ├── mean.npy │ │ └── top.npy │ ├── fixture_helper.py │ ├── layer │ │ ├── average_pooling_2d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── forward.bottoms.0.npy │ │ │ └── forward.tops.0.npy │ │ ├── batch_normalization_2d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_beta.npy │ │ │ ├── delta_params.delta_gamma.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.beta.npy │ │ │ └── train_params.gamma.npy │ │ ├── batch_normalization_4d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_beta.npy │ │ │ ├── delta_params.delta_gamma.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.beta.npy │ │ │ └── train_params.gamma.npy │ │ ├── convolution_2d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_bias.npy │ │ │ ├── delta_params.delta_weight.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.bias.npy │ │ │ └── train_params.weight.npy │ │ ├── convolution_2d_1x1 │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_bias.npy │ │ │ ├── delta_params.delta_weight.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.bias.npy │ │ │ └── train_params.weight.npy │ │ ├── convolution_2d_group │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_bias.npy │ │ │ ├── delta_params.delta_weight.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.bias.npy │ │ │ └── train_params.weight.npy │ │ ├── convolution_2d_stride_pad │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_bias.npy │ │ │ ├── delta_params.delta_weight.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.bias.npy │ │ │ └── train_params.weight.npy │ │ ├── linear_1d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_bias.npy │ │ │ ├── delta_params.delta_weight.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.bias.npy │ │ │ └── train_params.weight.npy │ │ ├── linear_3d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── delta_params.delta_bias.npy │ │ │ ├── delta_params.delta_weight.npy │ │ │ ├── forward.bottoms.0.npy │ │ │ ├── forward.tops.0.npy │ │ │ ├── train_params.bias.npy │ │ │ └── train_params.weight.npy │ │ ├── max_pooling_2d │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── forward.bottoms.0.npy │ │ │ └── forward.tops.0.npy │ │ └── relu │ │ │ ├── backward.bottom_deltas.0.npy │ │ │ ├── backward.bottoms.0.npy │ │ │ ├── backward.top_deltas.0.npy │ │ │ ├── case.json │ │ │ ├── forward.bottoms.0.npy │ │ │ └── forward.tops.0.npy │ ├── make_data_augmentation.py │ └── make_layer_data.py ├── layer_case_loader.ts └── sukiyaki.spec.ts ├── src ├── array_serializer.ts ├── forward_configuration.ts ├── layers │ ├── accuracy_layer.ts │ ├── batch_normalization_layer.ts │ ├── blob_data_layer.ts │ ├── branch_layer.ts │ ├── convolution_2d_layer.ts │ ├── data_augmentation_layer.ts │ ├── data_layer.ts │ ├── dropout_layer.ts │ ├── image_load_layer.ts │ ├── index.ts │ ├── layer.ts │ ├── layer_factory.ts │ ├── linear_layer.ts │ ├── loss_layer.ts │ ├── mnist_data_layer.ts │ ├── plus_layer.ts │ ├── pooling_2d_layer.ts │ ├── relu_layer.ts │ └── softmax_cross_entropy_layer.ts ├── network.ts ├── optimizer.ts ├── optimizers │ ├── index.ts │ ├── optimizer_momentum_sgd.ts │ └── optimizer_sgd.ts ├── sukiyaki.ts └── utils │ ├── array_helper.ts │ ├── dettmers_weight_compression.ts │ ├── im2col.ts │ └── mtimes_trans.ts ├── train_imagenet.ts ├── train_resnet.ts ├── tsconfig.json └── util ├── convert_images_to_blob.py ├── convert_images_to_blob_raw.py ├── convert_mnist.py ├── convert_weight.py ├── generate_resnet_def.py └── generate_resnet_identity_def.py /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | *.js 4 | *.js.map 5 | *.d.ts 6 | !browser/*.js 7 | browser/milsukiyaki2.js 8 | !docs/** 9 | !docs_raw/** 10 | 11 | example/mnist/data 12 | example/mnist/model 13 | !.gitkeep 14 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "起動", 6 | "type": "node", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/main.js", 9 | "stopOnEntry": false, 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "preLaunchTask": null, 13 | "runtimeExecutable": null, 14 | "runtimeArgs": [ 15 | "--nolazy" 16 | ], 17 | "env": { 18 | "NODE_ENV": "development" 19 | }, 20 | "externalConsole": false, 21 | "sourceMaps": true, 22 | "outDir": null 23 | }, 24 | { 25 | "name": "アタッチ", 26 | "type": "node", 27 | "request": "attach", 28 | "port": 5858, 29 | "address": "localhost", 30 | "restart": false, 31 | "sourceMaps": false, 32 | "outDir": null, 33 | "localRoot": "${workspaceRoot}", 34 | "remoteRoot": null 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "editor.tabSize": 2, 4 | "typescript.check.workspaceVersion": false 5 | } -------------------------------------------------------------------------------- /AUTHORS.txt: -------------------------------------------------------------------------------- 1 | Authors of sukiyaki2 2 | 3 | Masatoshi Hidaka 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Sukiyaki2 library 2 | The following license applies to all parts of this software except libraries 3 | in node_modules directory and individual source file which indicates otherwise. 4 | 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2016 Machine Intelligence Laboratory (The University of Tokyo) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | jQuery: 28 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 29 | 30 | This software consists of voluntary contributions made by many 31 | individuals. For exact contribution history, see the revision history 32 | available at https://github.com/jquery/jquery 33 | 34 | The following license applies to all parts of this software except as 35 | documented below: 36 | 37 | ==== 38 | 39 | Permission is hereby granted, free of charge, to any person obtaining 40 | a copy of this software and associated documentation files (the 41 | "Software"), to deal in the Software without restriction, including 42 | without limitation the rights to use, copy, modify, merge, publish, 43 | distribute, sublicense, and/or sell copies of the Software, and to 44 | permit persons to whom the Software is furnished to do so, subject to 45 | the following conditions: 46 | 47 | The above copyright notice and this permission notice shall be 48 | included in all copies or substantial portions of the Software. 49 | 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 51 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 52 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 53 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 54 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 55 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 56 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 57 | 58 | ==== 59 | 60 | All files located in the node_modules and external directories are 61 | externally maintained libraries used by this software which have their 62 | own licenses; we recommend you read them, as their terms may differ from 63 | the terms above. 64 | 65 | setImmediate: 66 | Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola 67 | 68 | Permission is hereby granted, free of charge, to any person obtaining 69 | a copy of this software and associated documentation files (the 70 | "Software"), to deal in the Software without restriction, including 71 | without limitation the rights to use, copy, modify, merge, publish, 72 | distribute, sublicense, and/or sell copies of the Software, and to 73 | permit persons to whom the Software is furnished to do so, subject to 74 | the following conditions: 75 | 76 | The above copyright notice and this permission notice shall be 77 | included in all copies or substantial portions of the Software. 78 | 79 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 80 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 81 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 82 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 83 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 84 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 85 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sukiyaki2 library 2 | Deep Learning Library for JavaScript 3 | 4 | Documents are under preparation. 5 | Currently, example of training MNIST digit recognition for node.js environment is provided. 6 | Code for distributed computing using web browser clients will be uploaded in near future. 7 | 8 | github.io page [Sukiyaki2](https://mil-tokyo.github.io/sukiyaki2/) [MILJS](https://mil-tokyo.github.io/miljs.html) 9 | 10 | # Build for use in node.js 11 | Since this project is written in TypeScript, transpiling to JavaScript is necessary. 12 | 13 | ```bash 14 | git clone https://github.com/mil-tokyo/sukiyaki2 15 | cd sukiyaki2 16 | npm install 17 | npm run build 18 | ``` 19 | 20 | On `npm install`, it installs [node-opencl](https://github.com/mikeseven/node-opencl) package for GPU computing which allows dramatically faster computation. 21 | In my environment (Ubuntu 14.04 + NVIDIA CUDA 7.5), installation with node-opencl requires additional environment variables. 22 | 23 | ```bash 24 | CPLUS_INCLUDE_PATH=/usr/local/cuda/include LIBRARY_PATH=/usr/local/cuda/lib64 npm install 25 | ``` 26 | 27 | # Example in node.js 28 | ## MNIST digit recognition training 29 | Run on root directory 30 | 31 | ```bash 32 | ./example/mnist/prepare.py 33 | ./example/mnist/train.sh 34 | ``` 35 | 36 | By default, GPU is not used. To try fast computation, 37 | 38 | ```bash 39 | ./example/mnist/train.sh cl 40 | ``` 41 | 42 | # Example in web browser 43 | They are in `docs/example` directory. 44 | 45 | Access to online demo from https://mil-tokyo.github.io/sukiyaki2/ 46 | -------------------------------------------------------------------------------- /apidoc/index.md: -------------------------------------------------------------------------------- 1 | # Sukiyaki2 library API reference 2 | 3 | - [Network construction](classes/network.html) 4 | - [Layer classes](classes/layer.html) 5 | - [Optimizer classes](classes/optimizer.html) 6 | -------------------------------------------------------------------------------- /bench/bench_base.ts: -------------------------------------------------------------------------------- 1 | import $M = require('milsushi2'); 2 | 3 | class BenchBase { 4 | name: string; 5 | setup(): any[] { 6 | return []; 7 | } 8 | 9 | run(callback: any, ...args: any[]): void { 10 | throw Error('Not implemented'); 11 | } 12 | } 13 | 14 | export = BenchBase; 15 | -------------------------------------------------------------------------------- /bench/conv.ts: -------------------------------------------------------------------------------- 1 | import $M = require('milsushi2'); 2 | import Sukiyaki = require('../index'); 3 | import BenchBase = require('./bench_base'); 4 | 5 | class conv extends BenchBase { 6 | layer: Sukiyaki.Layers.Convolution2DLayer; 7 | 8 | constructor(public params: {in_size: number, out_size: number, ksize: number, stride: number, pad: number}, public image_shape: number[]) { 9 | super(); 10 | this.name = 'conv ' + JSON.stringify(params) + ' with input ' + JSON.stringify(image_shape); 11 | } 12 | 13 | setup() { 14 | this.layer = new Sukiyaki.Layers.Convolution2DLayer(this.params); 15 | var input_image = $M.rand(...this.image_shape); 16 | return [input_image]; 17 | } 18 | 19 | run(callback: any, input_image: $M.Matrix): void { 20 | var config = new Sukiyaki.ForwardConfiguration(); 21 | config.devicetype = 'cpu'; 22 | config.phase = 'train'; 23 | this.layer['delta_weight'] = $M.zeros($M.size(this.layer['weight'])); 24 | this.layer['delta_bias'] = $M.zeros($M.size(this.layer['bias'])); 25 | this.layer.forward([input_image], config, (tops: $M.Matrix[]) => { 26 | // use top as top gradient 27 | var top_delta = tops[0]; 28 | this.layer.calculateUpdateParams([input_image], [top_delta], config, () => { 29 | this.layer.backward([input_image], [top_delta], config, (bottom_deltas: $M.Matrix[]) => { 30 | callback(); 31 | }) 32 | }); 33 | }); 34 | } 35 | } 36 | 37 | export = conv; 38 | -------------------------------------------------------------------------------- /bench/index.ts: -------------------------------------------------------------------------------- 1 | import $M = require('milsushi2'); 2 | 3 | declare var require; 4 | declare var process; 5 | declare var Buffer; 6 | var os = require('os'); 7 | var fs = require('fs'); 8 | var child_process = require('child_process'); 9 | var cl_enabled = Boolean(Number(process.env['TEST_CL'])); 10 | console.log('OpenCL ' + cl_enabled); 11 | var MatrixCL = null; 12 | if (cl_enabled) { 13 | $M.initcl(); 14 | } 15 | 16 | import BenchBase = require('./bench_base'); 17 | import conv = require('./conv'); 18 | import mtimes = require('./mtimes'); 19 | 20 | function time(f: BenchBase, n_run: number = 3, callback: any) { 21 | var elapsed = 0; 22 | var args = f.setup(); 23 | if (!args) { 24 | args = []; 25 | } 26 | console.log(f.name); 27 | var runtimes = []; 28 | var run_measure = () => { 29 | var time_begin = Date.now(); 30 | f.run(() => { 31 | if (cl_enabled) { 32 | $M.CL.finish(); 33 | } 34 | var time_end = Date.now(); 35 | var current_elapsed = time_end - time_begin; 36 | runtimes.push(current_elapsed); 37 | if (runtimes.length >= n_run + 1) { 38 | //get min-running time 39 | elapsed = Math.min.apply(null, runtimes); 40 | console.log('' + f.name + ': ' + elapsed + 'ms'); 41 | callback(); 42 | } else { 43 | run_measure(); 44 | } 45 | }, ...args); 46 | } 47 | 48 | run_measure(); 49 | } 50 | 51 | function time_all(f_array: BenchBase[], n_run?: number) { 52 | var call_next = () => { 53 | var f = f_array.shift(); 54 | if (f != null) { 55 | time(f, n_run, call_next); 56 | } else { 57 | console.log('finished all function'); 58 | } 59 | } 60 | 61 | call_next(); 62 | } 63 | 64 | function main() { 65 | time_all([new conv({in_size: 20, out_size: 50, ksize: 5, stride: 1, pad: 0}, [12, 12, 20, 64]), 66 | new mtimes(8*8*64, 50, 5*5*20)]); 67 | } 68 | 69 | main(); 70 | -------------------------------------------------------------------------------- /bench/mtimes.ts: -------------------------------------------------------------------------------- 1 | import $M = require('milsushi2'); 2 | import Sukiyaki = require('../index'); 3 | import BenchBase = require('./bench_base'); 4 | 5 | class mtimes extends BenchBase { 6 | constructor(public m: number, public n: number, public k: number) { 7 | super(); 8 | this.name = 'mtimes ' + m + ',' + n + ',' + k; 9 | } 10 | 11 | setup() { 12 | var a = $M.rand(this.m, this.k); 13 | var b = $M.rand(this.k, this.n); 14 | return [a, b]; 15 | } 16 | 17 | run(callback: any, a: $M.Matrix, b: $M.Matrix): void { 18 | var c = $M.mtimes(a, b); 19 | setImmediate(callback); 20 | } 21 | } 22 | 23 | export = mtimes; 24 | -------------------------------------------------------------------------------- /browser/header.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Sukiyaki2 library (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 3 | */ 4 | -------------------------------------------------------------------------------- /browser/run.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Sukiyaki sample on web browser 10 | 11 | 12 | -------------------------------------------------------------------------------- /do_browserify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | browserify index.js -o browser/milsukiyaki2.js -s milsukiyaki2 -p \[ browserify-header --file browser/header.js \] --external milsushi2 4 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/.nojekyll -------------------------------------------------------------------------------- /docs/api/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/api/assets/images/icons.png -------------------------------------------------------------------------------- /docs/api/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/api/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/api/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/api/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/api/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/api/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/api/assets/js/search.js: -------------------------------------------------------------------------------- 1 | var typedoc = typedoc || {};typedoc.search = typedoc.search || {};typedoc.search.data = {"kinds":{"32":"Variable","64":"Function","65536":"Type literal"},"rows":[{"id":0,"kind":65536,"name":"__type","url":"classes/convolution2dlayer.html#timer_vals.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"Convolution2DLayer.timer_vals"},{"id":1,"kind":65536,"name":"__type","url":"classes/network.html#layers.__type-4","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"Network.layers"},{"id":2,"kind":65536,"name":"__type","url":"classes/network.html#layer_instances.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"Network.layer_instances"},{"id":3,"kind":65536,"name":"__type","url":"classes/network.html#blobs_forward.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"Network.blobs_forward"},{"id":4,"kind":65536,"name":"__type","url":"classes/network.html#blobs_backward.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"Network.blobs_backward"},{"id":5,"kind":65536,"name":"__type","url":"classes/network.html#layer_time.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"Network.layer_time"},{"id":6,"kind":65536,"name":"__type","url":"classes/optimizersgd.html#last_deltas.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"OptimizerSGD.last_deltas"},{"id":7,"kind":64,"name":"train_mnist","url":"globals.html#train_mnist","classes":"tsd-kind-function"},{"id":8,"kind":64,"name":"train_imagenet","url":"globals.html#train_imagenet","classes":"tsd-kind-function"},{"id":9,"kind":32,"name":"process","url":"globals.html#process","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":10,"kind":32,"name":"cl_enabled","url":"globals.html#cl_enabled","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":11,"kind":32,"name":"MatrixCL","url":"globals.html#matrixcl","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":12,"kind":32,"name":"layer_test_cases","url":"globals.html#layer_test_cases","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":13,"kind":64,"name":"test_layer_case","url":"globals.html#test_layer_case","classes":"tsd-kind-function tsd-is-not-exported"},{"id":14,"kind":32,"name":"fixture_mean","url":"globals.html#fixture_mean","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":15,"kind":32,"name":"fixture_bottom","url":"globals.html#fixture_bottom","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":16,"kind":32,"name":"fixture_top","url":"globals.html#fixture_top","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":17,"kind":64,"name":"train_node","url":"globals.html#train_node","classes":"tsd-kind-function tsd-is-not-exported"},{"id":18,"kind":64,"name":"main","url":"globals.html#main","classes":"tsd-kind-function tsd-is-not-exported"},{"id":19,"kind":64,"name":"classify_node","url":"globals.html#classify_node","classes":"tsd-kind-function tsd-is-not-exported"},{"id":20,"kind":65536,"name":"__type","url":"classes/conv.html#__type","classes":"tsd-kind-type-literal tsd-parent-kind-class","parent":"conv"},{"id":21,"kind":32,"name":"require","url":"globals.html#require","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":22,"kind":32,"name":"Buffer","url":"globals.html#buffer","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":23,"kind":32,"name":"os","url":"globals.html#os","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":24,"kind":32,"name":"fs","url":"globals.html#fs","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":25,"kind":32,"name":"child_process","url":"globals.html#child_process","classes":"tsd-kind-variable tsd-is-not-exported"},{"id":26,"kind":64,"name":"time","url":"globals.html#time","classes":"tsd-kind-function tsd-is-not-exported"},{"id":27,"kind":64,"name":"time_all","url":"globals.html#time_all","classes":"tsd-kind-function tsd-is-not-exported"}]}; -------------------------------------------------------------------------------- /docs/examples/camera/camera_demo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var $M = milsushi2; 4 | var Sukiyaki = milsukiyaki2; 5 | var net; 6 | var stop_recognition = false; 7 | 8 | function write_status(msg) { 9 | var msg_box = $("input[name='status-msg']"); 10 | msg_box.val(msg); 11 | } 12 | 13 | $(function () { 14 | $("#stop-resume-recognition").click(stop_resume_recognition); 15 | 16 | write_status('Waiting the network weight to be loaded (3.4MB)'); 17 | setTimeout(wait_network_load, 100); 18 | }); 19 | 20 | function wait_network_load() { 21 | // network weight is loaded with defer tag, so wait until it is loaded 22 | if (typeof window.lenet_weight === 'undefined') { 23 | setTimeout(wait_network_load, 100); 24 | return; 25 | } 26 | 27 | write_status('Setting up network'); 28 | setTimeout(setup_network, 1); 29 | } 30 | 31 | function setup_network() { 32 | var netdef_json = [{ "params": { "random_crop": false, "random_flip": false, "scale": 0.00390625, "input_klass": "uint8", "out_shape": [28, 28] }, "type": "data_augmentation", "name": "aug_test", "outputs": ["augdata"], "inputs": ["data"] }, { "params": { "out_size": 20, "stride": 1, "pad": 0, "in_size": 1, "ksize": 5 }, "type": "convolution_2d", "name": "conv1", "outputs": ["conv1"], "inputs": ["augdata"] }, { "params": { "stride": 2, "pad": 0, "type": "max", "ksize": 2 }, "type": "pooling_2d", "name": "pool1", "outputs": ["pool1"], "inputs": ["conv1"] }, { "params": { "out_size": 50, "stride": 1, "pad": 0, "in_size": 20, "ksize": 5 }, "type": "convolution_2d", "name": "conv2", "outputs": ["conv2"], "inputs": ["pool1"] }, { "params": { "stride": 2, "pad": 0, "type": "max", "ksize": 2 }, "type": "pooling_2d", "name": "pool2", "outputs": ["pool2"], "inputs": ["conv2"] }, { "params": { "out_size": 500, "in_shape": [4, 4, 50] }, "type": "linear", "name": "fc3", "outputs": ["fc3"], "inputs": ["pool2"] }, { "params": {}, "type": "relu", "name": "relu3", "outputs": ["relu3"], "inputs": ["fc3"] }, { "params": { "out_size": 10, "in_shape": [500] }, "type": "linear", "name": "fc4", "outputs": ["pred"], "inputs": ["relu3"] }]; 33 | net = new Sukiyaki.Network(netdef_json); 34 | net.init(function () { 35 | Sukiyaki.ArraySerializer.load(lenet_weight["weight_packed"], net); 36 | write_status('Network loaded'); 37 | setup_camera(); 38 | }); 39 | } 40 | 41 | function setup_camera() { 42 | write_status('Initializing video input device'); 43 | navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia; 44 | var wURL = window.URL || window.webkitURL; 45 | var video = $("#camera-in")[0]; 46 | navigator.getUserMedia({ video: { facingMode: 'environment' }, audio: false }, 47 | function (stream) { 48 | video.src = wURL.createObjectURL(stream); 49 | write_status('Video initialization succeeded'); 50 | start_recognize(); 51 | }, 52 | function (err) { 53 | write_status('Video initialization failed: ' + err.name); 54 | }); 55 | } 56 | 57 | var dom_video; 58 | var canvas_context; 59 | function start_recognize() { 60 | dom_video = $("#camera-in")[0]; 61 | var canvas = $("#recognize-in")[0]; 62 | canvas_context = canvas.getContext('2d'); 63 | write_status('Recognizing'); 64 | setTimeout(do_recognize, 100); 65 | } 66 | 67 | function do_recognize() { 68 | canvas_context.drawImage(dom_video, 0, 0, 28, 28);// copy captured video to canvas 69 | var imagedata = canvas_context.getImageData(0, 0, 28, 28);// get pixel data from canvas 70 | var image = $M.typedarray2mat([4, 28, 28], 'uint8', new Uint8Array(imagedata.data));// channel, width, height (in fortran-order) 71 | image = image.get(1, $M.colon(), $M.colon());// extract single color channel 72 | image = $M.permute(image, [3, 2, 1]);// transpose to height, width, channel 73 | var recog_begin = Date.now(); 74 | net.forward({ 'data': image }, function () {// forward propagation 75 | var recog_end = Date.now(); 76 | var pred = net.blobs_forward['pred'];// prediction layer output 77 | var max_index = $M.argmax(pred).I.get();// get matrix index of highest score (1-origin) 78 | var predicted_number = max_index - 1; 79 | document.getElementById('result').textContent = predicted_number.toString(); 80 | net.release(); 81 | write_status('Recognition: ' + (recog_end - recog_begin) + 'ms'); 82 | 83 | if (!stop_recognition) { 84 | setTimeout(do_recognize, 100); 85 | } 86 | }); 87 | } 88 | 89 | function stop_resume_recognition() { 90 | if (stop_recognition) { 91 | // resume 92 | stop_recognition = false; 93 | $("#stop-resume-recognition").text("Stop"); 94 | setTimeout(do_recognize, 100); 95 | } else { 96 | // stop 97 | $("#stop-resume-recognition").text("Resume"); 98 | stop_recognition = true; 99 | } 100 | } -------------------------------------------------------------------------------- /docs/examples/camera/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sukiyaki2 Camera Digit Recognition 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |

Sukiyaki2 demo: digit recognition from camera

18 |
19 | 20 | Input: 21 | => Predicted: - 22 | 23 |
24 |
25 | Resized image: 26 |
27 | 28 |
29 |
30 | Supported: Firefox on PCs and Android. 31 | iPhone is not supported because its browser does not support camera capture. 32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/examples/mnist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sukiyaki2 Demo: Deep Learning of Digit Recognition 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |

Sukiyaki2 Demo: Deep Learning of Digit Recognition

18 |
19 | Dataset load: 20 |
21 |
Test image: 22 | 23 | => Predicted: - 24 |
25 | Mean accuracy: -% 26 |
27 |
28 |
29 | 30 | Learning rate: 31 | 36 | 37 |
38 |
39 | Trains convolutional neural network (CNN) on the browser using MNIST dataset (by Yann LeCun).
40 | CNN shape
41 | Powered by Sukiyaki2 framework of MILJS.
42 | Using pure JavaScript (running on CPU); WebCL support is omitted for simplicity (this demo is not tuned for speed).

43 | Benchmarks
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
Images/secDeviceBrowser
79Dell Alienware Area-51,
Intel Core i7-5960X (2015)
Firefox
67Macbook Pro (2013)Firefox
64iPhone SE (2016)Safari
6.3Nexus 7 (2012)Chrome
53 |
54 |
55 | Machine Intelligence Laboratory, The University of Tokyo 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /docs/examples/mnist/mnist_demo.css: -------------------------------------------------------------------------------- 1 | div.demo-view { 2 | font-size: 200%; 3 | } 4 | 5 | #recognize-in { 6 | width: 56px; 7 | height: 56px; 8 | } -------------------------------------------------------------------------------- /docs/examples/mnist/network_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/examples/mnist/network_shape.png -------------------------------------------------------------------------------- /docs/examples/mnist/network_shape_rot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/examples/mnist/network_shape_rot.png -------------------------------------------------------------------------------- /docs/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sukiyaki2 documantation 5 | Sukiyaki2 is a deep learning library for JavaScript. 6 | 7 | https://mil-tokyo.github.com/sukiyaki2/ 8 | 9 | Sun, 08 Jan 2017 11:14:12 +0900 10 | Sun, 08 Jan 2017 11:14:12 +0900 11 | Jekyll v2.4.0 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/images/ss_camerademo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs/images/ss_camerademo.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Sukiyaki2 documantation 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 51 | 52 | 53 |
54 |
55 |
56 |

Sukiyaki2

57 | 58 |

This is the document page for Sukiyaki2, a deep learning library for JavaScript.

59 | 60 |

API Reference

61 | 62 |
63 | Demos:
64 | Training of digit recognition
65 | Digit recognition from camera 66 | 67 |
68 | 69 |

Posts

70 | 71 |
    72 | 73 |
74 | 75 |

subscribe via RSS

76 | 77 |
78 | 79 |
80 |
81 | 82 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/setup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Sukiyaki2 documantation 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 51 | 52 | 53 |
54 |
55 |

Setup of Sukiyaki2 and introduction of basic usage

56 | 57 |

Sukiyaki2 is a deep learning library for JavaScript. 58 | Sukiyaki2 is designed to achive distributed training of Deep Neural Networks using ordinary personal 59 | computers by implementing system in JavaScript, which can run on web browsers. 60 | For training in single computer, it is recommeneded to use node.js environment 61 | because it is faster and can access filesystem directly 62 | (even in web browser, setting up a server to supply dataset is needed).

63 | 64 |

In this page, the way of setting up Sukiyaki2 on node.js environment and running basic example is described.

65 | 66 |

Setup for node.js

67 |

Since this project is written in TypeScript, transpiling to JavaScript is necessary.

68 | 69 |
git clone https://github.com/mil-tokyo/sukiyaki2
 70 | cd sukiyaki2
 71 | npm install
 72 | npm run build
 73 | 
74 | 75 |

On npm install, it installs node-opencl package for GPU computing which allows dramatically faster computation. 76 | In my environment (Ubuntu 14.04 + NVIDIA CUDA 7.5), installation with node-opencl requires additional environment variables.

77 | 78 |
CPLUS_INCLUDE_PATH=/usr/local/cuda/include LIBRARY_PATH=/usr/local/cuda/lib64 npm install
 79 | 
80 | 81 |

Running MNIST digit recognition training

82 |

This example trains Deep Convolutional Neural Networks (DCNNs) using “MNIST handwritten digit database”.

83 | 84 | 85 |
86 |
87 | 88 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /docs_raw/jekyll/.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache/ 2 | -------------------------------------------------------------------------------- /docs_raw/jekyll/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'github-pages', group: :jekyll_plugins 3 | gem "minima" 4 | -------------------------------------------------------------------------------- /docs_raw/jekyll/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | RedCloth (4.2.9) 5 | activesupport (5.0.0.1) 6 | concurrent-ruby (~> 1.0, >= 1.0.2) 7 | i18n (~> 0.7) 8 | minitest (~> 5.1) 9 | tzinfo (~> 1.1) 10 | addressable (2.4.0) 11 | blankslate (2.1.2.4) 12 | classifier-reborn (2.0.4) 13 | fast-stemmer (~> 1.0) 14 | coffee-script (2.4.1) 15 | coffee-script-source 16 | execjs 17 | coffee-script-source (1.11.1) 18 | colorator (0.1) 19 | concurrent-ruby (1.0.2) 20 | ethon (0.9.1) 21 | ffi (>= 1.3.0) 22 | execjs (2.7.0) 23 | faraday (0.10.0) 24 | multipart-post (>= 1.2, < 3) 25 | fast-stemmer (1.0.2) 26 | ffi (1.9.14) 27 | gemoji (2.1.0) 28 | github-pages (39) 29 | RedCloth (= 4.2.9) 30 | github-pages-health-check (~> 0.2) 31 | jekyll (= 2.4.0) 32 | jekyll-coffeescript (= 1.0.1) 33 | jekyll-feed (= 0.3.1) 34 | jekyll-mentions (= 0.2.1) 35 | jekyll-redirect-from (= 0.8.0) 36 | jekyll-sass-converter (= 1.3.0) 37 | jekyll-sitemap (= 0.8.1) 38 | jemoji (= 0.5.0) 39 | kramdown (= 1.5.0) 40 | liquid (= 2.6.2) 41 | maruku (= 0.7.0) 42 | mercenary (~> 0.3) 43 | pygments.rb (= 0.6.3) 44 | rdiscount (= 2.1.7) 45 | redcarpet (= 3.3.2) 46 | terminal-table (~> 1.4) 47 | github-pages-health-check (0.3.2) 48 | net-dns (~> 0.6) 49 | public_suffix (~> 1.4) 50 | typhoeus (~> 0.7) 51 | html-pipeline (1.9.0) 52 | activesupport (>= 2) 53 | nokogiri (~> 1.4) 54 | i18n (0.7.0) 55 | jekyll (2.4.0) 56 | classifier-reborn (~> 2.0) 57 | colorator (~> 0.1) 58 | jekyll-coffeescript (~> 1.0) 59 | jekyll-gist (~> 1.0) 60 | jekyll-paginate (~> 1.0) 61 | jekyll-sass-converter (~> 1.0) 62 | jekyll-watch (~> 1.1) 63 | kramdown (~> 1.3) 64 | liquid (~> 2.6.1) 65 | mercenary (~> 0.3.3) 66 | pygments.rb (~> 0.6.0) 67 | redcarpet (~> 3.1) 68 | safe_yaml (~> 1.0) 69 | toml (~> 0.1.0) 70 | jekyll-coffeescript (1.0.1) 71 | coffee-script (~> 2.2) 72 | jekyll-feed (0.3.1) 73 | jekyll-gist (1.4.0) 74 | octokit (~> 4.2) 75 | jekyll-mentions (0.2.1) 76 | html-pipeline (~> 1.9.0) 77 | jekyll (~> 2.0) 78 | jekyll-paginate (1.1.0) 79 | jekyll-redirect-from (0.8.0) 80 | jekyll (>= 2.0) 81 | jekyll-sass-converter (1.3.0) 82 | sass (~> 3.2) 83 | jekyll-sitemap (0.8.1) 84 | jekyll-watch (1.5.0) 85 | listen (~> 3.0, < 3.1) 86 | jemoji (0.5.0) 87 | gemoji (~> 2.0) 88 | html-pipeline (~> 1.9) 89 | jekyll (>= 2.0) 90 | kramdown (1.5.0) 91 | liquid (2.6.2) 92 | listen (3.0.8) 93 | rb-fsevent (~> 0.9, >= 0.9.4) 94 | rb-inotify (~> 0.9, >= 0.9.7) 95 | maruku (0.7.0) 96 | mercenary (0.3.6) 97 | mini_portile2 (2.1.0) 98 | minima (2.0.0) 99 | minitest (5.10.1) 100 | multipart-post (2.0.0) 101 | net-dns (0.8.0) 102 | nokogiri (1.6.8.1) 103 | mini_portile2 (~> 2.1.0) 104 | octokit (4.6.2) 105 | sawyer (~> 0.8.0, >= 0.5.3) 106 | parslet (1.5.0) 107 | blankslate (~> 2.0) 108 | posix-spawn (0.3.12) 109 | public_suffix (1.5.3) 110 | pygments.rb (0.6.3) 111 | posix-spawn (~> 0.3.6) 112 | yajl-ruby (~> 1.2.0) 113 | rb-fsevent (0.9.8) 114 | rb-inotify (0.9.7) 115 | ffi (>= 0.5.0) 116 | rdiscount (2.1.7) 117 | redcarpet (3.3.2) 118 | safe_yaml (1.0.4) 119 | sass (3.4.22) 120 | sawyer (0.8.1) 121 | addressable (>= 2.3.5, < 2.6) 122 | faraday (~> 0.8, < 1.0) 123 | terminal-table (1.7.3) 124 | unicode-display_width (~> 1.1.1) 125 | thread_safe (0.3.5) 126 | toml (0.1.2) 127 | parslet (~> 1.5.0) 128 | typhoeus (0.8.0) 129 | ethon (>= 0.8.0) 130 | tzinfo (1.2.2) 131 | thread_safe (~> 0.1) 132 | unicode-display_width (1.1.1) 133 | yajl-ruby (1.2.1) 134 | 135 | PLATFORMS 136 | ruby 137 | 138 | DEPENDENCIES 139 | github-pages 140 | minima 141 | 142 | BUNDLED WITH 143 | 1.13.6 144 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_config.yml: -------------------------------------------------------------------------------- 1 | # Site settings 2 | title: Sukiyaki2 documantation 3 | email: miljs@mi.t.u-tokyo.ac.jp 4 | description: > # this means to ignore newlines until "baseurl:" 5 | Sukiyaki2 is a deep learning library for JavaScript. 6 | baseurl: "/sukiyaki2" # the subpath of your site, e.g. /blog/ 7 | url: "https://mil-tokyo.github.com" # the base hostname & protocol for your site 8 | github_username: mil-tokyo 9 | theme: minima 10 | 11 | # Build settings 12 | markdown: kramdown 13 | kramdown: 14 | input: GFM 15 | hard_wrap: false 16 | keep_files: ["api", ".nojekyll"] 17 | exclude: ["Gemfile", "Gemfile.lock"] 18 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_includes/footer.html: -------------------------------------------------------------------------------- 1 | 56 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %} 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_includes/header.html: -------------------------------------------------------------------------------- 1 | 28 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head.html %} 5 | 6 | 7 | 8 | {% include header.html %} 9 | 10 |
11 |
12 | {{ content }} 13 |
14 |
15 | 16 | {% include footer.html %} 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | 6 |
7 |

{{ page.title }}

8 |
9 | 10 |
11 | {{ content }} 12 |
13 | 14 |
15 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | 6 |
7 |

{{ page.title }}

8 | 9 |
10 | 11 |
12 | {{ content }} 13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_sass/_base.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Reset some basic elements 3 | */ 4 | body, h1, h2, h3, h4, h5, h6, 5 | p, blockquote, pre, hr, 6 | dl, dd, ol, ul, figure { 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | 12 | 13 | /** 14 | * Basic styling 15 | */ 16 | body { 17 | font-family: $base-font-family; 18 | font-size: $base-font-size; 19 | line-height: $base-line-height; 20 | font-weight: 300; 21 | color: $text-color; 22 | background-color: $background-color; 23 | -webkit-text-size-adjust: 100%; 24 | } 25 | 26 | 27 | 28 | /** 29 | * Set `margin-bottom` to maintain vertical rhythm 30 | */ 31 | h1, h2, h3, h4, h5, h6, 32 | p, blockquote, pre, 33 | ul, ol, dl, figure, 34 | %vertical-rhythm { 35 | margin-bottom: $spacing-unit / 2; 36 | } 37 | 38 | 39 | 40 | /** 41 | * Images 42 | */ 43 | img { 44 | max-width: 100%; 45 | vertical-align: middle; 46 | } 47 | 48 | 49 | 50 | /** 51 | * Figures 52 | */ 53 | figure > img { 54 | display: block; 55 | } 56 | 57 | figcaption { 58 | font-size: $small-font-size; 59 | } 60 | 61 | 62 | 63 | /** 64 | * Lists 65 | */ 66 | ul, ol { 67 | margin-left: $spacing-unit; 68 | } 69 | 70 | li { 71 | > ul, 72 | > ol { 73 | margin-bottom: 0; 74 | } 75 | } 76 | 77 | 78 | 79 | /** 80 | * Headings 81 | */ 82 | h1, h2, h3, h4, h5, h6 { 83 | font-weight: 300; 84 | } 85 | 86 | 87 | 88 | /** 89 | * Links 90 | */ 91 | a { 92 | color: $brand-color; 93 | text-decoration: none; 94 | 95 | &:visited { 96 | color: darken($brand-color, 15%); 97 | } 98 | 99 | &:hover { 100 | color: $text-color; 101 | text-decoration: underline; 102 | } 103 | } 104 | 105 | 106 | 107 | /** 108 | * Blockquotes 109 | */ 110 | blockquote { 111 | color: $grey-color; 112 | border-left: 4px solid $grey-color-light; 113 | padding-left: $spacing-unit / 2; 114 | font-size: 18px; 115 | letter-spacing: -1px; 116 | font-style: italic; 117 | 118 | > :last-child { 119 | margin-bottom: 0; 120 | } 121 | } 122 | 123 | 124 | 125 | /** 126 | * Code formatting 127 | */ 128 | pre, 129 | code { 130 | font-size: 15px; 131 | border: 1px solid $grey-color-light; 132 | border-radius: 3px; 133 | background-color: #eef; 134 | } 135 | 136 | code { 137 | padding: 1px 5px; 138 | } 139 | 140 | pre { 141 | padding: 8px 12px; 142 | overflow-x: scroll; 143 | 144 | > code { 145 | border: 0; 146 | padding-right: 0; 147 | padding-left: 0; 148 | } 149 | } 150 | 151 | 152 | 153 | /** 154 | * Wrapper 155 | */ 156 | .wrapper { 157 | max-width: -webkit-calc(800px - (#{$spacing-unit} * 2)); 158 | max-width: calc(800px - (#{$spacing-unit} * 2)); 159 | margin-right: auto; 160 | margin-left: auto; 161 | padding-right: $spacing-unit; 162 | padding-left: $spacing-unit; 163 | @extend %clearfix; 164 | 165 | @include media-query($on-laptop) { 166 | max-width: -webkit-calc(800px - (#{$spacing-unit})); 167 | max-width: calc(800px - (#{$spacing-unit})); 168 | padding-right: $spacing-unit / 2; 169 | padding-left: $spacing-unit / 2; 170 | } 171 | } 172 | 173 | 174 | 175 | /** 176 | * Clearfix 177 | */ 178 | %clearfix { 179 | 180 | &:after { 181 | content: ""; 182 | display: table; 183 | clear: both; 184 | } 185 | } 186 | 187 | 188 | 189 | /** 190 | * Icons 191 | */ 192 | .icon { 193 | 194 | > svg { 195 | display: inline-block; 196 | width: 16px; 197 | height: 16px; 198 | vertical-align: middle; 199 | 200 | path { 201 | fill: $grey-color; 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_sass/_layout.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Site header 3 | */ 4 | .site-header { 5 | border-top: 5px solid $grey-color-dark; 6 | border-bottom: 1px solid $grey-color-light; 7 | min-height: 56px; 8 | 9 | // Positioning context for the mobile navigation icon 10 | position: relative; 11 | } 12 | 13 | .site-title { 14 | font-size: 26px; 15 | line-height: 56px; 16 | letter-spacing: -1px; 17 | margin-bottom: 0; 18 | float: left; 19 | 20 | &, 21 | &:visited { 22 | color: $grey-color-dark; 23 | } 24 | } 25 | 26 | .site-nav { 27 | float: right; 28 | line-height: 56px; 29 | 30 | .menu-icon { 31 | display: none; 32 | } 33 | 34 | .page-link { 35 | color: $text-color; 36 | line-height: $base-line-height; 37 | 38 | // Gaps between nav items, but not on the first one 39 | &:not(:first-child) { 40 | margin-left: 20px; 41 | } 42 | } 43 | 44 | @include media-query($on-palm) { 45 | position: absolute; 46 | top: 9px; 47 | right: 30px; 48 | background-color: $background-color; 49 | border: 1px solid $grey-color-light; 50 | border-radius: 5px; 51 | text-align: right; 52 | 53 | .menu-icon { 54 | display: block; 55 | float: right; 56 | width: 36px; 57 | height: 26px; 58 | line-height: 0; 59 | padding-top: 10px; 60 | text-align: center; 61 | 62 | > svg { 63 | width: 18px; 64 | height: 15px; 65 | 66 | path { 67 | fill: $grey-color-dark; 68 | } 69 | } 70 | } 71 | 72 | .trigger { 73 | clear: both; 74 | display: none; 75 | } 76 | 77 | &:hover .trigger { 78 | display: block; 79 | padding-bottom: 5px; 80 | } 81 | 82 | .page-link { 83 | display: block; 84 | padding: 5px 10px; 85 | } 86 | } 87 | } 88 | 89 | 90 | 91 | /** 92 | * Site footer 93 | */ 94 | .site-footer { 95 | border-top: 1px solid $grey-color-light; 96 | padding: $spacing-unit 0; 97 | } 98 | 99 | .footer-heading { 100 | font-size: 18px; 101 | margin-bottom: $spacing-unit / 2; 102 | } 103 | 104 | .contact-list, 105 | .social-media-list { 106 | list-style: none; 107 | margin-left: 0; 108 | } 109 | 110 | .footer-col-wrapper { 111 | font-size: 15px; 112 | color: $grey-color; 113 | margin-left: -$spacing-unit / 2; 114 | @extend %clearfix; 115 | } 116 | 117 | .footer-col { 118 | float: left; 119 | margin-bottom: $spacing-unit / 2; 120 | padding-left: $spacing-unit / 2; 121 | } 122 | 123 | .footer-col-1 { 124 | width: -webkit-calc(35% - (#{$spacing-unit} / 2)); 125 | width: calc(35% - (#{$spacing-unit} / 2)); 126 | } 127 | 128 | .footer-col-2 { 129 | width: -webkit-calc(20% - (#{$spacing-unit} / 2)); 130 | width: calc(20% - (#{$spacing-unit} / 2)); 131 | } 132 | 133 | .footer-col-3 { 134 | width: -webkit-calc(45% - (#{$spacing-unit} / 2)); 135 | width: calc(45% - (#{$spacing-unit} / 2)); 136 | } 137 | 138 | @include media-query($on-laptop) { 139 | .footer-col-1, 140 | .footer-col-2 { 141 | width: -webkit-calc(50% - (#{$spacing-unit} / 2)); 142 | width: calc(50% - (#{$spacing-unit} / 2)); 143 | } 144 | 145 | .footer-col-3 { 146 | width: -webkit-calc(100% - (#{$spacing-unit} / 2)); 147 | width: calc(100% - (#{$spacing-unit} / 2)); 148 | } 149 | } 150 | 151 | @include media-query($on-palm) { 152 | .footer-col { 153 | float: none; 154 | width: -webkit-calc(100% - (#{$spacing-unit} / 2)); 155 | width: calc(100% - (#{$spacing-unit} / 2)); 156 | } 157 | } 158 | 159 | 160 | 161 | /** 162 | * Page content 163 | */ 164 | .page-content { 165 | padding: $spacing-unit 0; 166 | } 167 | 168 | .page-heading { 169 | font-size: 20px; 170 | } 171 | 172 | .post-list { 173 | margin-left: 0; 174 | list-style: none; 175 | 176 | > li { 177 | margin-bottom: $spacing-unit; 178 | } 179 | } 180 | 181 | .post-meta { 182 | font-size: $small-font-size; 183 | color: $grey-color; 184 | } 185 | 186 | .post-link { 187 | display: block; 188 | font-size: 24px; 189 | } 190 | 191 | 192 | 193 | /** 194 | * Posts 195 | */ 196 | .post-header { 197 | margin-bottom: $spacing-unit; 198 | } 199 | 200 | .post-title { 201 | font-size: 42px; 202 | letter-spacing: -1px; 203 | line-height: 1; 204 | 205 | @include media-query($on-laptop) { 206 | font-size: 36px; 207 | } 208 | } 209 | 210 | .post-content { 211 | margin-bottom: $spacing-unit; 212 | 213 | h2 { 214 | font-size: 32px; 215 | 216 | @include media-query($on-laptop) { 217 | font-size: 28px; 218 | } 219 | } 220 | 221 | h3 { 222 | font-size: 26px; 223 | 224 | @include media-query($on-laptop) { 225 | font-size: 22px; 226 | } 227 | } 228 | 229 | h4 { 230 | font-size: 20px; 231 | 232 | @include media-query($on-laptop) { 233 | font-size: 18px; 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /docs_raw/jekyll/_sass/_syntax-highlighting.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Syntax highlighting styles 3 | */ 4 | .highlight { 5 | background: #fff; 6 | @extend %vertical-rhythm; 7 | 8 | .c { color: #998; font-style: italic } // Comment 9 | .err { color: #a61717; background-color: #e3d2d2 } // Error 10 | .k { font-weight: bold } // Keyword 11 | .o { font-weight: bold } // Operator 12 | .cm { color: #998; font-style: italic } // Comment.Multiline 13 | .cp { color: #999; font-weight: bold } // Comment.Preproc 14 | .c1 { color: #998; font-style: italic } // Comment.Single 15 | .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special 16 | .gd { color: #000; background-color: #fdd } // Generic.Deleted 17 | .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific 18 | .ge { font-style: italic } // Generic.Emph 19 | .gr { color: #a00 } // Generic.Error 20 | .gh { color: #999 } // Generic.Heading 21 | .gi { color: #000; background-color: #dfd } // Generic.Inserted 22 | .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific 23 | .go { color: #888 } // Generic.Output 24 | .gp { color: #555 } // Generic.Prompt 25 | .gs { font-weight: bold } // Generic.Strong 26 | .gu { color: #aaa } // Generic.Subheading 27 | .gt { color: #a00 } // Generic.Traceback 28 | .kc { font-weight: bold } // Keyword.Constant 29 | .kd { font-weight: bold } // Keyword.Declaration 30 | .kp { font-weight: bold } // Keyword.Pseudo 31 | .kr { font-weight: bold } // Keyword.Reserved 32 | .kt { color: #458; font-weight: bold } // Keyword.Type 33 | .m { color: #099 } // Literal.Number 34 | .s { color: #d14 } // Literal.String 35 | .na { color: #008080 } // Name.Attribute 36 | .nb { color: #0086B3 } // Name.Builtin 37 | .nc { color: #458; font-weight: bold } // Name.Class 38 | .no { color: #008080 } // Name.Constant 39 | .ni { color: #800080 } // Name.Entity 40 | .ne { color: #900; font-weight: bold } // Name.Exception 41 | .nf { color: #900; font-weight: bold } // Name.Function 42 | .nn { color: #555 } // Name.Namespace 43 | .nt { color: #000080 } // Name.Tag 44 | .nv { color: #008080 } // Name.Variable 45 | .ow { font-weight: bold } // Operator.Word 46 | .w { color: #bbb } // Text.Whitespace 47 | .mf { color: #099 } // Literal.Number.Float 48 | .mh { color: #099 } // Literal.Number.Hex 49 | .mi { color: #099 } // Literal.Number.Integer 50 | .mo { color: #099 } // Literal.Number.Oct 51 | .sb { color: #d14 } // Literal.String.Backtick 52 | .sc { color: #d14 } // Literal.String.Char 53 | .sd { color: #d14 } // Literal.String.Doc 54 | .s2 { color: #d14 } // Literal.String.Double 55 | .se { color: #d14 } // Literal.String.Escape 56 | .sh { color: #d14 } // Literal.String.Heredoc 57 | .si { color: #d14 } // Literal.String.Interpol 58 | .sx { color: #d14 } // Literal.String.Other 59 | .sr { color: #009926 } // Literal.String.Regex 60 | .s1 { color: #d14 } // Literal.String.Single 61 | .ss { color: #990073 } // Literal.String.Symbol 62 | .bp { color: #999 } // Name.Builtin.Pseudo 63 | .vc { color: #008080 } // Name.Variable.Class 64 | .vg { color: #008080 } // Name.Variable.Global 65 | .vi { color: #008080 } // Name.Variable.Instance 66 | .il { color: #099 } // Literal.Number.Integer.Long 67 | } 68 | -------------------------------------------------------------------------------- /docs_raw/jekyll/css/main.scss: -------------------------------------------------------------------------------- 1 | --- 2 | # Only the main Sass file needs front matter (the dashes are enough) 3 | --- 4 | @charset "utf-8"; 5 | 6 | 7 | 8 | // Our variables 9 | $base-font-family: Helvetica, Arial, sans-serif; 10 | $base-font-size: 16px; 11 | $small-font-size: $base-font-size * 0.875; 12 | $base-line-height: 1.5; 13 | 14 | $spacing-unit: 30px; 15 | 16 | $text-color: #111; 17 | $background-color: #fdfdfd; 18 | $brand-color: #2a7ae2; 19 | 20 | $grey-color: #828282; 21 | $grey-color-light: lighten($grey-color, 40%); 22 | $grey-color-dark: darken($grey-color, 25%); 23 | 24 | $on-palm: 600px; 25 | $on-laptop: 800px; 26 | 27 | 28 | 29 | // Using media queries with like this: 30 | // @include media-query($palm) { 31 | // .wrapper { 32 | // padding-right: $spacing-unit / 2; 33 | // padding-left: $spacing-unit / 2; 34 | // } 35 | // } 36 | @mixin media-query($device) { 37 | @media screen and (max-width: $device) { 38 | @content; 39 | } 40 | } 41 | 42 | 43 | 44 | // Import partials from `sass_dir` (defaults to `_sass`) 45 | @import 46 | "base", 47 | "layout", 48 | "syntax-highlighting" 49 | ; 50 | -------------------------------------------------------------------------------- /docs_raw/jekyll/examples/camera/camera_demo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var $M = milsushi2; 4 | var Sukiyaki = milsukiyaki2; 5 | var net; 6 | var stop_recognition = false; 7 | 8 | function write_status(msg) { 9 | var msg_box = $("input[name='status-msg']"); 10 | msg_box.val(msg); 11 | } 12 | 13 | $(function () { 14 | $("#stop-resume-recognition").click(stop_resume_recognition); 15 | 16 | write_status('Waiting the network weight to be loaded (3.4MB)'); 17 | setTimeout(wait_network_load, 100); 18 | }); 19 | 20 | function wait_network_load() { 21 | // network weight is loaded with defer tag, so wait until it is loaded 22 | if (typeof window.lenet_weight === 'undefined') { 23 | setTimeout(wait_network_load, 100); 24 | return; 25 | } 26 | 27 | write_status('Setting up network'); 28 | setTimeout(setup_network, 1); 29 | } 30 | 31 | function setup_network() { 32 | var netdef_json = [{ "params": { "random_crop": false, "random_flip": false, "scale": 0.00390625, "input_klass": "uint8", "out_shape": [28, 28] }, "type": "data_augmentation", "name": "aug_test", "outputs": ["augdata"], "inputs": ["data"] }, { "params": { "out_size": 20, "stride": 1, "pad": 0, "in_size": 1, "ksize": 5 }, "type": "convolution_2d", "name": "conv1", "outputs": ["conv1"], "inputs": ["augdata"] }, { "params": { "stride": 2, "pad": 0, "type": "max", "ksize": 2 }, "type": "pooling_2d", "name": "pool1", "outputs": ["pool1"], "inputs": ["conv1"] }, { "params": { "out_size": 50, "stride": 1, "pad": 0, "in_size": 20, "ksize": 5 }, "type": "convolution_2d", "name": "conv2", "outputs": ["conv2"], "inputs": ["pool1"] }, { "params": { "stride": 2, "pad": 0, "type": "max", "ksize": 2 }, "type": "pooling_2d", "name": "pool2", "outputs": ["pool2"], "inputs": ["conv2"] }, { "params": { "out_size": 500, "in_shape": [4, 4, 50] }, "type": "linear", "name": "fc3", "outputs": ["fc3"], "inputs": ["pool2"] }, { "params": {}, "type": "relu", "name": "relu3", "outputs": ["relu3"], "inputs": ["fc3"] }, { "params": { "out_size": 10, "in_shape": [500] }, "type": "linear", "name": "fc4", "outputs": ["pred"], "inputs": ["relu3"] }]; 33 | net = new Sukiyaki.Network(netdef_json); 34 | net.init(function () { 35 | Sukiyaki.ArraySerializer.load(lenet_weight["weight_packed"], net); 36 | write_status('Network loaded'); 37 | setup_camera(); 38 | }); 39 | } 40 | 41 | function setup_camera() { 42 | write_status('Initializing video input device'); 43 | navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia; 44 | var wURL = window.URL || window.webkitURL; 45 | var video = $("#camera-in")[0]; 46 | navigator.getUserMedia({ video: { facingMode: 'environment' }, audio: false }, 47 | function (stream) { 48 | video.src = wURL.createObjectURL(stream); 49 | write_status('Video initialization succeeded'); 50 | start_recognize(); 51 | }, 52 | function (err) { 53 | write_status('Video initialization failed: ' + err.name); 54 | }); 55 | } 56 | 57 | var dom_video; 58 | var canvas_context; 59 | function start_recognize() { 60 | dom_video = $("#camera-in")[0]; 61 | var canvas = $("#recognize-in")[0]; 62 | canvas_context = canvas.getContext('2d'); 63 | write_status('Recognizing'); 64 | setTimeout(do_recognize, 100); 65 | } 66 | 67 | function do_recognize() { 68 | canvas_context.drawImage(dom_video, 0, 0, 28, 28);// copy captured video to canvas 69 | var imagedata = canvas_context.getImageData(0, 0, 28, 28);// get pixel data from canvas 70 | var image = $M.typedarray2mat([4, 28, 28], 'uint8', new Uint8Array(imagedata.data));// channel, width, height (in fortran-order) 71 | image = image.get(1, $M.colon(), $M.colon());// extract single color channel 72 | image = $M.permute(image, [3, 2, 1]);// transpose to height, width, channel 73 | var recog_begin = Date.now(); 74 | net.forward({ 'data': image }, function () {// forward propagation 75 | var recog_end = Date.now(); 76 | var pred = net.blobs_forward['pred'];// prediction layer output 77 | var max_index = $M.argmax(pred).I.get();// get matrix index of highest score (1-origin) 78 | var predicted_number = max_index - 1; 79 | document.getElementById('result').textContent = predicted_number.toString(); 80 | net.release(); 81 | write_status('Recognition: ' + (recog_end - recog_begin) + 'ms'); 82 | 83 | if (!stop_recognition) { 84 | setTimeout(do_recognize, 100); 85 | } 86 | }); 87 | } 88 | 89 | function stop_resume_recognition() { 90 | if (stop_recognition) { 91 | // resume 92 | stop_recognition = false; 93 | $("#stop-resume-recognition").text("Stop"); 94 | setTimeout(do_recognize, 100); 95 | } else { 96 | // stop 97 | $("#stop-resume-recognition").text("Resume"); 98 | stop_recognition = true; 99 | } 100 | } -------------------------------------------------------------------------------- /docs_raw/jekyll/examples/camera/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sukiyaki2 Camera Digit Recognition 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |

Sukiyaki2 demo: digit recognition from camera

18 |
19 | 20 | Input: 21 | => Predicted: - 22 | 23 |
24 |
25 | Resized image: 26 |
27 | 28 |
29 |
30 | Supported: Firefox on PCs and Android. 31 | iPhone is not supported because its browser does not support camera capture. 32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /docs_raw/jekyll/examples/mnist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sukiyaki2 Demo: Deep Learning of Digit Recognition 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |

Sukiyaki2 Demo: Deep Learning of Digit Recognition

18 |
19 | Dataset load: 20 |
21 |
Test image: 22 | 23 | => Predicted: - 24 |
25 | Mean accuracy: -% 26 |
27 |
28 |
29 | 30 | Learning rate: 31 | 36 | 37 |
38 |
39 | Trains convolutional neural network (CNN) on the browser using MNIST dataset (by Yann LeCun).
40 | CNN shape
41 | Powered by Sukiyaki2 framework of MILJS.
42 | Using pure JavaScript (running on CPU); WebCL support is omitted for simplicity (this demo is not tuned for speed).

43 | Benchmarks
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
Images/secDeviceBrowser
79Dell Alienware Area-51,
Intel Core i7-5960X (2015)
Firefox
67Macbook Pro (2013)Firefox
64iPhone SE (2016)Safari
6.3Nexus 7 (2012)Chrome
53 |
54 |
55 | Machine Intelligence Laboratory, The University of Tokyo 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /docs_raw/jekyll/examples/mnist/mnist_demo.css: -------------------------------------------------------------------------------- 1 | div.demo-view { 2 | font-size: 200%; 3 | } 4 | 5 | #recognize-in { 6 | width: 56px; 7 | height: 56px; 8 | } -------------------------------------------------------------------------------- /docs_raw/jekyll/examples/mnist/network_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs_raw/jekyll/examples/mnist/network_shape.png -------------------------------------------------------------------------------- /docs_raw/jekyll/examples/mnist/network_shape_rot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs_raw/jekyll/examples/mnist/network_shape_rot.png -------------------------------------------------------------------------------- /docs_raw/jekyll/feed.xml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: null 3 | --- 4 | 5 | 6 | 7 | {{ site.title | xml_escape }} 8 | {{ site.description | xml_escape }} 9 | {{ site.url }}{{ site.baseurl }}/ 10 | 11 | {{ site.time | date_to_rfc822 }} 12 | {{ site.time | date_to_rfc822 }} 13 | Jekyll v{{ jekyll.version }} 14 | {% for post in site.posts limit:10 %} 15 | 16 | {{ post.title | xml_escape }} 17 | {{ post.content | xml_escape }} 18 | {{ post.date | date_to_rfc822 }} 19 | {{ post.url | prepend: site.baseurl | prepend: site.url }} 20 | {{ post.url | prepend: site.baseurl | prepend: site.url }} 21 | {% for tag in post.tags %} 22 | {{ tag | xml_escape }} 23 | {% endfor %} 24 | {% for cat in post.categories %} 25 | {{ cat | xml_escape }} 26 | {% endfor %} 27 | 28 | {% endfor %} 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs_raw/jekyll/images/ss_camerademo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/docs_raw/jekyll/images/ss_camerademo.png -------------------------------------------------------------------------------- /docs_raw/jekyll/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |

Sukiyaki2

7 | 8 |

This is the document page for Sukiyaki2, a deep learning library for JavaScript.

9 | 10 |

API Reference

11 | 12 |
13 | Demos:
14 | Training of digit recognition
15 | Digit recognition from camera 16 | 17 |
18 | 19 |

Posts

20 | 21 | 32 | 33 |

subscribe via RSS

34 | 35 |
36 | -------------------------------------------------------------------------------- /docs_raw/jekyll/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | # Setup of Sukiyaki2 and introduction of basic usage 6 | 7 | Sukiyaki2 is a deep learning library for JavaScript. 8 | Sukiyaki2 is designed to achive distributed training of Deep Neural Networks using ordinary personal 9 | computers by implementing system in JavaScript, which can run on web browsers. 10 | For training in single computer, it is recommeneded to use node.js environment 11 | because it is faster and can access filesystem directly 12 | (even in web browser, setting up a server to supply dataset is needed). 13 | 14 | In this page, the way of setting up Sukiyaki2 on node.js environment and running basic example is described. 15 | 16 | ## Setup for node.js 17 | Since this project is written in TypeScript, transpiling to JavaScript is necessary. 18 | 19 | ```bash 20 | git clone https://github.com/mil-tokyo/sukiyaki2 21 | cd sukiyaki2 22 | npm install 23 | npm run build 24 | ``` 25 | 26 | On `npm install`, it installs [node-opencl](https://github.com/mikeseven/node-opencl) package for GPU computing which allows dramatically faster computation. 27 | In my environment (Ubuntu 14.04 + NVIDIA CUDA 7.5), installation with node-opencl requires additional environment variables. 28 | 29 | ```bash 30 | CPLUS_INCLUDE_PATH=/usr/local/cuda/include LIBRARY_PATH=/usr/local/cuda/lib64 npm install 31 | ``` 32 | 33 | ## Running MNIST digit recognition training 34 | This example trains Deep Convolutional Neural Networks (DCNNs) using ["MNIST handwritten digit database"](http://yann.lecun.com/exdb/mnist/). 35 | 36 | -------------------------------------------------------------------------------- /example/mnist/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/example/mnist/data/.gitkeep -------------------------------------------------------------------------------- /example/mnist/lenet.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "d_train", 4 | "type": "blob_data", 5 | "params": { 6 | "file_prefix": "example/mnist/data/mnist_train", 7 | "data_shape": [ 8 | 28, 9 | 28, 10 | 1 11 | ], 12 | "data_klass": "uint8" 13 | }, 14 | "inputs": [ 15 | "batch" 16 | ], 17 | "outputs": [ 18 | "rawdata", 19 | "label" 20 | ], 21 | "phase": [ 22 | "train" 23 | ] 24 | }, 25 | { 26 | "name": "d_test", 27 | "type": "blob_data", 28 | "params": { 29 | "file_prefix": "example/mnist/data/mnist_test", 30 | "data_shape": [ 31 | 28, 32 | 28, 33 | 1 34 | ], 35 | "data_klass": "uint8" 36 | }, 37 | "inputs": [ 38 | "batch" 39 | ], 40 | "outputs": [ 41 | "rawdata", 42 | "label" 43 | ], 44 | "phase": [ 45 | "test" 46 | ] 47 | }, 48 | { 49 | "name": "aug_train", 50 | "type": "data_augmentation", 51 | "params": { 52 | "out_shape": [28, 28], 53 | "scale": 0.00390625, 54 | "random_crop": false, 55 | "random_flip": false, 56 | "input_klass": "uint8" 57 | }, 58 | "inputs": ["rawdata"], 59 | "outputs": ["data"], 60 | "phase": ["train"] 61 | }, 62 | { 63 | "name": "aug_test", 64 | "type": "data_augmentation", 65 | "params": { 66 | "out_shape": [28, 28], 67 | "scale": 0.00390625, 68 | "random_crop": false, 69 | "random_flip": false, 70 | "input_klass": "uint8" 71 | }, 72 | "inputs": ["rawdata"], 73 | "outputs": ["data"], 74 | "phase": ["test"] 75 | }, 76 | { 77 | "name": "conv1", 78 | "type": "convolution_2d", 79 | "params": { 80 | "in_size": 1, 81 | "out_size": 20, 82 | "ksize": 5, 83 | "stride": 1, 84 | "pad": 0 85 | }, 86 | "inputs": [ 87 | "data" 88 | ], 89 | "outputs": [ 90 | "conv1" 91 | ] 92 | }, 93 | { 94 | "name": "pool1", 95 | "type": "pooling_2d", 96 | "params": { 97 | "type": "max", 98 | "ksize": 2, 99 | "stride": 2, 100 | "pad": 0 101 | }, 102 | "inputs": [ 103 | "conv1" 104 | ], 105 | "outputs": [ 106 | "pool1" 107 | ] 108 | }, 109 | { 110 | "name": "conv2", 111 | "type": "convolution_2d", 112 | "params": { 113 | "in_size": 20, 114 | "out_size": 50, 115 | "ksize": 5, 116 | "stride": 1, 117 | "pad": 0 118 | }, 119 | "inputs": [ 120 | "pool1" 121 | ], 122 | "outputs": [ 123 | "conv2" 124 | ] 125 | }, 126 | { 127 | "name": "pool2", 128 | "type": "pooling_2d", 129 | "params": { 130 | "type": "max", 131 | "ksize": 2, 132 | "stride": 2, 133 | "pad": 0 134 | }, 135 | "inputs": [ 136 | "conv2" 137 | ], 138 | "outputs": [ 139 | "pool2" 140 | ] 141 | }, 142 | { 143 | "name": "fc3", 144 | "type": "linear", 145 | "params": { 146 | "in_shape": [ 147 | 4, 148 | 4, 149 | 50 150 | ], 151 | "out_size": 500 152 | }, 153 | "inputs": [ 154 | "pool2" 155 | ], 156 | "outputs": [ 157 | "fc3" 158 | ] 159 | }, 160 | { 161 | "name": "relu3", 162 | "type": "relu", 163 | "params": {}, 164 | "inputs": [ 165 | "fc3" 166 | ], 167 | "outputs": [ 168 | "relu3" 169 | ] 170 | }, 171 | { 172 | "name": "fc4", 173 | "type": "linear", 174 | "params": { 175 | "in_shape": [ 176 | 500 177 | ], 178 | "out_size": 10 179 | }, 180 | "inputs": [ 181 | "relu3" 182 | ], 183 | "outputs": [ 184 | "pred" 185 | ] 186 | }, 187 | { 188 | "name": "l", 189 | "type": "softmax_cross_entropy", 190 | "params": {}, 191 | "inputs": [ 192 | "pred", 193 | "label" 194 | ], 195 | "outputs": [ 196 | "loss" 197 | ] 198 | }, 199 | { 200 | "name": "a", 201 | "type": "accuracy", 202 | "params": {}, 203 | "inputs": [ 204 | "pred", 205 | "label" 206 | ], 207 | "outputs": [ 208 | "accuracy" 209 | ], 210 | "phase": [ 211 | "test" 212 | ] 213 | } 214 | ] -------------------------------------------------------------------------------- /example/mnist/model/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/example/mnist/model/.gitkeep -------------------------------------------------------------------------------- /example/mnist/prepare.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | """ 5 | Downloads MNIST dataset and convert it to training dataset 6 | """ 7 | 8 | import os 9 | import sys 10 | from six.moves import urllib 11 | import gzip 12 | import json 13 | 14 | import numpy as np 15 | 16 | def download_mnist(): 17 | sys.stderr.write("Downloading MNIST dataset (12MB)... ") 18 | urls = [("http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz", "train-images-idx3-ubyte.gz"), 19 | ("http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz", "train-labels-idx1-ubyte.gz"), 20 | ("http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz", "t10k-images-idx3-ubyte.gz"), 21 | ("http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz", "t10k-labels-idx1-ubyte.gz")] 22 | for url, filename in urls: 23 | if not os.path.exists(filename): 24 | urllib.request.urlretrieve(url, filename) 25 | sys.stderr.write("done.\n") 26 | 27 | def convert_images(src_path_gz, dst_path): 28 | with gzip.open(src_path_gz, "rb") as f: 29 | d = f.read() 30 | images = np.fromstring(d[16:], dtype=np.uint8) 31 | images = images.reshape(-1, 28, 28)#sample, h, w 32 | 33 | # convert to (h, w, sample) in fortran-order = (sample, w, h) in c-order 34 | trans_images = np.transpose(images, (0, 2, 1)) 35 | trans_images.tofile(dst_path) 36 | 37 | def convert_labels(src_path_gz, dst_path): 38 | with gzip.open(src_path_gz, "rb") as f: 39 | d = f.read() 40 | labels = np.fromstring(d[8:], dtype=np.uint8) 41 | labels_list = labels.tolist() 42 | with open(dst_path, "wb") as f: 43 | json.dump(labels_list, f) 44 | 45 | def main(): 46 | data_dir = os.path.dirname(__file__) + "/data" 47 | if not os.path.exists(data_dir): 48 | os.mkdir(data_dir) 49 | os.chdir(data_dir)#current directory to data directory for simplify file path 50 | download_mnist() 51 | sys.stderr.write("Converting images and labels... ") 52 | for src_path_gz, dst_path in [("train-images-idx3-ubyte.gz", "mnist_train.bin"), 53 | ("t10k-images-idx3-ubyte.gz", "mnist_test.bin")]: 54 | convert_images(src_path_gz, dst_path) 55 | for src_path_gz, dst_path in [("train-labels-idx1-ubyte.gz", "mnist_train.json"), 56 | ("t10k-labels-idx1-ubyte.gz", "mnist_test.json")]: 57 | convert_labels(src_path_gz, dst_path) 58 | sys.stderr.write("done.\n") 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /example/mnist/train.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -e "run/train_node.js" ] 4 | then 5 | echo "run/train_node.js not found. Build the project and run this script at project root directory." 6 | exit 1 7 | fi 8 | 9 | echo "Models and log will be saved on example/mnist/model" 10 | 11 | CL_OPTION="" 12 | VAL_ITER_LIMIT="10" 13 | VAL_CYCLE="50" 14 | 15 | if [ "$1" == "cl" ] 16 | then 17 | echo "OpenCL mode" 18 | CL_OPTION="--cl" 19 | VAL_ITER_LIMIT="0" 20 | VAL_CYCLE="500" 21 | else 22 | echo "No OpenCL mode; training will slow. 23 | $ train.sh cl 24 | for enable OpenCL." 25 | fi 26 | 27 | node run/train_node --net example/mnist/lenet.json --save_tmpl example/mnist/model/lenet_iter_%d.model $CL_OPTION --iter 2000 --batch_size 32 --val_cycle $VAL_CYCLE --val_iter_limit $VAL_ITER_LIMIT | tee example/mnist/model/train.log 28 | -------------------------------------------------------------------------------- /imagenet_mean.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/imagenet_mean.npy -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import Sukiyaki = require('./src/sukiyaki'); 2 | export = Sukiyaki; 3 | -------------------------------------------------------------------------------- /netdef/lenet.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "d_train", 4 | "type": "blob_data", 5 | "params": { 6 | "file_prefix": "mnist/mnist_train_8bit", 7 | "data_shape": [ 8 | 28, 9 | 28, 10 | 1 11 | ], 12 | "data_klass": "uint8" 13 | }, 14 | "inputs": [ 15 | "batch" 16 | ], 17 | "outputs": [ 18 | "rawdata", 19 | "label" 20 | ], 21 | "phase": [ 22 | "train" 23 | ] 24 | }, 25 | { 26 | "name": "d_test", 27 | "type": "blob_data", 28 | "params": { 29 | "file_prefix": "mnist/mnist_test_8bit", 30 | "data_shape": [ 31 | 28, 32 | 28, 33 | 1 34 | ], 35 | "data_klass": "uint8" 36 | }, 37 | "inputs": [ 38 | "batch" 39 | ], 40 | "outputs": [ 41 | "rawdata", 42 | "label" 43 | ], 44 | "phase": [ 45 | "test" 46 | ] 47 | }, 48 | { 49 | "name": "aug_train", 50 | "type": "data_augmentation", 51 | "params": { 52 | "out_shape": [28, 28], 53 | "scale": 0.00390625, 54 | "random_crop": false, 55 | "random_flip": false, 56 | "input_klass": "uint8" 57 | }, 58 | "inputs": ["rawdata"], 59 | "outputs": ["data"], 60 | "phase": ["train"] 61 | }, 62 | { 63 | "name": "aug_test", 64 | "type": "data_augmentation", 65 | "params": { 66 | "out_shape": [28, 28], 67 | "scale": 0.00390625, 68 | "random_crop": false, 69 | "random_flip": false, 70 | "input_klass": "uint8" 71 | }, 72 | "inputs": ["rawdata"], 73 | "outputs": ["data"], 74 | "phase": ["test"] 75 | }, 76 | { 77 | "name": "conv1", 78 | "type": "convolution_2d", 79 | "params": { 80 | "in_size": 1, 81 | "out_size": 20, 82 | "ksize": 5, 83 | "stride": 1, 84 | "pad": 0 85 | }, 86 | "inputs": [ 87 | "data" 88 | ], 89 | "outputs": [ 90 | "conv1" 91 | ] 92 | }, 93 | { 94 | "name": "pool1", 95 | "type": "pooling_2d", 96 | "params": { 97 | "type": "max", 98 | "ksize": 2, 99 | "stride": 2, 100 | "pad": 0 101 | }, 102 | "inputs": [ 103 | "conv1" 104 | ], 105 | "outputs": [ 106 | "pool1" 107 | ] 108 | }, 109 | { 110 | "name": "conv2", 111 | "type": "convolution_2d", 112 | "params": { 113 | "in_size": 20, 114 | "out_size": 50, 115 | "ksize": 5, 116 | "stride": 1, 117 | "pad": 0 118 | }, 119 | "inputs": [ 120 | "pool1" 121 | ], 122 | "outputs": [ 123 | "conv2" 124 | ] 125 | }, 126 | { 127 | "name": "pool2", 128 | "type": "pooling_2d", 129 | "params": { 130 | "type": "max", 131 | "ksize": 2, 132 | "stride": 2, 133 | "pad": 0 134 | }, 135 | "inputs": [ 136 | "conv2" 137 | ], 138 | "outputs": [ 139 | "pool2" 140 | ] 141 | }, 142 | { 143 | "name": "fc3", 144 | "type": "linear", 145 | "params": { 146 | "in_shape": [ 147 | 4, 148 | 4, 149 | 50 150 | ], 151 | "out_size": 500 152 | }, 153 | "inputs": [ 154 | "pool2" 155 | ], 156 | "outputs": [ 157 | "fc3" 158 | ] 159 | }, 160 | { 161 | "name": "relu3", 162 | "type": "relu", 163 | "params": {}, 164 | "inputs": [ 165 | "fc3" 166 | ], 167 | "outputs": [ 168 | "relu3" 169 | ] 170 | }, 171 | { 172 | "name": "fc4", 173 | "type": "linear", 174 | "params": { 175 | "in_shape": [ 176 | 500 177 | ], 178 | "out_size": 10 179 | }, 180 | "inputs": [ 181 | "relu3" 182 | ], 183 | "outputs": [ 184 | "pred" 185 | ] 186 | }, 187 | { 188 | "name": "l", 189 | "type": "softmax_cross_entropy", 190 | "params": {}, 191 | "inputs": [ 192 | "pred", 193 | "label" 194 | ], 195 | "outputs": [ 196 | "loss" 197 | ] 198 | }, 199 | { 200 | "name": "a", 201 | "type": "accuracy", 202 | "params": {}, 203 | "inputs": [ 204 | "pred", 205 | "label" 206 | ], 207 | "outputs": [ 208 | "accuracy" 209 | ], 210 | "phase": [ 211 | "test" 212 | ] 213 | } 214 | ] -------------------------------------------------------------------------------- /netdef/lenet_invert.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "d_train", 4 | "type": "blob_data", 5 | "params": { 6 | "file_prefix": "mnist_invert/mnist_train_8bit", 7 | "data_shape": [ 8 | 28, 9 | 28, 10 | 1 11 | ], 12 | "data_klass": "uint8" 13 | }, 14 | "inputs": [ 15 | "batch" 16 | ], 17 | "outputs": [ 18 | "rawdata", 19 | "label" 20 | ], 21 | "phase": [ 22 | "train" 23 | ] 24 | }, 25 | { 26 | "name": "d_test", 27 | "type": "blob_data", 28 | "params": { 29 | "file_prefix": "mnist_invert/mnist_test_8bit", 30 | "data_shape": [ 31 | 28, 32 | 28, 33 | 1 34 | ], 35 | "data_klass": "uint8" 36 | }, 37 | "inputs": [ 38 | "batch" 39 | ], 40 | "outputs": [ 41 | "rawdata", 42 | "label" 43 | ], 44 | "phase": [ 45 | "test" 46 | ] 47 | }, 48 | { 49 | "name": "aug_train", 50 | "type": "data_augmentation", 51 | "params": { 52 | "out_shape": [28, 28], 53 | "scale": 0.00390625, 54 | "random_crop": false, 55 | "random_flip": false, 56 | "input_klass": "uint8" 57 | }, 58 | "inputs": ["rawdata"], 59 | "outputs": ["data"], 60 | "phase": ["train"] 61 | }, 62 | { 63 | "name": "aug_test", 64 | "type": "data_augmentation", 65 | "params": { 66 | "out_shape": [28, 28], 67 | "scale": 0.00390625, 68 | "random_crop": false, 69 | "random_flip": false, 70 | "input_klass": "uint8" 71 | }, 72 | "inputs": ["rawdata"], 73 | "outputs": ["data"], 74 | "phase": ["test"] 75 | }, 76 | { 77 | "name": "conv1", 78 | "type": "convolution_2d", 79 | "params": { 80 | "in_size": 1, 81 | "out_size": 20, 82 | "ksize": 5, 83 | "stride": 1, 84 | "pad": 0 85 | }, 86 | "inputs": [ 87 | "data" 88 | ], 89 | "outputs": [ 90 | "conv1" 91 | ] 92 | }, 93 | { 94 | "name": "pool1", 95 | "type": "pooling_2d", 96 | "params": { 97 | "type": "max", 98 | "ksize": 2, 99 | "stride": 2, 100 | "pad": 0 101 | }, 102 | "inputs": [ 103 | "conv1" 104 | ], 105 | "outputs": [ 106 | "pool1" 107 | ] 108 | }, 109 | { 110 | "name": "conv2", 111 | "type": "convolution_2d", 112 | "params": { 113 | "in_size": 20, 114 | "out_size": 50, 115 | "ksize": 5, 116 | "stride": 1, 117 | "pad": 0 118 | }, 119 | "inputs": [ 120 | "pool1" 121 | ], 122 | "outputs": [ 123 | "conv2" 124 | ] 125 | }, 126 | { 127 | "name": "pool2", 128 | "type": "pooling_2d", 129 | "params": { 130 | "type": "max", 131 | "ksize": 2, 132 | "stride": 2, 133 | "pad": 0 134 | }, 135 | "inputs": [ 136 | "conv2" 137 | ], 138 | "outputs": [ 139 | "pool2" 140 | ] 141 | }, 142 | { 143 | "name": "fc3", 144 | "type": "linear", 145 | "params": { 146 | "in_shape": [ 147 | 4, 148 | 4, 149 | 50 150 | ], 151 | "out_size": 500 152 | }, 153 | "inputs": [ 154 | "pool2" 155 | ], 156 | "outputs": [ 157 | "fc3" 158 | ] 159 | }, 160 | { 161 | "name": "relu3", 162 | "type": "relu", 163 | "params": {}, 164 | "inputs": [ 165 | "fc3" 166 | ], 167 | "outputs": [ 168 | "relu3" 169 | ] 170 | }, 171 | { 172 | "name": "fc4", 173 | "type": "linear", 174 | "params": { 175 | "in_shape": [ 176 | 500 177 | ], 178 | "out_size": 10 179 | }, 180 | "inputs": [ 181 | "relu3" 182 | ], 183 | "outputs": [ 184 | "pred" 185 | ] 186 | }, 187 | { 188 | "name": "l", 189 | "type": "softmax_cross_entropy", 190 | "params": {}, 191 | "inputs": [ 192 | "pred", 193 | "label" 194 | ], 195 | "outputs": [ 196 | "loss" 197 | ] 198 | }, 199 | { 200 | "name": "a", 201 | "type": "accuracy", 202 | "params": {}, 203 | "inputs": [ 204 | "pred", 205 | "label" 206 | ], 207 | "outputs": [ 208 | "accuracy" 209 | ], 210 | "phase": [ 211 | "test" 212 | ] 213 | } 214 | ] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "milsukiyaki2", 3 | "version": "0.0.0", 4 | "description": "Deep Learning Library for JavaScript", 5 | "main": "index.js", 6 | "dependencies": { 7 | "@types/argparse": "^1.0.30", 8 | "@types/node": "0.0.2", 9 | "argparse": "^1.0.9", 10 | "jpeg-turbo": "^0.4.0", 11 | "milsushi2": "^0.0.1" 12 | }, 13 | "devDependencies": { 14 | "typedoc": "^0.5.1", 15 | "typescript": ">=2.0.0", 16 | "browserify": "^13.0.1", 17 | "browserify-shim": "^3.8.12", 18 | "browserify-header": "^0.9.2", 19 | "@types/jasmine": "^2.5.38" 20 | }, 21 | "scripts": { 22 | "build": "tsc", 23 | "test": "jasmine-node spec", 24 | "browserify": "./do_browserify.sh", 25 | "typedoc": "typedoc . --out ./docs/api/ --target ES5 --module commonjs --mode file --name Sukiyaki2 --includes apidoc --readme apidoc/index.md", 26 | "jekyll": "cd docs_raw/jekyll; bundle exec jekyll build --source . --destination ../../docs", 27 | "jekyll-setup": "cd docs_raw/jekyll; bundle install" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/mil-tokyo/sukiyaki2.git" 32 | }, 33 | "keywords": [ 34 | "DeepLearning" 35 | ], 36 | "author": "Masatoshi Hidaka, Ken Miura, Tatsuya Harada", 37 | "license": "MIT", 38 | "bugs": { 39 | "url": "https://github.com/mil-tokyo/sukiyaki2/issues" 40 | }, 41 | "homepage": "https://github.com/mil-tokyo/sukiyaki2", 42 | "browserify": { 43 | "transform": [ 44 | "browserify-shim" 45 | ] 46 | }, 47 | "browserify-shim": { 48 | "milsushi2": "global:milsushi2" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /run/classify_node.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Sukiyaki = require('../index'); 4 | import argparse = require('argparse'); 5 | var Network = Sukiyaki.Network; 6 | var OptimizerSGD = Sukiyaki.Optimizers.OptimizerSGD; 7 | var ArraySerializer = Sukiyaki.ArraySerializer; 8 | import fs = require('fs'); 9 | 10 | function classify_node(netdef: string, mean_file: string, weight: string, dst: string, cl: boolean = false) { 11 | if (cl) { 12 | $M.initcl(); 13 | } 14 | var layers = JSON.parse(fs.readFileSync(netdef, 'utf8')); 15 | var net = new Network(layers); 16 | net.init(() => { 17 | if (cl) { 18 | net.to_cl(); 19 | } 20 | net.layer_time = {}; 21 | if (mean_file) { 22 | var data_mean = $M.permute($M.npyread(fs.readFileSync(mean_file)), [2, 3, 1]);//to h, w, c 23 | (net.layer_instances["aug_test"]).set_data_mean(data_mean); 24 | } 25 | var batch_size = 8; 26 | 27 | console.log('loading net'); 28 | var buf = new Uint8Array(fs.readFileSync(weight).buffer); 29 | ArraySerializer.load(buf, net); 30 | 31 | var validation_iter = 0; 32 | var validation_length = (net.layer_instances["d_test"]).length; 33 | var validation_n_batch = Math.ceil(validation_length / batch_size); 34 | var validation_sum_accuracy = 0; 35 | var validation_sum_loss = 0; 36 | var final_fc_list = []; 37 | var validation = (start_val: boolean = false) => { 38 | if (start_val) { 39 | validation_iter = 0; 40 | validation_sum_accuracy = 0; 41 | validation_sum_loss = 0; 42 | net.phase = "test"; 43 | } 44 | console.log(validation_iter); 45 | var range_bottom = validation_iter * batch_size + 1; 46 | var range_size = Math.min(batch_size, validation_length - range_bottom + 1); 47 | var input_vars: { [index: string]: $M.Matrix } = { 'batch': $M.jsa2mat([range_bottom, range_size]) }; 48 | net.forward(input_vars, () => { 49 | final_fc_list.push(net.blobs_forward['fc8'].copy());//[labels,range_size] 50 | var val_a = net.blobs_forward['accuracy'].get(); 51 | var val_l = net.blobs_forward['loss'].get(); 52 | validation_sum_accuracy += val_a * range_size; 53 | validation_sum_loss += val_l * range_size; 54 | net.release(); 55 | validation_iter++; 56 | if (validation_iter == validation_n_batch) { 57 | // end of validation 58 | var val_mean_accuracy = validation_sum_accuracy / validation_length; 59 | var val_mean_loss = validation_sum_loss / validation_length; 60 | console.log(JSON.stringify({'type': 'val', 'loss': val_mean_loss, 'accuracy': val_mean_accuracy})); 61 | var final_fc = $M.horzcat(...final_fc_list); 62 | fs.writeFileSync(dst, new Buffer($M.npysave(final_fc))); 63 | } else { 64 | //next iteration of validation 65 | validation(false); 66 | } 67 | }); 68 | }; 69 | 70 | validation(true); 71 | 72 | }); 73 | 74 | return net; 75 | } 76 | 77 | function main() { 78 | //classify_node(netdef: string, mean_file: string, weight: string, dst: string, cl: boolean = false) 79 | var parser = new argparse.ArgumentParser(); 80 | parser.addArgument(['--net'], {required:true}); 81 | parser.addArgument(['--mean'], {}); 82 | parser.addArgument(['--dst'],{required:true}); 83 | parser.addArgument(['--weight'],{required:true}); 84 | parser.addArgument(['--cl'],{ action: 'storeTrue', defaultValue: false }); 85 | var args = parser.parseArgs(); 86 | classify_node(args.net, args.mean, args.weight, args.dst, args.cl); 87 | } 88 | 89 | main(); 90 | -------------------------------------------------------------------------------- /spec/data_augmentation.spec.ts: -------------------------------------------------------------------------------- 1 | import $M = require('milsushi2'); 2 | import Sukiyaki = require('../index'); 3 | import fs = require('fs'); 4 | import load_layer_case = require('./layer_case_loader'); 5 | 6 | declare var process; 7 | var cl_enabled = Boolean(Number(process.env['TEST_CL'])); 8 | console.log('OpenCL ' + cl_enabled); 9 | var MatrixCL = null; 10 | if (cl_enabled) { 11 | $M.initcl(); 12 | } 13 | 14 | function load_npy(name: string): $M.Matrix { 15 | var path = 'spec/fixture/data_augmentation/' + name + '.npy'; 16 | var m = $M.npyread(fs.readFileSync(path)); 17 | if (cl_enabled) { 18 | m = $M.gpuArray(m); 19 | } 20 | return m; 21 | } 22 | 23 | var fixture_mean = load_npy('mean'); 24 | var fixture_bottom = load_npy('bottom'); 25 | var fixture_top = load_npy('top'); 26 | 27 | describe('Data augmentation layer', function () { 28 | it('give desired output without random', function (done) { 29 | var layer = new Sukiyaki.Layers.DataAugmentationLayer( 30 | { "out_shape": [6, 7], "scale": 0.5, "random_crop": false, "random_flip": false, "input_klass": "single" }); 31 | layer.init(() => { 32 | if (cl_enabled) { 33 | layer.to_cl(); 34 | } 35 | layer.set_data_mean(fixture_mean); 36 | 37 | var fwdconfig = new Sukiyaki.ForwardConfiguration(); 38 | fwdconfig.phase = 'train'; 39 | fwdconfig.devicetype = cl_enabled ? 'cl' : 'cpu'; 40 | layer.forward([fixture_bottom], fwdconfig, (tops) => { 41 | var top = tops[0]; 42 | expect($M.allclose(fixture_top, top)).toBeTruthy(); 43 | done(); 44 | }); 45 | }); 46 | }); 47 | 48 | it('give desired output in random pattern', function (done) { 49 | var layer = new Sukiyaki.Layers.DataAugmentationLayer( 50 | { "out_shape": [6, 7], "scale": 1.0, "random_crop": true, "random_flip": true, "input_klass": "single" }); 51 | layer.init(() => { 52 | if (cl_enabled) { 53 | layer.to_cl(); 54 | } 55 | layer.set_data_mean(fixture_mean); 56 | 57 | var fwdconfig = new Sukiyaki.ForwardConfiguration(); 58 | fwdconfig.phase = 'train'; 59 | fwdconfig.devicetype = cl_enabled ? 'cl' : 'cpu'; 60 | layer.forward([fixture_bottom], fwdconfig, (tops) => { 61 | var top = tops[0];//[out_h, out_w, c, n] 6, 7, 2, 3 62 | // ydiff=2, xdiff=1, cdiff=3 63 | expect(top.get(2, 1, 1, 1) - top.get(1, 1, 1, 1)).toBeCloseTo(2, 4); 64 | expect(Math.abs(top.get(3, 5, 1, 2) - top.get(3, 4, 1, 2))).toBeCloseTo(1, 4);//abs to support mirror 65 | expect(top.get(6, 7, 2, 3) - top.get(6, 7, 1, 3)).toBeCloseTo(3, 4); 66 | done(); 67 | }); 68 | }); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /spec/fixture/data_augmentation/bottom.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/data_augmentation/bottom.npy -------------------------------------------------------------------------------- /spec/fixture/data_augmentation/mean.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/data_augmentation/mean.npy -------------------------------------------------------------------------------- /spec/fixture/data_augmentation/top.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/data_augmentation/top.npy -------------------------------------------------------------------------------- /spec/fixture/fixture_helper.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import numpy as np 4 | 5 | # utilities 6 | def random_float32(shape): 7 | # chainer requires float32 array for parameters 8 | return np.random.standard_normal(shape).astype(np.float32) 9 | 10 | def reverse_order(*mats): 11 | # reverse order of axis (for supporting c-order and f-order change) 12 | rets = [] 13 | for x in mats: 14 | perm_from = list(range(x.ndim)) 15 | perm_to = list(range(x.ndim)) 16 | perm_to.reverse() 17 | rets.append(np.moveaxis(x, perm_from, perm_to)) 18 | return rets 19 | 20 | def reorder_nchw_hwcn(*mats): 21 | # order from (n, c, h, w) to (h, w, c, n) 22 | rets = [] 23 | nchw = (0, 1, 2, 3) 24 | hwcn = (3, 2, 0, 1) 25 | for x in mats: 26 | rets.append(np.moveaxis(x, nchw, hwcn)) 27 | return rets 28 | -------------------------------------------------------------------------------- /spec/fixture/layer/average_pooling_2d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/average_pooling_2d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/average_pooling_2d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/average_pooling_2d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/average_pooling_2d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/average_pooling_2d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/average_pooling_2d/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"stride": [2, 3], "pad": [1, 2], "ksize": [3, 5], "type": "average"}, "type": "pooling_2d"}, "blobs": {"delta_params": [], "forward": {"tops": 1, "bottoms": 1}, "backward": {"bottom_deltas": 1, "top_deltas": 1, "bottoms": 1}, "train_params": []}} -------------------------------------------------------------------------------- /spec/fixture/layer/average_pooling_2d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/average_pooling_2d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/average_pooling_2d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/average_pooling_2d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"in_size": 5, "eps": 1e-05, "target_dim": 1}, "type": "batch_normalization"}, "blobs": {"train_params": ["beta", "gamma"], "backward": {"bottoms": 1, "top_deltas": 1, "bottom_deltas": 1}, "delta_params": ["delta_beta", "delta_gamma"], "forward": {"tops": 1, "bottoms": 1}}} -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/delta_params.delta_beta.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/delta_params.delta_beta.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/delta_params.delta_gamma.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/delta_params.delta_gamma.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/train_params.beta.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/train_params.beta.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_2d/train_params.gamma.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_2d/train_params.gamma.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"in_size": 5, "eps": 0.001, "target_dim": 3}, "type": "batch_normalization"}, "blobs": {"train_params": ["beta", "gamma"], "backward": {"bottoms": 1, "top_deltas": 1, "bottom_deltas": 1}, "delta_params": ["delta_beta", "delta_gamma"], "forward": {"tops": 1, "bottoms": 1}}} -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/delta_params.delta_beta.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/delta_params.delta_beta.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/delta_params.delta_gamma.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/delta_params.delta_gamma.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/train_params.beta.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/train_params.beta.npy -------------------------------------------------------------------------------- /spec/fixture/layer/batch_normalization_4d/train_params.gamma.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/batch_normalization_4d/train_params.gamma.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"stride": [1, 1], "pad": [0, 0], "in_size": 3, "out_size": 4, "ksize": [3, 3]}, "type": "convolution_2d"}, "blobs": {"backward": {"top_deltas": 1, "bottoms": 1, "bottom_deltas": 1}, "delta_params": ["delta_bias", "delta_weight"], "forward": {"bottoms": 1, "tops": 1}, "train_params": ["weight", "bias"]}} -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/delta_params.delta_bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/delta_params.delta_bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/delta_params.delta_weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/delta_params.delta_weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/train_params.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/train_params.bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d/train_params.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d/train_params.weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"pad": [0, 0], "stride": [1, 1], "out_size": 3, "ksize": [1, 1], "in_size": 2}, "type": "convolution_2d"}, "blobs": {"backward": {"bottoms": 1, "top_deltas": 1, "bottom_deltas": 1}, "forward": {"bottoms": 1, "tops": 1}, "delta_params": ["delta_weight", "delta_bias"], "train_params": ["bias", "weight"]}} -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/delta_params.delta_bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/delta_params.delta_bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/delta_params.delta_weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/delta_params.delta_weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/train_params.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/train_params.bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_1x1/train_params.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_1x1/train_params.weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"group": 2, "stride": [2, 3], "pad": [1, 2], "ksize": [3, 5], "out_size": 8, "in_size": 6}, "type": "convolution_2d"}, "blobs": {"forward": {"tops": 1, "bottoms": 1}, "train_params": ["bias", "weight"], "backward": {"top_deltas": 1, "bottom_deltas": 1, "bottoms": 1}, "delta_params": ["delta_weight", "delta_bias"]}} -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/delta_params.delta_bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/delta_params.delta_bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/delta_params.delta_weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/delta_params.delta_weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/train_params.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/train_params.bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_group/train_params.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_group/train_params.weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/case.json: -------------------------------------------------------------------------------- 1 | {"blobs": {"delta_params": ["delta_bias", "delta_weight"], "backward": {"bottoms": 1, "top_deltas": 1, "bottom_deltas": 1}, "train_params": ["bias", "weight"], "forward": {"bottoms": 1, "tops": 1}}, "layer_params": {"type": "convolution_2d", "params": {"stride": [2, 3], "pad": [1, 2], "in_size": 3, "out_size": 4, "ksize": [3, 5]}}} -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/delta_params.delta_bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/delta_params.delta_bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/delta_params.delta_weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/delta_params.delta_weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/train_params.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/train_params.bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/convolution_2d_stride_pad/train_params.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/convolution_2d_stride_pad/train_params.weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/case.json: -------------------------------------------------------------------------------- 1 | {"blobs": {"backward": {"bottoms": 1, "top_deltas": 1, "bottom_deltas": 1}, "forward": {"tops": 1, "bottoms": 1}, "delta_params": ["delta_bias", "delta_weight"], "train_params": ["bias", "weight"]}, "layer_params": {"type": "linear", "params": {"out_size": 3, "in_shape": [4]}}} -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/delta_params.delta_bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/delta_params.delta_bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/delta_params.delta_weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/delta_params.delta_weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/train_params.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/train_params.bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_1d/train_params.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_1d/train_params.weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/case.json: -------------------------------------------------------------------------------- 1 | {"blobs": {"backward": {"bottoms": 1, "top_deltas": 1, "bottom_deltas": 1}, "forward": {"tops": 1, "bottoms": 1}, "delta_params": ["delta_bias", "delta_weight"], "train_params": ["bias", "weight"]}, "layer_params": {"type": "linear", "params": {"out_size": 3, "in_shape": [2, 2, 4]}}} -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/delta_params.delta_bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/delta_params.delta_bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/delta_params.delta_weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/delta_params.delta_weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/train_params.bias.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/train_params.bias.npy -------------------------------------------------------------------------------- /spec/fixture/layer/linear_3d/train_params.weight.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/linear_3d/train_params.weight.npy -------------------------------------------------------------------------------- /spec/fixture/layer/max_pooling_2d/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/max_pooling_2d/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/max_pooling_2d/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/max_pooling_2d/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/max_pooling_2d/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/max_pooling_2d/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/max_pooling_2d/case.json: -------------------------------------------------------------------------------- 1 | {"layer_params": {"params": {"stride": [2, 3], "pad": [1, 2], "ksize": [3, 5], "type": "max"}, "type": "pooling_2d"}, "blobs": {"delta_params": [], "forward": {"tops": 1, "bottoms": 1}, "backward": {"bottom_deltas": 1, "top_deltas": 1, "bottoms": 1}, "train_params": []}} -------------------------------------------------------------------------------- /spec/fixture/layer/max_pooling_2d/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/max_pooling_2d/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/max_pooling_2d/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/max_pooling_2d/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/relu/backward.bottom_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/relu/backward.bottom_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/relu/backward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/relu/backward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/relu/backward.top_deltas.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/relu/backward.top_deltas.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/relu/case.json: -------------------------------------------------------------------------------- 1 | {"blobs": {"delta_params": [], "backward": {"bottoms": 1, "bottom_deltas": 1, "top_deltas": 1}, "forward": {"bottoms": 1, "tops": 1}, "train_params": []}, "layer_params": {"params": {}, "type": "relu"}} -------------------------------------------------------------------------------- /spec/fixture/layer/relu/forward.bottoms.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/relu/forward.bottoms.0.npy -------------------------------------------------------------------------------- /spec/fixture/layer/relu/forward.tops.0.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mil-tokyo/sukiyaki2/9b7ba01fed74f0672b83ee3498a458e5284e2fc8/spec/fixture/layer/relu/forward.tops.0.npy -------------------------------------------------------------------------------- /spec/fixture/make_data_augmentation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | import sys 5 | import os 6 | import json 7 | from collections import defaultdict 8 | import itertools 9 | import numpy as np 10 | from fixture_helper import random_float32, reverse_order, reorder_nchw_hwcn 11 | 12 | DST_DIR = os.path.abspath(os.path.dirname(__file__)) + '/data_augmentation/' 13 | 14 | def make_data(n, c, in_h, in_w, out_h, out_w, scale): 15 | mean = random_float32((1, c, in_h, in_w)) 16 | bottom = np.zeros((n, c, in_h, in_w), dtype = np.float32) 17 | for in_n, in_c, y, x in itertools.product(range(n), range(c), range(in_h), range(in_w)): 18 | bottom[in_n, in_c, y, x] = in_n * 10 + in_c * 3 + y * 2 + x * 1 19 | bottom += mean 20 | crop_y = (in_h - out_h) // 2 21 | crop_x = (in_w - out_w) // 2 22 | top = ((bottom - mean)[:, :, crop_y:crop_y+out_h, crop_x:crop_x+out_w]) * scale 23 | mean, bottom, top = reorder_nchw_hwcn(mean, bottom, top) 24 | return mean, bottom, top 25 | 26 | if __name__ == '__main__': 27 | mean, bottom, top = make_data(3, 2, 10, 9, 6, 7, 0.5) 28 | np.save(DST_DIR + 'mean', mean) 29 | np.save(DST_DIR + 'bottom', bottom) 30 | np.save(DST_DIR + 'top', top) 31 | -------------------------------------------------------------------------------- /spec/layer_case_loader.ts: -------------------------------------------------------------------------------- 1 | // loads test case of a layer 2 | 3 | import fs = require('fs'); 4 | import $M = require('milsushi2'); 5 | 6 | function load_npy(basedir: string, keys: any[], cl: boolean) { 7 | // load_npy('foo', ['bar', 1]) => foo/bar.1.npy 8 | var path = basedir + '/'; 9 | keys.forEach((key) => { path += key + '.'; }); 10 | path += 'npy'; 11 | var m = $M.npyread(fs.readFileSync(path)); 12 | if (cl) { 13 | m = $M.gpuArray(m); 14 | } 15 | return m; 16 | } 17 | 18 | function load_layer_case(case_name: string, cl: boolean): any { 19 | var case_dir = 'spec/fixture/layer/' + case_name; 20 | var case_metadata = JSON.parse(fs.readFileSync(case_dir + '/case.json', 'utf8')); 21 | var layer_params = case_metadata.layer_params;//for layer_factory 22 | var blobs = {}; 23 | ["train_params", "delta_params"].forEach((param_type) => { 24 | blobs[param_type] = {}; 25 | if (case_metadata.blobs[param_type]) { 26 | case_metadata.blobs[param_type].forEach((param_name) => { 27 | blobs[param_type][param_name] = load_npy(case_dir, [param_type, param_name], cl); 28 | }); 29 | } 30 | }); 31 | 32 | ["forward", "backward"].forEach((param_type) => { 33 | blobs[param_type] = {}; 34 | var type_vars = case_metadata.blobs[param_type]; 35 | //type_vars == {"bottoms": 1, "tops": 1} 36 | for (var param_name in type_vars) { 37 | if (type_vars.hasOwnProperty(param_name)) { 38 | var param_count: number = type_vars[param_name]; 39 | var npy_list = []; 40 | for (var j = 0; j < param_count; j++) { 41 | npy_list.push(load_npy(case_dir, [param_type, param_name, j], cl)); 42 | } 43 | blobs[param_type][param_name] = npy_list; 44 | } 45 | } 46 | }); 47 | 48 | return { layer_params: layer_params, blobs: blobs }; 49 | } 50 | 51 | export = load_layer_case; 52 | -------------------------------------------------------------------------------- /spec/sukiyaki.spec.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | // reference only needed for typedoc 4 | import $M = require('milsushi2'); 5 | import Sukiyaki = require('../index'); 6 | import fs = require('fs'); 7 | import load_layer_case = require('./layer_case_loader'); 8 | 9 | declare var process; 10 | var cl_enabled = Boolean(Number(process.env['TEST_CL'])); 11 | console.log('OpenCL ' + cl_enabled); 12 | var MatrixCL = null; 13 | if (cl_enabled) { 14 | $M.initcl(); 15 | } 16 | 17 | var layer_test_cases = fs.readdirSync('spec/fixture/layer'); 18 | layer_test_cases.sort(); 19 | 20 | function test_layer_case(case_name: string, done: any, cl: boolean) { 21 | var case_data = load_layer_case(case_name, cl); 22 | console.log(case_name); 23 | var layer = Sukiyaki.LayerFactory.create(case_data.layer_params.type, case_data.layer_params.params); 24 | var forward_config = new Sukiyaki.ForwardConfiguration(); 25 | forward_config.phase = 'train'; 26 | if (cl) { 27 | layer.to_cl(); 28 | forward_config.devicetype = 'cl'; 29 | } else { 30 | forward_config.devicetype = 'cpu'; 31 | } 32 | 33 | //fill parameters to train (weight, bias) 34 | for (var param_name in case_data.blobs.train_params) { 35 | if (case_data.blobs.train_params.hasOwnProperty(param_name)) { 36 | var mat = case_data.blobs.train_params[param_name]; 37 | layer[param_name] = mat; 38 | } 39 | } 40 | //zero clear gradient parameters (delta_weight, delta_bias) 41 | if (layer.train_params) { 42 | for (var index = 0; index < layer.train_params.length; index++) { 43 | var train_param_name = layer.train_params[index]; 44 | var delta_param_name = layer.delta_params[index]; 45 | if (cl) { 46 | layer[delta_param_name] = $M.zeros($M.size(layer[train_param_name]), 'gpuArray'); 47 | } else { 48 | layer[delta_param_name] = $M.zeros($M.size(layer[train_param_name])); 49 | } 50 | } 51 | } 52 | 53 | layer.forward(case_data.blobs.forward.bottoms, forward_config, (actual_tops) => { 54 | // test forward result 55 | for (var forward_top_i = 0; forward_top_i < case_data.blobs.forward.tops.length; forward_top_i++) { 56 | var expected_top = case_data.blobs.forward.tops[forward_top_i]; 57 | try { 58 | expect($M.allclose(actual_tops[forward_top_i], expected_top, 1e-2, 1e-2)).toBeTruthy(); 59 | } catch (error) { 60 | console.error('Exception on forward test: ' + error); 61 | } 62 | } 63 | 64 | if (case_data.blobs.backward.bottom_deltas.length == 0) { 65 | //no backward test 66 | done(); 67 | } else { 68 | // update test 69 | layer.calculateUpdateParams(case_data.blobs.backward.bottoms, 70 | case_data.blobs.backward.top_deltas, forward_config, () => { 71 | // test update result 72 | for (var param_name in case_data.blobs.delta_params) { 73 | if (case_data.blobs.delta_params.hasOwnProperty(param_name)) { 74 | var expected_delta = case_data.blobs.delta_params[param_name]; 75 | // console.log('diff ' + param_name + ' ' + $M.min($M.reshape($M.minus(layer[param_name], expected_delta), -1, 1)).get()); 76 | try { 77 | expect($M.allclose(layer[param_name], expected_delta, 1e-2, 1e-2)).toBeTruthy(); 78 | } catch (error) { 79 | console.error('Exception on calculateUpdateParams test: ' + error); 80 | } 81 | } 82 | } 83 | 84 | // backward test 85 | layer.backward(case_data.blobs.backward.bottoms, 86 | case_data.blobs.backward.top_deltas, forward_config, (actual_bottom_deltas) => { 87 | // test backward result 88 | for (var backward_bottom_i = 0; backward_bottom_i < case_data.blobs.backward.bottom_deltas.length; backward_bottom_i++) { 89 | var expected_bottom_delta = case_data.blobs.backward.bottom_deltas[backward_bottom_i]; 90 | try { 91 | expect($M.allclose(actual_bottom_deltas[backward_bottom_i], expected_bottom_delta, 1e-2, 1e-2)).toBeTruthy(); 92 | } catch (error) { 93 | console.error('Exception on backward test: ' + error); 94 | } 95 | } 96 | 97 | done(); 98 | }); 99 | }); 100 | } 101 | }); 102 | } 103 | 104 | describe('Sukiyaki module', function () { 105 | it('has network class', function () { 106 | expect(Sukiyaki.Network).toBeDefined(); 107 | }) 108 | }); 109 | 110 | describe('layer test', function () { 111 | layer_test_cases.forEach((case_name) => { 112 | it('layer case cpu ' + case_name, function (done) { 113 | test_layer_case(case_name, done, false); 114 | }); 115 | }); 116 | 117 | if (cl_enabled) { 118 | layer_test_cases.forEach((case_name) => { 119 | it('layer case cl ' + case_name, function (done) { 120 | test_layer_case(case_name, done, true); 121 | }); 122 | }); 123 | } 124 | }); 125 | -------------------------------------------------------------------------------- /src/array_serializer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Layer = require('./layers/layer'); 4 | import Network = require('./network'); 5 | 6 | class ArraySerializer { 7 | static dump(net: Network, gradient: boolean = false): Uint8Array { 8 | // temporary format 9 | // header: json indicating offset and size of each variable 10 | // assuming all weights are Float32Array 11 | var header_obj; 12 | var max_header_size = 1024; 13 | var offset; 14 | var header_str; 15 | while (true) { 16 | header_obj = {}; 17 | offset = max_header_size; 18 | // get size 19 | for (var layer_name in net.layer_instances) { 20 | if (net.layer_instances.hasOwnProperty(layer_name)) { 21 | var layer_inst = net.layer_instances[layer_name]; 22 | if (!layer_inst.train_params) { 23 | continue; 24 | } 25 | var params_names = gradient ? layer_inst.delta_params : layer_inst.train_params; 26 | for (var i = 0; i < params_names.length; i++) { 27 | var train_param_name = params_names[i]; 28 | var weight: $M.Matrix = layer_inst[train_param_name]; 29 | if ($M.klass(weight) != 'single') { 30 | throw new Error('Only matrix of klass single is supported'); 31 | } 32 | var weight_size = $M.numel(weight) * 4; 33 | header_obj[layer_name + '/' + train_param_name] = { offset: offset, size: weight_size }; 34 | offset += weight_size; 35 | } 36 | } 37 | } 38 | header_str = JSON.stringify(header_obj); 39 | if (header_str.length < max_header_size) { 40 | //ok 41 | break; 42 | } 43 | max_header_size = Math.ceil(header_str.length / 1024) * 1024 + 1024;//increase header size and retry 44 | } 45 | 46 | var buf = new Uint8Array(offset); 47 | //write header as binary 48 | for (var i = 0; i < header_str.length; i++) { 49 | buf[i] = header_str.charCodeAt(i); 50 | } 51 | 52 | //console.log(header_str); 53 | //write body 54 | for (var obj_name in header_obj) { 55 | if (header_obj.hasOwnProperty(obj_name)) { 56 | var offset_size = header_obj[obj_name]; 57 | var [layer_name, train_param_name] = obj_name.split('/'); 58 | var weight: $M.Matrix = net.layer_instances[layer_name][train_param_name]; 59 | var bin_view = new Float32Array(buf.buffer, offset_size.offset, offset_size.size / 4); 60 | weight.getdatacopy(null, null, bin_view); 61 | } 62 | } 63 | 64 | return buf; 65 | } 66 | 67 | static load(buf: Uint8Array, net: Network): void { 68 | //parse header 69 | var header_str = ''; 70 | for (var i = 0; i < 32768; i++) { 71 | if (buf[i] == 0) { 72 | break; 73 | } 74 | header_str += String.fromCharCode(buf[i]); 75 | } 76 | //console.log(header_str); 77 | var header_obj = JSON.parse(header_str); 78 | 79 | //copy body to each layer weight 80 | for (var obj_name in header_obj) { 81 | if (header_obj.hasOwnProperty(obj_name)) { 82 | var offset_size = header_obj[obj_name]; 83 | var [layer_name, train_param_name] = obj_name.split('/'); 84 | //console.log(layer_name); 85 | var weight: $M.Matrix = net.layer_instances[layer_name][train_param_name]; 86 | var bin_view = new Float32Array(buf.buffer, offset_size.offset, offset_size.size / 4); 87 | if (weight) { 88 | weight.setdata(bin_view); 89 | } 90 | } 91 | } 92 | } 93 | } 94 | 95 | export = ArraySerializer; 96 | -------------------------------------------------------------------------------- /src/forward_configuration.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | class ForwardConfiguration { 3 | phase: string; 4 | devicetype: string; 5 | constructor() { 6 | } 7 | } 8 | 9 | export = ForwardConfiguration; 10 | -------------------------------------------------------------------------------- /src/layers/accuracy_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class AccuracyLayer extends Layer { 7 | constructor(params: any) { 8 | super(); 9 | } 10 | 11 | init(callback: () => void): void { 12 | setImmediate(callback); 13 | } 14 | 15 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 16 | //softmax cross entropy 17 | var data: $M.Matrix = bottoms[0]; 18 | var gtlabel: $M.Matrix = bottoms[1];//label: 0 to nlabel-1 19 | let accuracy = $M.autodestruct(() => { 20 | var predlabel = $M.argmax(data, 0, 1).I;//1 to nlabel 21 | predlabel = $M.minus(predlabel, 1); 22 | var match = $M.eq(gtlabel, predlabel); 23 | let accuracy = $M.sum(match).get() / $M.numel(match); 24 | return accuracy; 25 | }); 26 | 27 | setImmediate(function () { 28 | callback([$M.jsa2mat([accuracy])]); 29 | }); 30 | } 31 | 32 | release(): void { 33 | } 34 | 35 | destruct(): void { 36 | 37 | } 38 | } 39 | 40 | export = AccuracyLayer; 41 | -------------------------------------------------------------------------------- /src/layers/blob_data_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | import fs = require('fs'); 6 | 7 | class BlobDataLayer extends Layer { 8 | length: number; 9 | label: $M.Matrix; 10 | data_shape: number[]; 11 | file_prefix: string; 12 | data_klass: string; 13 | data_klass_size: number; 14 | data_file: any; 15 | record_size: number; 16 | 17 | constructor(public params: any) { 18 | super(); 19 | this.file_prefix = params.file_prefix; 20 | this.data_shape = params.data_shape; 21 | this.data_klass = params.data_klass || 'uint8'; 22 | switch (this.data_klass) { 23 | case 'single': 24 | this.data_klass_size = 4; 25 | break; 26 | case 'uint8': 27 | this.data_klass_size = 1; 28 | break; 29 | default: 30 | throw new Error('Unsupported data_klass'); 31 | } 32 | this.record_size = this.data_shape.reduce((pv, cv) => pv * cv, 1) * this.data_klass_size; 33 | } 34 | 35 | init(callback: () => void): void { 36 | var label_ary = new Int32Array(JSON.parse(fs.readFileSync(this.file_prefix + '.json', 'utf8'))); 37 | this.label = $M.typedarray2mat([1, label_ary.length], 'int32', label_ary); 38 | this.length = label_ary.length; 39 | this.data_file = fs.openSync(this.file_prefix + '.bin', 'r'); 40 | console.log('Data length set to ' + this.length); 41 | setImmediate(callback); 42 | } 43 | 44 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 45 | var range: $M.Matrix = bottoms[0];//[from, to] 46 | var range_min = range.get(1);//1 to length 47 | var range_size = range.get(2); 48 | range_min = (range_min - 1) % this.length + 1; 49 | if (range_min + range_size - 1 > this.length) { 50 | range_min = 1; 51 | } 52 | var range_max = range_min + range_size - 1; 53 | var batch_label = this.label.get($M.colon(), $M.colon(range_min, range_max)); 54 | var buffer = new Buffer(this.record_size * range_size); 55 | fs.read(this.data_file, buffer, 0, this.record_size * range_size, this.record_size * (range_min - 1), 56 | (err, bytesRead, _buffer) => { 57 | var rawimgs; 58 | switch (this.data_klass) { 59 | case 'single': 60 | rawimgs = new Float32Array(buffer.buffer); 61 | break; 62 | case 'uint8': 63 | rawimgs = new Uint8Array(buffer.buffer); 64 | break; 65 | } 66 | var batch_data = $M.typedarray2mat(this.data_shape.concat(range_size), this.data_klass, rawimgs); 67 | if (config.devicetype == 'cl') { 68 | var batch_data2 = batch_data; 69 | batch_data = $M.gpuArray(batch_data2); 70 | batch_data2.destruct(); 71 | var batch_label2 = batch_label; 72 | batch_label = $M.gpuArray(batch_label2); 73 | batch_label2.destruct(); 74 | } 75 | buffer = null; 76 | // pseudo read ahead (to disk cache) 77 | var buffer_dummy = new Buffer(this.record_size * range_size); 78 | fs.read(this.data_file, buffer_dummy, 0, this.record_size * range_size, this.record_size * (range_max), 79 | (err, bytesRead, _buffer) => {}); 80 | callback([batch_data, batch_label]); 81 | }); 82 | 83 | } 84 | 85 | release(): void { 86 | 87 | } 88 | 89 | destruct(): void { 90 | fs.closeSync(this.data_file); 91 | } 92 | } 93 | 94 | export = BlobDataLayer; 95 | -------------------------------------------------------------------------------- /src/layers/branch_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class BranchLayer extends Layer { 7 | n_output: number; 8 | 9 | constructor(params: any) { 10 | super(); 11 | 12 | if (!(params.n_output >= 1)) { 13 | throw Error('n_output must be positive integer'); 14 | } 15 | this.n_output = params.n_output; 16 | } 17 | 18 | init(callback: () => void): void { 19 | setImmediate(callback); 20 | } 21 | 22 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 23 | //copy inputs 24 | var data: $M.Matrix = bottoms[0]; 25 | var outputs = []; 26 | for (var i = 0; i < this.n_output; i++) { 27 | outputs.push(data.copy()); 28 | } 29 | setImmediate(function() { 30 | callback(outputs); 31 | }); 32 | } 33 | 34 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 35 | //sum all deltas 36 | var top_delta: $M.Matrix = top_deltas[0]; 37 | var bottom_delta: $M.Matrix; 38 | if (this.n_output == 1) { 39 | bottom_delta = top_deltas[0].copy(); 40 | } else { 41 | bottom_delta = $M.plus(top_deltas[0], top_deltas[1]); 42 | for (var i = 2; i < this.n_output; i++) { 43 | var new_bottom_delta = $M.plus(bottom_delta, top_deltas[i]); 44 | bottom_delta.destruct(); 45 | bottom_delta = new_bottom_delta; 46 | } 47 | } 48 | 49 | setImmediate(function(){ 50 | callback([bottom_delta]); 51 | }); 52 | } 53 | 54 | release(): void { 55 | 56 | } 57 | 58 | destruct(): void { 59 | 60 | } 61 | } 62 | 63 | export = BranchLayer; 64 | -------------------------------------------------------------------------------- /src/layers/data_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class DataLayer extends Layer { 7 | length: number; 8 | constructor(params: any) { 9 | super(); 10 | } 11 | 12 | init(callback: () => void): void { 13 | this.length = 100; 14 | console.log('Data length set'); 15 | setImmediate(callback); 16 | } 17 | 18 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 19 | var range: $M.Matrix = bottoms[0];//[from, to] 20 | var model_weight = $M.jsa2mat([[1,2,3],[4,5,6]]); 21 | var data = $M.rand(3,5); 22 | var labels = $M.mtimes(model_weight, data); 23 | 24 | setTimeout(function() { 25 | callback([data, labels]); 26 | }, 1); 27 | } 28 | 29 | release(): void { 30 | 31 | } 32 | 33 | destruct(): void { 34 | 35 | } 36 | } 37 | 38 | export = DataLayer; 39 | -------------------------------------------------------------------------------- /src/layers/dropout_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class DropoutLayer extends Layer { 7 | dropout_ratio: number; 8 | private mask: $M.Matrix; 9 | private rndcache: $M.Matrix; 10 | 11 | constructor(params: any) { 12 | super(); 13 | this.dropout_ratio = params.dropout_ratio; 14 | if (!(this.dropout_ratio >= 0.0 && this.dropout_ratio < 1.0)) { 15 | throw Error('dropout_ratio must be 0 <= dropout_ratio < 1'); 16 | } 17 | } 18 | 19 | init(callback: () => void): void { 20 | setImmediate(callback); 21 | } 22 | 23 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 24 | var data: $M.Matrix = bottoms[0]; 25 | var output: $M.Matrix; 26 | if (config.phase == 'train') { 27 | if (config.devicetype == 'cl') { 28 | if (this.rndcache && $M.numel(this.rndcache) != $M.numel(data)) { 29 | //discard cache 30 | this.rndcache.destruct(); 31 | this.rndcache = null; 32 | } 33 | 34 | if (!this.rndcache) { 35 | //initialize random value 36 | this.rndcache = cl_init_random($M.sizejsa(data)); 37 | } 38 | 39 | // update random value and make mask 40 | this.mask = cl_update_random(this.rndcache, this.dropout_ratio); 41 | output = $M.times(data, this.mask); 42 | } else { 43 | var [m, o] = $M.autodestruct(() => { 44 | // mask = Bernoulli distribution * scale 45 | var mask = $M.rand($M.size(data)); 46 | mask = $M.ge(mask, this.dropout_ratio); 47 | mask = $M.times(mask, 1.0 / (1.0 - this.dropout_ratio)); 48 | var out = $M.times(mask, data); 49 | return [mask, out]; 50 | }); 51 | this.mask = m; 52 | output = o; 53 | } 54 | } else { 55 | output = data.copy(); 56 | } 57 | setImmediate(function () { 58 | callback([output]); 59 | }); 60 | } 61 | 62 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 63 | var data: $M.Matrix = bottoms[0]; 64 | var top_delta: $M.Matrix = top_deltas[0]; 65 | 66 | let bottom_delta: $M.Matrix; 67 | if (config.phase == 'train') { 68 | bottom_delta = $M.times(top_delta, this.mask); 69 | } else { 70 | bottom_delta = top_delta.copy(); 71 | } 72 | 73 | 74 | setImmediate(function () { 75 | callback([bottom_delta]); 76 | }); 77 | } 78 | 79 | release(): void { 80 | if (this.mask) { 81 | this.mask.destruct(); 82 | this.mask = null; 83 | } 84 | } 85 | 86 | destruct(): void { 87 | if (this.rndcache) { 88 | this.rndcache.destruct(); 89 | this.rndcache = null; 90 | } 91 | } 92 | } 93 | 94 | export = DropoutLayer; 95 | 96 | var cl_init_random_kernel: any = null; 97 | function cl_init_random(sizejsa: number[]): $M.Matrix { 98 | if (!cl_init_random_kernel) { 99 | //single thread xorshift96 100 | cl_init_random_kernel = $M.CL.createKernel([ 101 | '__kernel void kernel_func(__global int *rnd, uint length, uint x, uint y, uint z)', 102 | '{', 103 | 'uint i = get_global_id(0);', 104 | 'if (i > 0) {return;}', 105 | 'uint t;', 106 | 'for (uint j = 0; j < length; j++) {', 107 | ' t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6));', 108 | ' x = y; y = z; z = t;', 109 | ' rnd[j] = (int)t;', 110 | '}', 111 | '}'].join('\n')); 112 | } 113 | 114 | var WebCL = $M.CL.WebCL; 115 | var rnd = new $M.CL.MatrixCL(sizejsa, 'int32'); 116 | $M.CL.executeKernel(cl_init_random_kernel, [ 117 | { access: WebCL.MEM_WRITE_ONLY, datum: rnd }, 118 | { datum: $M.numel(rnd), type: WebCL.type.UINT }, 119 | { datum: Math.random() * 2147483648 | 0, type: WebCL.type.UINT }, 120 | { datum: Math.random() * 2147483648 | 0, type: WebCL.type.UINT },//channels 121 | { datum: Math.random() * 2147483648 | 0, type: WebCL.type.UINT } 122 | ], 32, 32); 123 | return rnd; 124 | } 125 | 126 | var cl_update_random_kernel: any = null; 127 | function cl_update_random(rnd: $M.Matrix, dropout_ratio: number): $M.Matrix { 128 | if (!cl_update_random_kernel) { 129 | //multi thread xorshift32 130 | cl_update_random_kernel = $M.CL.createKernel([ 131 | '__kernel void kernel_func(__global float *mask, __global int *rnd, uint length, float dropout_ratio)', 132 | '{', 133 | 'uint i = get_global_id(0);', 134 | 'if (i >= length) {return;}', 135 | 'uint y = (uint)rnd[i];', 136 | 'y = y ^ (y << 13); y = y ^ (y >> 17); y = y ^ (y << 5);', 137 | 'rnd[i] = (int)y;', 138 | 'if ((float)y > dropout_ratio * 4294967296.0F) {', 139 | ' mask[i] = 1.0F / (1.0F - dropout_ratio);', 140 | '} else {', 141 | ' mask[i] = 0.0F;', 142 | '}', 143 | '}'].join('\n')); 144 | } 145 | 146 | var WebCL = $M.CL.WebCL; 147 | var mask = new $M.CL.MatrixCL($M.sizejsa(rnd), 'single'); 148 | var numel = $M.numel(mask); 149 | $M.CL.executeKernel(cl_update_random_kernel, [ 150 | { access: WebCL.MEM_WRITE_ONLY, datum: mask }, 151 | { access: WebCL.MEM_READ_WRITE, datum: rnd }, 152 | { datum: numel, type: WebCL.type.UINT }, 153 | { datum: dropout_ratio, type: WebCL.type.FLOAT } 154 | ], numel); 155 | return mask; 156 | } 157 | -------------------------------------------------------------------------------- /src/layers/image_load_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import jpg = require('jpeg-turbo'); 4 | import fs = require('fs'); 5 | import ForwardConfiguration = require('../forward_configuration'); 6 | import Layer = require('./layer'); 7 | 8 | class ImageLoadLayer extends Layer { 9 | base_dir: string; 10 | shuffle: boolean; 11 | grayscale: boolean; 12 | list_path: string; 13 | file_paths: string[]; 14 | file_labels: $M.Matrix;//int32 row vector of labels 15 | length: number; 16 | 17 | constructor(params: any) { 18 | super(); 19 | 20 | // params: {list_path: string, shuffle: boolean, base_dir: string} 21 | // file format: foo.jpg 1(integer label) 22 | 23 | this.base_dir = (params['base_dir'] || '.') + '/'; 24 | this.shuffle = params['shuffle'] || false; 25 | this.grayscale = params['grayscale'] || false; 26 | if (typeof params['list_path'] !== 'string') { 27 | throw Error('list_path must be string'); 28 | } 29 | this.list_path = params['list_path']; 30 | } 31 | 32 | init(callback: () => void): void { 33 | fs.readFile(this.list_path, 'utf8', (err, data) => { 34 | if (err) { 35 | throw err; 36 | } 37 | var lines = data.split(/\r?\n/); 38 | var fps: string[] = []; 39 | var fls: number[] = []; 40 | for (var i = 0; i < lines.length; i++) { 41 | var element = lines[i]; 42 | if (element.length == 0) { 43 | break; 44 | } 45 | var [fp, fl] = element.split(' '); 46 | fps.push(fp); 47 | fls.push(Number(fl)); 48 | } 49 | 50 | this.length = this.file_paths.length; 51 | 52 | if (this.shuffle) { 53 | // do Fisher-Yates shuffle 54 | var n = this.length; 55 | for (var i = n - 1; i >= 1; i--) { 56 | var j = Math.floor(Math.random() * (i + 1));// [0, i] 57 | var fptmp = fps[j]; 58 | fps[j] = fps[i]; 59 | fps[i] = fptmp; 60 | var fltmp = fls[j]; 61 | fls[j] = fls[i]; 62 | fls[i] = fltmp; 63 | } 64 | } 65 | 66 | this.file_paths = fps; 67 | this.file_labels = $M.jsa2mat(fls, false, 'int32'); 68 | 69 | callback(); 70 | }); 71 | } 72 | 73 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 74 | var range: $M.Matrix = bottoms[0]; 75 | var range_min = (range.get(1) - 1) % this.length + 1; 76 | var range_size = range.get(2); 77 | var labels: $M.Matrix; 78 | var paths: string[] = []; 79 | if (range_min + range_size > this.length) { 80 | //tail and head 81 | labels = $M.horzcat(this.file_labels.get(1, $M.colon(range_min, null)), 82 | this.file_labels.get(1, $M.colon(null, range_size - this.length - range_min - 1))); 83 | for (var i = range_min - 1; i < this.length; i++) { 84 | paths.push(this.file_paths[i]); 85 | } 86 | for (var i = 0; i < range_size - this.length - range_min - 1; i++) { 87 | paths.push(this.file_paths[i]); 88 | } 89 | } else { 90 | labels = this.file_labels.get(1, $M.colon(range_min, range_min + range_size - 1)); 91 | for (var i = range_min - 1; i < range_min + range_size - 1; i++) { 92 | paths.push(this.file_paths[i]); 93 | } 94 | } 95 | 96 | var img_bufs = []; 97 | var read_count = 0; 98 | var read_and_store = function (i, path) { 99 | fs.readFile(path, function (err, data) { 100 | if (err) { 101 | throw err; 102 | } 103 | process_loaded_data(i, data); 104 | }); 105 | }; 106 | 107 | var jpg_format = { format: this.grayscale ? jpg.FORMAT_GRAY : jpg.FORMAT_RGB }; 108 | 109 | var process_loaded_data = function (i, data) { 110 | img_bufs[i] = jpg.decompressSync(data, jpg_format); 111 | read_count++; 112 | if (read_count == range_size) { 113 | generate_mat(); 114 | } 115 | }; 116 | 117 | var generate_mat = function () { 118 | var width = img_bufs[0].width; 119 | var height = img_bufs[0].height; 120 | var n_channel = this.grayscale ? 1 : 3; 121 | var data = new Float32Array(width * height * n_channel * range_size);//[ch, w, h, n] 122 | for (var i = 0; i < range_size; i++) { 123 | data.set(img_bufs[i].data, i * width * height * n_channel); 124 | } 125 | var mat_cwhn = $M.typedarray2mat([n_channel, width, height, range_size], 'single', data); 126 | var mat_hwcn = $M.permute(mat_cwhn, [3, 2, 1, 4]);//[h, w, ch, n] 127 | callback([mat_hwcn, labels]); 128 | }; 129 | 130 | for (var i = 0; i < paths.length; i++) { 131 | read_and_store(i, paths[i]); 132 | } 133 | } 134 | 135 | release(): void { 136 | 137 | } 138 | 139 | destruct(): void { 140 | 141 | } 142 | } 143 | 144 | export = ImageLoadLayer; 145 | -------------------------------------------------------------------------------- /src/layers/index.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import Layer = require('./layer'); 3 | export import LinearLayer = require('./linear_layer'); 4 | export import BranchLayer = require('./branch_layer'); 5 | export import PlusLayer = require('./plus_layer'); 6 | export import DataLayer = require('./data_layer'); 7 | export import LossLayer = require('./loss_layer'); 8 | export import MnistDataLayer = require('./mnist_data_layer'); 9 | export import BlobDataLayer = require('./blob_data_layer'); 10 | export import DataAugmentationLayer = require('./data_augmentation_layer'); 11 | export import SoftmaxCrossEntropyLayer = require('./softmax_cross_entropy_layer'); 12 | export import ReluLayer = require('./relu_layer'); 13 | export import AccuracyLayer = require('./accuracy_layer'); 14 | export import Convolution2DLayer = require('./convolution_2d_layer'); 15 | export import Pooling2DLayer = require('./pooling_2d_layer'); 16 | export import BatchNormalizationLayer = require('./batch_normalization_layer'); 17 | export import DropoutLayer = require('./dropout_layer'); 18 | -------------------------------------------------------------------------------- /src/layers/layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | 5 | class Layer { 6 | train_params: string[]; 7 | delta_params: string[]; 8 | need_update: boolean; 9 | 10 | constructor() { 11 | this.need_update = false; 12 | } 13 | 14 | init(callback: () => void): void { 15 | setImmediate(callback); 16 | } 17 | 18 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 19 | throw new Error('Not implemented'); 20 | } 21 | 22 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 23 | throw new Error('Not implemented'); 24 | } 25 | 26 | calculateUpdateParams(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: () => void): void { 27 | setImmediate(function () { 28 | callback(); 29 | }); 30 | } 31 | 32 | to_cpu(): void { 33 | if (this.train_params) { 34 | for (var i = 0; i < this.train_params.length; i++) { 35 | var param_name = this.train_params[i]; 36 | var m: $M.Matrix = this[param_name]; 37 | if ($M.devicetype(m) == 'cl') { 38 | var cpum = $M.gather(m); 39 | this[param_name] = cpum; 40 | m.destruct(); 41 | } 42 | } 43 | } 44 | } 45 | 46 | to_cl(): void { 47 | if (this.train_params) { 48 | for (var i = 0; i < this.train_params.length; i++) { 49 | var param_name = this.train_params[i]; 50 | var m: $M.Matrix = this[param_name]; 51 | if ($M.devicetype(m) == 'cpu') { 52 | var clm = $M.gpuArray(m); 53 | this[param_name] = clm; 54 | m.destruct(); 55 | } 56 | } 57 | } 58 | } 59 | 60 | release(): void { 61 | //release internal data for a batch 62 | } 63 | 64 | destruct(): void { 65 | //release data in the layer 66 | } 67 | } 68 | 69 | export = Layer; 70 | -------------------------------------------------------------------------------- /src/layers/layer_factory.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import Layer = require('./layer'); 3 | import Layers = require('./index'); 4 | 5 | class LayerFactory { 6 | static create(type: string, params: any): Layer { 7 | switch (type) { 8 | case 'data': 9 | return new Layers.DataLayer(params); 10 | case 'linear': 11 | return new Layers.LinearLayer(params); 12 | case 'branch': 13 | return new Layers.BranchLayer(params); 14 | case 'plus': 15 | return new Layers.PlusLayer(params); 16 | case 'loss': 17 | return new Layers.LossLayer(params); 18 | case 'mnist_data': 19 | return new Layers.MnistDataLayer(params); 20 | case 'blob_data': 21 | return new Layers.BlobDataLayer(params); 22 | case 'data_augmentation': 23 | return new Layers.DataAugmentationLayer(params); 24 | case 'softmax_cross_entropy': 25 | return new Layers.SoftmaxCrossEntropyLayer(params); 26 | case 'relu': 27 | return new Layers.ReluLayer(params); 28 | case 'accuracy': 29 | return new Layers.AccuracyLayer(params); 30 | case 'convolution_2d': 31 | return new Layers.Convolution2DLayer(params); 32 | case 'pooling_2d': 33 | return new Layers.Pooling2DLayer(params); 34 | case 'batch_normalization': 35 | return new Layers.BatchNormalizationLayer(params); 36 | case 'dropout': 37 | return new Layers.DropoutLayer(params); 38 | default: 39 | throw new Error('Unknown layer'); 40 | } 41 | } 42 | } 43 | 44 | export = LayerFactory; 45 | -------------------------------------------------------------------------------- /src/layers/linear_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Layer = require('./layer'); 4 | import ForwardConfiguration = require('../forward_configuration'); 5 | import mtimes_trans = require('../utils/mtimes_trans'); 6 | 7 | class LinearLayer extends Layer { 8 | weight: $M.Matrix; 9 | bias: $M.Matrix; 10 | delta_weight: $M.Matrix; 11 | delta_bias: $M.Matrix; 12 | in_size: number; 13 | out_size: number; 14 | in_shape: number[]; 15 | 16 | constructor(params: any) { 17 | super(); 18 | this.need_update = true; 19 | // scalar (1-dim) or size array (output shape from conv layer) 20 | if (params.in_shape) { 21 | this.in_shape = params.in_shape; 22 | } else { 23 | this.in_shape = [params.in_size]; 24 | } 25 | this.in_size = this.in_shape.reduce((prev, cur) => prev * cur, 1); 26 | this.out_size = params.out_size; 27 | this.weight = $M.times($M.randn(this.in_size, this.out_size), 1.0 / Math.sqrt(this.in_size)); 28 | this.bias = $M.zeros(this.out_size, 1); 29 | this.delta_weight = null;//$M.zeros(in_size, out_size); 30 | this.delta_bias = null;//$M.zeros(out_size, 1); 31 | this.train_params = ['weight', 'bias']; 32 | this.delta_params = ['delta_weight', 'delta_bias']; 33 | } 34 | 35 | init(callback: () => void): void { 36 | setImmediate(callback); 37 | } 38 | 39 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 40 | //multiply input by weight 41 | var data: $M.Matrix = bottoms[0]; 42 | var data_orig_shape = $M.size(data); 43 | // convert to 2d with keeping batch length (flatten in fortran-order) 44 | data.reshape_inplace(-1, $M.size(data, this.in_shape.length + 1)); 45 | //batch: [dim, sample] 46 | var top = $M.autodestruct(() => { 47 | var output = mtimes_trans.mtimes_trans(this.weight, data, true, false); 48 | var output_with_bias = $M.plus(output, $M.repmat(this.bias, 1, $M.sizejsa(data)[1])); 49 | return output_with_bias; 50 | }); 51 | data.reshape_inplace(data_orig_shape); 52 | 53 | setImmediate(function () { 54 | callback([top]); 55 | }); 56 | } 57 | 58 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 59 | var data: $M.Matrix = bottoms[0]; 60 | var top_delta: $M.Matrix = top_deltas[0]; 61 | var data_orig_shape = $M.size(data); 62 | 63 | var bottom_delta = $M.autodestruct(() => { 64 | var result = $M.mtimes(this.weight, top_delta); 65 | result.reshape_inplace(data_orig_shape); 66 | return result; 67 | }); 68 | 69 | setImmediate(function () { 70 | callback([bottom_delta]); 71 | }); 72 | } 73 | 74 | calculateUpdateParams(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: () => void): void { 75 | var data: $M.Matrix = bottoms[0]; 76 | var top_delta: $M.Matrix = top_deltas[0]; 77 | // convert to 2d with keeping batch length 78 | var data_orig_shape = $M.size(data); 79 | data.reshape_inplace(-1, $M.size(data, this.in_shape.length + 1)); 80 | 81 | var delta_weight = mtimes_trans.mtimes_trans(data, top_delta, false, true); 82 | var new_delta_weight = $M.plus(this.delta_weight, delta_weight); 83 | delta_weight.destruct(); 84 | 85 | this.delta_weight.destruct(); 86 | this.delta_weight = new_delta_weight; 87 | var new_delta_bias = $M.autodestruct(() => { 88 | var delta_bias = $M.sum(top_delta, 2); 89 | return $M.plus(this.delta_bias, delta_bias); 90 | }); 91 | this.delta_bias.destruct(); 92 | this.delta_bias = new_delta_bias; 93 | 94 | data.reshape_inplace(data_orig_shape); 95 | 96 | setImmediate(function () { 97 | callback(); 98 | }); 99 | } 100 | 101 | release(): void { 102 | 103 | } 104 | 105 | destruct(): void { 106 | 107 | } 108 | } 109 | 110 | export = LinearLayer; 111 | -------------------------------------------------------------------------------- /src/layers/loss_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Layer = require('./layer'); 4 | import ForwardConfiguration = require('../forward_configuration'); 5 | 6 | class LossLayer extends Layer { 7 | 8 | constructor(params: any) { 9 | super(); 10 | } 11 | 12 | init(callback: () => void): void { 13 | setImmediate(callback); 14 | } 15 | 16 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 17 | //square loss 18 | var data: $M.Matrix = bottoms[0]; 19 | var gt: $M.Matrix = bottoms[1]; 20 | var loss = $M.autodestruct(() => $M.times($M.sum($M.sum($M.power($M.minus(data, gt), 2.0))), 1.0 / $M.numel(data))); 21 | 22 | setImmediate(function () { 23 | callback([loss]); 24 | }); 25 | } 26 | 27 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 28 | //top_deltas[0] is usually 1.0 29 | var data: $M.Matrix = bottoms[0]; 30 | var gt: $M.Matrix = bottoms[1]; 31 | var top_delta: $M.Matrix = top_deltas[0];//scalar 32 | 33 | var bottom_delta = $M.autodestruct(() => $M.times($M.minus(data, gt), $M.times(top_delta, 1.0 / $M.numel(data)))); 34 | 35 | setImmediate(function () { 36 | callback([bottom_delta]); 37 | }); 38 | } 39 | 40 | release(): void { 41 | 42 | } 43 | 44 | destruct(): void { 45 | 46 | } 47 | } 48 | 49 | export = LossLayer; 50 | -------------------------------------------------------------------------------- /src/layers/mnist_data_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | import fs = require('fs'); 6 | 7 | class MnistDataLayer extends Layer { 8 | length: number; 9 | data: $M.Matrix; 10 | label: $M.Matrix; 11 | data_shape: number[] = [28, 28, 1]; 12 | constructor(public params: any) { 13 | super(); 14 | } 15 | 16 | init(callback: () => void): void { 17 | var label_ary = new Uint8Array(fs.readFileSync(this.params.label).buffer); 18 | fs.readFile(this.params.data, (err, data) => { 19 | var data_ary = new Float32Array(data.buffer); 20 | this.label = $M.typedarray2mat([1, label_ary.length], 'uint8', label_ary); 21 | this.length = label_ary.length; 22 | console.log('Data length set to ' + this.length); 23 | this.data = $M.typedarray2mat(this.data_shape.concat([this.length]), 'single', data_ary); 24 | callback(); 25 | }); 26 | } 27 | 28 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 29 | var range: $M.Matrix = bottoms[0];//[from, to] 30 | var range_min = range.get(1); 31 | var range_size = range.get(2); 32 | range_min = range_min % this.length; 33 | var range_max = range_min + range_size - 1; 34 | var batch_data = this.data.get($M.colon(), $M.colon(), $M.colon(), $M.colon(range_min, range_max)); 35 | var batch_label = this.label.get($M.colon(), $M.colon(range_min, range_max)); 36 | if (config.devicetype == 'cl') { 37 | var batch_data2 = batch_data; 38 | batch_data = $M.gpuArray(batch_data2); 39 | batch_data2.destruct(); 40 | var batch_label2 = batch_label; 41 | batch_label = $M.gpuArray(batch_label2); 42 | batch_label2.destruct(); 43 | } 44 | 45 | setTimeout(function() { 46 | callback([batch_data, batch_label]); 47 | }, 1); 48 | } 49 | 50 | release(): void { 51 | 52 | } 53 | 54 | destruct(): void { 55 | 56 | } 57 | } 58 | 59 | export = MnistDataLayer; 60 | -------------------------------------------------------------------------------- /src/layers/plus_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class PlusLayer extends Layer { 7 | n_input: number; 8 | 9 | constructor(params: any) { 10 | super(); 11 | 12 | if (!(params.n_input >= 1)) { 13 | throw Error('n_input must be positive integer'); 14 | } 15 | this.n_input = params.n_input; 16 | } 17 | 18 | init(callback: () => void): void { 19 | setImmediate(callback); 20 | } 21 | 22 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 23 | //sum up inputs 24 | var top: $M.Matrix; 25 | if (this.n_input == 1) { 26 | top = bottoms[0].copy(); 27 | } else { 28 | top = $M.plus(bottoms[0], bottoms[1]); 29 | for (var i = 2; i < this.n_input; i++) { 30 | var new_top = $M.plus(top, bottoms[i]); 31 | top.destruct(); 32 | top = new_top; 33 | } 34 | } 35 | setImmediate(function() { 36 | callback([top]); 37 | }); 38 | } 39 | 40 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 41 | //copy deltas 42 | var data: $M.Matrix = top_deltas[0]; 43 | var outputs = []; 44 | for (var i = 0; i < this.n_input; i++) { 45 | outputs.push(data.copy()); 46 | } 47 | 48 | setImmediate(function(){ 49 | callback(outputs); 50 | }); 51 | } 52 | 53 | release(): void { 54 | 55 | } 56 | 57 | destruct(): void { 58 | 59 | } 60 | } 61 | 62 | export = PlusLayer; 63 | -------------------------------------------------------------------------------- /src/layers/relu_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class ReluLayer extends Layer { 7 | 8 | constructor(params: any) { 9 | super(); 10 | } 11 | 12 | init(callback: () => void): void { 13 | setImmediate(callback); 14 | } 15 | 16 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 17 | //multiply input by weight 18 | var data: $M.Matrix = bottoms[0]; 19 | //batch: [dim, sample] 20 | var output = $M.max(data, 0); 21 | setImmediate(function () { 22 | callback([output]); 23 | }); 24 | } 25 | 26 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 27 | var data: $M.Matrix = bottoms[0]; 28 | var top_delta: $M.Matrix = top_deltas[0]; 29 | 30 | let bottom_delta = $M.autodestruct(() => { 31 | let bottom_delta = $M.times(top_delta, $M.gt(data, 0)); 32 | return bottom_delta; 33 | }); 34 | 35 | setImmediate(function () { 36 | callback([bottom_delta]); 37 | }); 38 | } 39 | 40 | release(): void { 41 | 42 | } 43 | 44 | destruct(): void { 45 | 46 | } 47 | } 48 | 49 | export = ReluLayer; 50 | -------------------------------------------------------------------------------- /src/layers/softmax_cross_entropy_layer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import ForwardConfiguration = require('../forward_configuration'); 4 | import Layer = require('./layer'); 5 | 6 | class SoftmaxCrossEntropyLayer extends Layer { 7 | data_softmax: $M.Matrix; 8 | constructor(params: any) { 9 | super(); 10 | } 11 | 12 | init(callback: () => void): void { 13 | setImmediate(callback); 14 | } 15 | 16 | forward(bottoms: $M.Matrix[], config: ForwardConfiguration, callback: (tops: $M.Matrix[]) => void): void { 17 | //softmax cross entropy 18 | let data: $M.Matrix = bottoms[0]; 19 | let gtlabel: $M.Matrix = bottoms[1]; 20 | var loss: $M.Matrix; 21 | var data_softmax: $M.Matrix; 22 | if (config.devicetype == 'cl') { 23 | var c = $M.size(data, 1); 24 | var n = $M.size(data, 2); 25 | let data_softmax_log: $M.Matrix = new $M.CL.MatrixCL([1, n], 'single'); 26 | data_softmax = new $M.CL.MatrixCL([c, n], 'single'); 27 | 28 | var WebCL = $M.CL.WebCL; 29 | $M.CL.executeKernel(get_cl_forward_kernel(), [ 30 | { access: WebCL.MEM_WRITE_ONLY, datum: data_softmax_log }, 31 | { access: WebCL.MEM_WRITE_ONLY, datum: data_softmax }, 32 | { access: WebCL.MEM_READ_ONLY, datum: data }, 33 | { access: WebCL.MEM_READ_ONLY, datum: gtlabel }, 34 | { datum: c, type: WebCL.type.UINT }, 35 | { datum: n, type: WebCL.type.UINT } 36 | ], n, 32); 37 | loss = $M.sum(data_softmax_log); 38 | data_softmax_log.destruct(); 39 | } else { 40 | [loss, data_softmax] = $M.autodestruct(() => { 41 | let gt = $M.zeros($M.size(data)); 42 | let batch_size = $M.sizejsa(gtlabel)[1];//number of column 43 | let data_exp = $M.exp(data); 44 | let data_exp_sum = $M.repmat($M.sum(data_exp, 1), $M.sizejsa(data)[0], 1); 45 | let data_softmax = $M.rdivide(data_exp, data_exp_sum); 46 | let data_softmax_log = $M.log(data_softmax); 47 | let loss = $M.zeros(1); 48 | for (let sample = 1; sample <= batch_size; sample++) { 49 | let label = gtlabel.get(sample) + 1; 50 | loss = $M.minus(loss, data_softmax_log.get(label, sample) / batch_size); 51 | } 52 | return [loss, data_softmax]; 53 | }); 54 | } 55 | 56 | this.data_softmax = data_softmax; 57 | setImmediate(function () { 58 | callback([loss]); 59 | }); 60 | } 61 | 62 | backward(bottoms: $M.Matrix[], top_deltas: $M.Matrix[], config: ForwardConfiguration, callback: (bottom_deltas: $M.Matrix[]) => void): void { 63 | //top_deltas[0] is usually 1.0 64 | var data: $M.Matrix = bottoms[0]; 65 | var gtlabel: $M.Matrix = bottoms[1]; 66 | var top_delta: $M.Matrix = top_deltas[0];//scalar 67 | 68 | var bottom_delta: $M.Matrix; 69 | if (config.devicetype == 'cl') { 70 | bottom_delta = $M.times(this.data_softmax, top_delta); 71 | } else { 72 | bottom_delta = $M.autodestruct(() => { 73 | let bottom_delta = this.data_softmax.copy(); 74 | var batch_size = $M.sizejsa(gtlabel)[1];//number of column 75 | for (var sample = 1; sample <= batch_size; sample++) { 76 | var label = gtlabel.get(sample) + 1; 77 | bottom_delta.set(label, sample, bottom_delta.get(label, sample) - 1); 78 | } 79 | 80 | bottom_delta = $M.times(bottom_delta, $M.times(top_delta, 1.0 / batch_size)); 81 | return bottom_delta; 82 | }); 83 | } 84 | 85 | setImmediate(function () { 86 | callback([bottom_delta]); 87 | }); 88 | } 89 | 90 | release(): void { 91 | if (this.data_softmax != null) { 92 | this.data_softmax.destruct(); 93 | this.data_softmax = null; 94 | } 95 | } 96 | 97 | destruct(): void { 98 | 99 | } 100 | } 101 | 102 | export = SoftmaxCrossEntropyLayer; 103 | 104 | var cl_forward_kernel: any = null; 105 | function get_cl_forward_kernel(): any { 106 | if (!cl_forward_kernel) { 107 | cl_forward_kernel = $M.CL.createKernel([ 108 | '__kernel void kernel_func(__global float *softmax_log, __global float *softmax, __global const float *score, __global const int *label, uint c, uint n)', 109 | '{', 110 | 'uint batch = get_global_id(0);', 111 | 'if (batch >= n) {return;}', 112 | 'float sample_max = score[batch * c];', 113 | 'for (int i = 1; i < c; i++) {', 114 | ' float cur_score = score[batch * c + i];', 115 | ' if (cur_score > sample_max) {', 116 | ' sample_max = cur_score;', 117 | ' }', 118 | '}', 119 | 'float exp_sum = 0.0F;', 120 | 'for (int i = 0; i < c; i++) {', 121 | ' float cur_score = score[batch * c + i];', 122 | ' float cur_score_exp = exp(cur_score - sample_max);', 123 | ' softmax[batch * c + i] = cur_score_exp;', 124 | ' exp_sum += cur_score_exp;', 125 | '}', 126 | 'for (int i = 0; i < c; i++) {', 127 | ' softmax[batch * c + i] /= exp_sum;', 128 | '}', 129 | 'softmax_log[batch] = -log(softmax[batch * c + label[batch]]) / (float)n;', 130 | 'softmax[batch * c + label[batch]] -= 1.0F;', 131 | 'for (int i = 0; i < c; i++) {', 132 | ' softmax[batch * c + i] /= n;', 133 | '}', 134 | '}' 135 | ].join('\n')); 136 | } 137 | return cl_forward_kernel; 138 | } 139 | -------------------------------------------------------------------------------- /src/optimizer.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Network = require('./network'); 4 | 5 | abstract class Optimizer { 6 | net: Network; 7 | 8 | constructor(net: Network) { 9 | this.net = net; 10 | } 11 | 12 | zero_grads(): void { 13 | //zero clear gradients 14 | for (var key in this.net.layer_instances) { 15 | if (this.net.layer_instances.hasOwnProperty(key)) { 16 | var layer_instance = this.net.layer_instances[key]; 17 | if (layer_instance.train_params == null) { 18 | continue; 19 | } 20 | for (var index = 0; index < layer_instance.train_params.length; index++) { 21 | var train_param_name = layer_instance.train_params[index]; 22 | var delta_param_name = layer_instance.delta_params[index]; 23 | if (this.net.devicetype == 'cl') { 24 | layer_instance[delta_param_name] = $M.zeros($M.size(layer_instance[train_param_name]), 'gpuArray'); 25 | } else { 26 | layer_instance[delta_param_name] = $M.zeros($M.size(layer_instance[train_param_name])); 27 | } 28 | } 29 | } 30 | } 31 | } 32 | 33 | abstract do_update(): void; 34 | 35 | update(input_vars: { [index: string]: $M.Matrix }, callback: () => void): void { 36 | this.zero_grads(); 37 | this.net.forward(input_vars, () => { 38 | this.net.backward(() => { 39 | this.do_update(); 40 | callback(); 41 | }); 42 | }); 43 | } 44 | 45 | update_divided(divided_input_vars: { [index: string]: $M.Matrix }[], callback: () => void): void { 46 | this.zero_grads(); 47 | var div_i = 0; 48 | var div_count = divided_input_vars.length; 49 | var update_once = () => { 50 | this.net.forward(divided_input_vars[div_i], () => { 51 | this.net.backward(() => { 52 | div_i++; 53 | if (div_i >= div_count) { 54 | this.do_update(); 55 | callback(); 56 | } else { 57 | this.net.release(); 58 | update_once(); 59 | } 60 | }); 61 | }); 62 | }; 63 | update_once(); 64 | } 65 | 66 | release(): void { 67 | //release gradients 68 | for (var key in this.net.layer_instances) { 69 | if (this.net.layer_instances.hasOwnProperty(key)) { 70 | var layer_instance = this.net.layer_instances[key]; 71 | if (layer_instance.train_params == null) { 72 | continue; 73 | } 74 | for (var index = 0; index < layer_instance.train_params.length; index++) { 75 | var delta_param_name = layer_instance.delta_params[index]; 76 | if (layer_instance[delta_param_name] != null) { 77 | layer_instance[delta_param_name].destruct(); 78 | layer_instance[delta_param_name] = null; 79 | } 80 | } 81 | } 82 | } 83 | this.net.release(); 84 | } 85 | 86 | destruct(): void { 87 | //release all matrices 88 | } 89 | } 90 | 91 | export = Optimizer; 92 | -------------------------------------------------------------------------------- /src/optimizers/index.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | export import OptimizerSGD = require('./optimizer_sgd'); 3 | export import OptimizerMomentumSGD = require('./optimizer_momentum_sgd'); 4 | -------------------------------------------------------------------------------- /src/optimizers/optimizer_momentum_sgd.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Network = require('../network'); 4 | import Optimizer = require('../optimizer'); 5 | 6 | class OptimizerSGD extends Optimizer { 7 | lr: number;//learning rate 8 | momentum: number; 9 | last_deltas: { [index: string]: $M.Matrix }; 10 | 11 | constructor(net: Network, lr: number = 0.01, momentum: number = 0.9) { 12 | super(net); 13 | this.lr = lr; 14 | this.momentum = momentum; 15 | this.last_deltas = {}; 16 | } 17 | 18 | do_update(): void { 19 | // update params 20 | for (var key in this.net.layer_instances) { 21 | if (this.net.layer_instances.hasOwnProperty(key)) { 22 | var layer_instance = this.net.layer_instances[key]; 23 | if (layer_instance.train_params == null) { 24 | continue; 25 | } 26 | for (var index = 0; index < layer_instance.train_params.length; index++) { 27 | var train_param_name = layer_instance.train_params[index]; 28 | var delta_param_name = layer_instance.delta_params[index]; 29 | var cur_weight: $M.Matrix = layer_instance[train_param_name]; 30 | var cur_grad: $M.Matrix = layer_instance[delta_param_name]; 31 | var param_global_name = key + '/' + train_param_name; 32 | var last_delta: $M.Matrix = this.last_deltas[param_global_name]; 33 | var new_weight: $M.Matrix, new_last_delta: $M.Matrix; 34 | $M.autodestruct(() => { 35 | if (last_delta) { 36 | new_last_delta = $M.times(last_delta, this.momentum); 37 | new_last_delta = $M.plus(new_last_delta, $M.times(cur_grad, -this.lr)); 38 | } else { 39 | new_last_delta = $M.times(cur_grad, -this.lr); 40 | } 41 | new_weight = $M.plus(cur_weight, new_last_delta); 42 | return [new_weight, new_last_delta]; 43 | }) 44 | cur_weight.destruct(); 45 | layer_instance[train_param_name] = new_weight; 46 | if (last_delta) { 47 | last_delta.destruct(); 48 | } 49 | this.last_deltas[param_global_name] = new_last_delta; 50 | } 51 | } 52 | } 53 | } 54 | 55 | release(): void { 56 | super.release(); 57 | } 58 | 59 | destruct(): void { 60 | super.destruct(); 61 | for (var key in this.last_deltas) { 62 | if (this.last_deltas.hasOwnProperty(key)) { 63 | var last_delta = this.last_deltas[key]; 64 | last_delta.destruct(); 65 | } 66 | } 67 | this.last_deltas = {}; 68 | } 69 | } 70 | 71 | export = OptimizerSGD; 72 | -------------------------------------------------------------------------------- /src/optimizers/optimizer_sgd.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | import Network = require('../network'); 4 | import Optimizer = require('../optimizer'); 5 | 6 | class OptimizerSGD extends Optimizer { 7 | lr: number;//learning rate 8 | 9 | constructor(net: Network, lr: number = 0.01) { 10 | super(net); 11 | this.lr = lr; 12 | } 13 | 14 | do_update(): void { 15 | // update params 16 | for (var key in this.net.layer_instances) { 17 | if (this.net.layer_instances.hasOwnProperty(key)) { 18 | var layer_instance = this.net.layer_instances[key]; 19 | if (layer_instance.train_params == null) { 20 | continue; 21 | } 22 | for (var index = 0; index < layer_instance.train_params.length; index++) { 23 | var train_param_name = layer_instance.train_params[index]; 24 | var delta_param_name = layer_instance.delta_params[index]; 25 | var cur_weight: $M.Matrix = layer_instance[train_param_name]; 26 | var cur_grad: $M.Matrix = layer_instance[delta_param_name]; 27 | var new_weight = $M.autodestruct(() => $M.plus(cur_weight, $M.times(cur_grad, -this.lr))); 28 | cur_weight.destruct(); 29 | layer_instance[train_param_name] = new_weight; 30 | } 31 | } 32 | } 33 | } 34 | 35 | release(): void { 36 | super.release(); 37 | } 38 | } 39 | 40 | export = OptimizerSGD; 41 | -------------------------------------------------------------------------------- /src/sukiyaki.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | export import Network = require('./network'); 3 | export import Optimizers = require('./optimizers'); 4 | export import ArraySerializer = require('./array_serializer'); 5 | export import Layer = require('./layers/layer'); 6 | export import Layers = require('./layers'); 7 | export import LayerFactory = require('./layers/layer_factory'); 8 | export import ForwardConfiguration = require('./forward_configuration'); 9 | export import DettmersWeightCompression = require('./utils/dettmers_weight_compression'); 10 | -------------------------------------------------------------------------------- /src/utils/array_helper.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | // Helper functions of Array 3 | 4 | export function repeat_scalar(val: number | number[], length: number): number[] { 5 | if ((val).length !== void 0) { 6 | //val is array 7 | if ((val).length !== length) { 8 | throw Error('val is not length ' + length); 9 | } 10 | return (val); 11 | } else { 12 | //val is scalar 13 | var array = []; 14 | for (var i = 0; i < length; i++) { 15 | array.push(val); 16 | } 17 | return array; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/utils/mtimes_trans.ts: -------------------------------------------------------------------------------- 1 | // (c) 2016 Machine Intelligence Laboratory (The University of Tokyo), MIT License. 2 | import $M = require('milsushi2'); 3 | 4 | export function mtimes_trans(A: $M.Matrix, B: $M.Matrix, trans_a: boolean, trans_b: boolean): $M.Matrix { 5 | var devicetype = $M.devicetype(A); 6 | if (devicetype !== $M.devicetype(B)) { 7 | throw new Error('devicetype mismatch'); 8 | } 9 | if (devicetype == 'cl') { 10 | return mtimes_trans_cl(A, B, trans_a, trans_b); 11 | } else { 12 | if (trans_a) { 13 | A = $M.t(A); 14 | } 15 | if (trans_b) { 16 | B = $M.t(B); 17 | } 18 | var C = $M.mtimes(A, B); 19 | if (trans_a) { 20 | A.destruct(); 21 | } 22 | if (trans_b) { 23 | B.destruct(); 24 | } 25 | return C; 26 | } 27 | } 28 | 29 | export function mtimes_trans_cl(A: $M.Matrix, B: $M.Matrix, trans_a: boolean, trans_b: boolean): $M.Matrix { 30 | if (A._ndims != 2 || B._ndims != 2) { 31 | throw new Error('Matrix must be two-dimensional'); 32 | } 33 | if (A._klass != 'single' || B._klass != 'single') { 34 | throw new Error('Matrix klass must be single'); 35 | } 36 | var m: number, n: number, k: number; 37 | var lda: number, ldb: number, ldc: number; 38 | var trans_a_char = 'N', trans_b_char = 'N'; 39 | if (trans_a) { 40 | m = A._size[1]; 41 | k = A._size[0]; 42 | trans_a_char = 'T'; 43 | } else { 44 | m = A._size[0]; 45 | k = A._size[1]; 46 | } 47 | var size_mismatch = false; 48 | if (trans_b) { 49 | n = B._size[0]; 50 | if (k != B._size[1]) { 51 | size_mismatch = true; 52 | } 53 | trans_b_char = 'T'; 54 | } else { 55 | n = B._size[1]; 56 | if (k != B._size[0]) { 57 | size_mismatch = true; 58 | } 59 | } 60 | 61 | var C = new $M.CL.MatrixCL([m, n], 'single'); 62 | lda = A._strides[1]; 63 | ldb = B._strides[1]; 64 | ldc = C._strides[1]; 65 | $M.CL.sgemm(trans_a_char, trans_b_char, m, n, k, 1.0, A, lda, B, ldb, 0.0, C, ldc); 66 | return C; 67 | } 68 | 69 | 70 | export function mtimes_atrans_largek(A: $M.Matrix, B: $M.Matrix): $M.Matrix { 71 | // A^T * B 72 | var devicetype = $M.devicetype(A); 73 | if (devicetype !== $M.devicetype(B)) { 74 | throw new Error('devicetype mismatch'); 75 | } 76 | if (devicetype == 'cl') { 77 | return mtimes_largek_cl(A, B); 78 | } else { 79 | var At = $M.t(A); 80 | var C = $M.mtimes(At, B); 81 | At.destruct(); 82 | return C; 83 | } 84 | } 85 | 86 | var mtimes_largek_cl_kernel = null; 87 | function mtimes_largek_cl(A: $M.Matrix, B: $M.Matrix) { 88 | // A^T * B 89 | var m: number, k: number, n: number; 90 | 91 | k = A._size[0]; 92 | m = A._size[1]; 93 | n = B._size[1]; 94 | var C = new $M.CL.MatrixCL([m, n], 'single'); 95 | 96 | var group_size = 256; 97 | if (!mtimes_largek_cl_kernel) { 98 | mtimes_largek_cl_kernel = $M.CL.createKernel([ 99 | '#define GROUP_SIZE ' + group_size, 100 | '__kernel void kernel_func(__global float *C, __global const float *A, __global const float *B, uint m, uint n, uint k)', 101 | '{', 102 | 'uint i = get_group_id(0);', 103 | 'uint j = get_group_id(1);', 104 | 'uint l = get_local_id(0);', 105 | '__local float local_sums[GROUP_SIZE];', 106 | 'float local_sum = 0.0F;', 107 | 'for (uint s = l; s < k; s+=GROUP_SIZE) {', 108 | ' local_sum += A[s+k*i]*B[s+k*j];', 109 | '}', 110 | 'local_sums[l] = local_sum;', 111 | 'barrier(CLK_LOCAL_MEM_FENCE);', 112 | 'if (l == 0) {', 113 | 'for (uint g = 1; g < GROUP_SIZE; g++) {', 114 | ' local_sum += local_sums[g];', 115 | '}', 116 | 'C[i+m*j]=local_sum;', 117 | '}', 118 | '}' 119 | ].join('\n')); 120 | } 121 | 122 | var WebCL = $M.CL.WebCL; 123 | $M.CL.executeKernel(mtimes_largek_cl_kernel, [ 124 | { access: WebCL.MEM_WRITE_ONLY, datum: C }, 125 | { access: WebCL.MEM_READ_ONLY, datum: A }, 126 | { access: WebCL.MEM_READ_ONLY, datum: B }, 127 | { datum: m, type: WebCL.type.UINT }, 128 | { datum: n, type: WebCL.type.UINT }, 129 | { datum: k, type: WebCL.type.UINT } 130 | ], [m * group_size, n], [group_size, 1]); 131 | 132 | return C; 133 | } 134 | -------------------------------------------------------------------------------- /train_resnet.ts: -------------------------------------------------------------------------------- 1 | import $M = require('milsushi2'); 2 | import Sukiyaki = require('./index'); 3 | var Network = Sukiyaki.Network; 4 | var OptimizerSGD = Sukiyaki.Optimizers.OptimizerSGD; 5 | var ArraySerializer = Sukiyaki.ArraySerializer; 6 | import fs = require('fs'); 7 | 8 | function train_imagenet(load_weight: boolean = false, cl: boolean = false) { 9 | if (cl) { 10 | $M.initcl(); 11 | } 12 | var layers = JSON.parse(fs.readFileSync('netdef/vgg16.json', 'utf8')); 13 | var net = new Network(layers); 14 | net.init(() => { 15 | if (cl) { 16 | net.to_cl(); 17 | } 18 | net.layer_time = {}; 19 | var opt = new Sukiyaki.Optimizers.OptimizerMomentumSGD(net, 1e-3, 0.9); 20 | var data_mean = $M.permute($M.npyread(fs.readFileSync('./imagenet_mean.npy')), [2, 3, 1]);//to h, w, c 21 | (net.layer_instances["aug_train"]).set_data_mean(data_mean); 22 | (net.layer_instances["aug_test"]).set_data_mean(data_mean); 23 | var batch_size = 8; 24 | 25 | if (load_weight) { 26 | console.log('loading net'); 27 | var buf = new Uint8Array(fs.readFileSync('/var/tmp/sukiyaki_weight_resnet308_lr1e-2_iter196000.bin').buffer); 28 | ArraySerializer.load(buf, net); 29 | } 30 | 31 | var iter = 0; 32 | var max_iter = 200000; 33 | var next_iter = () => { 34 | if (iter % 10 == 0) { 35 | console.log("iteration " + iter + ' ' + (new Date())); 36 | if (cl) { 37 | console.log("buffers: " + $M.CL.buffers); 38 | } 39 | } 40 | net.phase = "train"; 41 | var range_bottom = iter * batch_size + 1; 42 | var range_size = batch_size; 43 | var input_vars: { [index: string]: $M.Matrix } = { 'batch': $M.jsa2mat([range_bottom, range_size]) }; 44 | opt.update(input_vars, () => { 45 | if (iter % 10 == 0) { 46 | console.log('loss: ' + net.blobs_forward['loss']); 47 | for (var key in net.layer_time) { 48 | if (net.layer_time.hasOwnProperty(key)) { 49 | var element = net.layer_time[key]; 50 | console.log(key + '\t' + element); 51 | } 52 | } 53 | } 54 | opt.release(); 55 | if (iter < max_iter) { 56 | iter++; 57 | if (iter % 1000 == 0) { 58 | validation(); 59 | } else { 60 | next_iter(); 61 | } 62 | } else { 63 | console.log("optimization finished"); 64 | validation(); 65 | } 66 | }); 67 | 68 | }; 69 | 70 | var validation = () => { 71 | console.log("validation at iteration " + iter); 72 | net.phase = "test"; 73 | var input_vars: { [index: string]: $M.Matrix } = { 'batch': $M.jsa2mat([1, batch_size]) }; 74 | net.forward(input_vars, () => { 75 | var acc = net.blobs_forward['accuracy'].get(); 76 | console.log('accuracy ' + acc); 77 | net.release(); 78 | console.log('saving net'); 79 | var buf = ArraySerializer.dump(net); 80 | fs.writeFileSync('/var/tmp/sukiyaki_weight_vgg_'+iter+'.bin', new Buffer(buf)); 81 | if (iter < max_iter) { 82 | next_iter(); 83 | } 84 | }); 85 | }; 86 | 87 | validation(); 88 | 89 | }); 90 | 91 | return net; 92 | } 93 | 94 | export = train_imagenet; 95 | train_imagenet(false, true); 96 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "declaration": true, 7 | "inlineSources": true, 8 | "allowUnreachableCode": true 9 | }, 10 | "files": [ 11 | "index.ts", 12 | "spec/sukiyaki.spec.ts", 13 | "spec/data_augmentation.spec.ts", 14 | "run/train_node.ts", 15 | "run/classify_node.ts", 16 | "bench/index.ts" 17 | ], 18 | "exclude": [ 19 | "node_modules" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /util/convert_images_to_blob.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | """ 5 | image list to raw image blob 6 | IMAGE_CROP_SIZEx3xn 7 | float32 8 | """ 9 | 10 | import sys 11 | import os 12 | import numpy as np 13 | from PIL import Image 14 | import json 15 | 16 | IMAGE_RESIZE_SIZE = (256, 256) 17 | IMAGE_CROP_SIZE = (224, 224) 18 | MEAN_IMAGE = np.load("mean.npy") 19 | 20 | def read_image_list(path): 21 | image_path_list = [] 22 | label_list = [] 23 | with open(path) as f: 24 | for line in f: 25 | image_path, label_str = line.rstrip().split() 26 | image_path_list.append(image_path) 27 | label_list.append(int(label_str)) 28 | return image_path_list, label_list 29 | 30 | def read_augment_image(image_path): 31 | image = np.asarray(Image.open(image_path)) 32 | assert image.shape[0:2] == IMAGE_RESIZE_SIZE 33 | if image.ndim == 3: 34 | image = np.asarray(image).transpose(2, 0, 1)#rgb, h, w 35 | else: 36 | image = np.array([image, image, image]) 37 | image = image.astype(np.float32) 38 | crop_top = (IMAGE_RESIZE_SIZE[0] - IMAGE_CROP_SIZE[0]) // 2 39 | crop_left = (IMAGE_RESIZE_SIZE[1] - IMAGE_CROP_SIZE[1]) // 2 40 | image -= MEAN_IMAGE 41 | cropped_image = image[:, crop_top:crop_top+IMAGE_CROP_SIZE[0], crop_left:crop_left+IMAGE_CROP_SIZE[1]] 42 | cropped_image /= 255. 43 | return cropped_image 44 | 45 | def process(image_list_path, dst_prefix): 46 | image_path_list, label_list = read_image_list(image_list_path) 47 | with open(dst_prefix + ".bin", "wb") as f: 48 | for image_path in image_path_list: 49 | image_array = read_augment_image(image_path) 50 | image_array_cwh = image_array.transpose(0, 2, 1)#rgb, w, h 51 | image_array_cwh.tofile(f)#c-order, h-w-c viewed in f-order 52 | with open(dst_prefix + ".json", "wb") as f: 53 | json.dump(label_list, f) 54 | 55 | if __name__ == '__main__': 56 | image_list_path = sys.argv[1] 57 | dst_prefix = sys.argv[2] 58 | process(image_list_path, dst_prefix) 59 | 60 | -------------------------------------------------------------------------------- /util/convert_images_to_blob_raw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | """ 5 | image list to raw image blob 6 | IMAGE_RESIZE_SIZEx3xn 7 | uint8 8 | """ 9 | 10 | import sys 11 | import os 12 | import numpy as np 13 | from PIL import Image 14 | import json 15 | 16 | IMAGE_RESIZE_SIZE = (256, 256) 17 | 18 | def read_image_list(path): 19 | image_path_list = [] 20 | label_list = [] 21 | with open(path) as f: 22 | for line in f: 23 | image_path, label_str = line.rstrip().split() 24 | image_path_list.append(image_path) 25 | label_list.append(int(label_str)) 26 | return image_path_list, label_list 27 | 28 | def read_augment_image(image_path): 29 | image = np.asarray(Image.open(image_path)) 30 | assert image.shape[0:2] == IMAGE_RESIZE_SIZE 31 | if image.ndim == 3: 32 | image = np.asarray(image).transpose(2, 0, 1)#rgb, h, w 33 | else: 34 | image = np.array([image, image, image]) 35 | image = image.astype(np.uint8) 36 | return image 37 | 38 | def process(image_list_path, dst_prefix): 39 | image_path_list, label_list = read_image_list(image_list_path) 40 | with open(dst_prefix + ".bin", "wb") as f: 41 | for image_path in image_path_list: 42 | image_array = read_augment_image(image_path) 43 | image_array_cwh = image_array.transpose(0, 2, 1)#rgb, w, h 44 | image_array_cwh.tofile(f)#c-order, h-w-c viewed in f-order 45 | with open(dst_prefix + ".json", "wb") as f: 46 | json.dump(label_list, f) 47 | 48 | if __name__ == '__main__': 49 | image_list_path = sys.argv[1] 50 | dst_prefix = sys.argv[2] 51 | process(image_list_path, dst_prefix) 52 | 53 | -------------------------------------------------------------------------------- /util/convert_mnist.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | """ 5 | MNIST dataset to training file format 6 | """ 7 | 8 | import sys 9 | import os 10 | import json 11 | import argparse 12 | import numpy as np 13 | 14 | def load_images(path): 15 | with open(path, "rb") as f: 16 | d = f.read() 17 | images = np.fromstring(d[16:], dtype=np.uint8) 18 | images = images.reshape(-1, 28, 28)#sample, h, w 19 | return images 20 | 21 | def load_labels(path): 22 | with open(path, "rb") as f: 23 | d = f.read() 24 | labels = np.fromstring(d[8:], dtype=np.uint8) 25 | return labels 26 | 27 | def save_images(path, images): 28 | # convert to (h, w, sample) in fortran-order = (sample, w, h) in c-order 29 | images = np.transpose(images, (0, 2, 1)) 30 | images.tofile(path) 31 | 32 | def save_labels(path, labels): 33 | ary = map(int, labels) 34 | with open(path, "wt") as f: 35 | json.dump(ary, f) 36 | 37 | 38 | if __name__ == '__main__': 39 | parser = argparse.ArgumentParser() 40 | parser.add_argument("src") 41 | parser.add_argument("dst") 42 | parser.add_argument("--invert", action="store_true") 43 | args = parser.parse_args() 44 | src_dir = args.src 45 | dst_dir = args.dst 46 | if not os.path.exists(dst_dir): 47 | os.mkdir(dst_dir) 48 | for settype, srcprefix in [("train", "train"), ("test", "t10k")]: 49 | images = load_images(os.path.join(src_dir, srcprefix + "-images-idx3-ubyte")) 50 | labels = load_labels(os.path.join(src_dir, srcprefix + "-labels-idx1-ubyte")) 51 | if args.invert: 52 | images = 255 - images 53 | save_images(os.path.join(dst_dir, "mnist_" + settype + "_8bit.bin"), images) 54 | save_labels(os.path.join(dst_dir, "mnist_" + settype + "_8bit.json"), labels) 55 | -------------------------------------------------------------------------------- /util/convert_weight.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | """ 5 | Learned weight converter (sukiyaki <=> chainer) 6 | """ 7 | 8 | import sys 9 | import os 10 | import json 11 | import argparse 12 | import re 13 | import numpy as np 14 | 15 | def sukiyaki_unpack(binary): 16 | """ 17 | load key-flatarray pairs 18 | """ 19 | eoh = binary.find('\0') 20 | header_str = binary[:eoh] 21 | header = json.loads(header_str) 22 | pairs = {} 23 | for key, pos in header.items(): 24 | pairs[key] = np.fromstring(binary[pos["offset"]:pos["offset"]+pos["size"]], dtype=np.float32) 25 | return pairs 26 | 27 | def sukiyaki_pack(pairs): 28 | """ 29 | key-flatarray pairs to serialized byte string 30 | """ 31 | header_size = 65536 32 | while True: 33 | header = {} 34 | offset = header_size 35 | elements = [] 36 | for key, ary in pairs.items(): 37 | assert ary.dtype == np.float32 38 | ary_size = ary.size * 4 39 | header[key] = {"offset":offset, "size":ary_size} 40 | elements.append(ary.tobytes(order="C")) 41 | offset += ary_size 42 | header_str = json.dumps(header) 43 | if len(header_str) < header_size: 44 | break 45 | header_size *= 2 46 | nullstr = "\0" * (header_size - len(header_str)) 47 | elements.insert(0, nullstr) 48 | elements.insert(0, header_str) 49 | return "".join(elements) 50 | 51 | def key_chainer2sukiyaki(array_key): 52 | """ 53 | "conv1/W" to "conv1/weight" 54 | "conv1/b" to "conv1/bias" 55 | """ 56 | m = re.match("([0-9A-Za-z_]+)/(W|b)", array_key) 57 | if m is None: 58 | raise ValueError("Unexpected array_key " + array_key) 59 | weight_name = {"W":"weight", "b":"bias"} 60 | sukiyaki_key = "{}/{}".format(m.group(1), weight_name[m.group(2)]) 61 | return sukiyaki_key 62 | 63 | def key_sukiyaki2chainer(array_key): 64 | """ 65 | "conv1/weight" to "conv1/W" 66 | "conv1/bias" to "conv1/b" 67 | """ 68 | m = re.match("([0-9A-Za-z_]+)/(weight|bias)", array_key) 69 | if m is None: 70 | raise ValueError("Unexpected array_key " + array_key) 71 | weight_name = {"weight":"W", "bias":"b"} 72 | chainer_key = "{}/{}".format(m.group(1), weight_name[m.group(2)]) 73 | return chainer_key 74 | 75 | def weight_chainer2sukiyaki(ary): 76 | """ 77 | if ary.ndim == 4, convert out,in,h,w to out,in,w,h 78 | otherwise, do nothing 79 | """ 80 | if ary.ndim == 4: 81 | ary = np.transpose(ary, (0, 1, 3, 2)) 82 | return ary 83 | 84 | def weight_chainer2sukiyaki_vgg_fc6(ary): 85 | """ 86 | special handling for conv-fc connection; out,in_ch,h,w to out,in_ch,w,h 87 | """ 88 | ary = ary.reshape((ary.shape[0], 512, 7, 7)) 89 | ary = np.transpose(ary, (0, 1, 3, 2)) 90 | return ary 91 | 92 | def weight_sukiyaki2chainer(ary, chainer_shape): 93 | """ 94 | reshape flat array to specified shape in chainer 95 | if ary.ndim == 4, convert out,in,w,h to out,in,h,w 96 | otherwise, do nothing 97 | """ 98 | if ary.ndim == 4: 99 | ary = ary.reshape((chainer_shape[0], chainer_shape[1], chainer_shape[3], chainer_shape[2])) 100 | ary = np.transpose(ary, (0, 1, 3, 2)) 101 | else: 102 | ary = ary.reshape(chainer_shape) 103 | return ary 104 | 105 | def chainer2sukiyaki(in_path, out_path): 106 | c_model = np.load(in_path) 107 | keys = c_model.keys() 108 | pairs = {} 109 | for c_key in keys: 110 | c_weight = c_model[c_key] 111 | if c_key == "fc6/W": 112 | print("special handling of vgg fc6") 113 | s_weight = weight_chainer2sukiyaki_vgg_fc6(c_weight) 114 | else: 115 | s_weight = weight_chainer2sukiyaki(c_weight) 116 | s_key = key_chainer2sukiyaki(c_key) 117 | pairs[s_key] = s_weight 118 | del c_model 119 | s_data = sukiyaki_pack(pairs) 120 | with open(out_path, "wb") as f: 121 | f.write(s_data) 122 | 123 | def sukiyaki2chainer(in_path, out_path, tmpl_path): 124 | with open(in_path, "rb") as f: 125 | s_pairs = sukiyaki_unpack(f.read()) 126 | tmpl_model = np.load(tmpl_path) 127 | c_shapes = {} 128 | for c_key in tmpl_model.keys(): 129 | c_shapes[c_key] = tmpl_model[c_key].shape 130 | del tmpl_model 131 | 132 | pairs = {} 133 | for s_key, s_ary in s_pairs.items(): 134 | c_key = key_sukiyaki2chainer(s_key) 135 | if c_key not in c_shapes: 136 | raise ValueError("key {} not found in template, so cannot determine shape".format(c_key)) 137 | c_ary = weight_sukiyaki2chainer(s_ary, c_shapes[c_key]) 138 | pairs[c_key] = c_ary 139 | del s_pairs 140 | np.savez(out_path, **pairs) 141 | 142 | if __name__ == '__main__': 143 | parser = argparse.ArgumentParser() 144 | parser.add_argument("direction", help="c2s: chainer to sukiyaki, s2c: sukiyaki to chainer") 145 | parser.add_argument("src") 146 | parser.add_argument("dst") 147 | parser.add_argument("--tmpl", "-t", help="template chainer model") 148 | args = parser.parse_args() 149 | if args.direction == "c2s": 150 | chainer2sukiyaki(args.src, args.dst) 151 | elif args.direction == "s2c": 152 | sukiyaki2chainer(args.src, args.dst, args.tmpl) 153 | 154 | 155 | --------------------------------------------------------------------------------