Unverified Commit 0be20741 authored by mikebitsoko's avatar mikebitsoko Committed by GitHub

Deeplearnjs model builder

use case: make sure deeplearnjs is installed in your system
Installation:
$ git clone https://github.com/PAIR-code/deeplearnjs.git
$ cd deeplearnjs
$ yarn prep # Installs dependencies.

After installation, replace model-builder folder with this
Contact me for assistance.
parent 392041e4
[{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":8},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":16},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":4}]
[{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":4},{"layerName":"ReLU"},{"layerName":"Fully connected","hiddenUnits":4},{"layerName":"ReLU"},{"layerName":"Fully connected","hiddenUnits":4}]
This diff is collapsed.
This diff is collapsed.
[{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":16},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":20},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":20},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":10}]
\ No newline at end of file
<!-- Copyright 2017 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="../node_modules/@bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="../demo-header.html">
<link rel="import" href="../demo-footer.html">
<link rel="import" href="model-builder.html">
<link rel="import" href="../node_modules/@bower_components/iron-icons/image-icons.html">
<link rel="import" href="../node_modules/@bower_components/iron-icons/iron-icons.html">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.css" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js"></script>
<script src="../homepage/assets/support.js"></script>
<title>Bitsoko Model Builder</title>
<style>
html {
width: 100%;
height: 100%;
}
body {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
margin: 0;
width: 100%;
height: 100%;
}
head {
height: 0;
width: 0;
}
</style>
</head>
<body>
<demo-header name="model builder"></demo-header>
<model-builder></model-builder>
<demo-footer></demo-footer>
</body>
</html>
["asterisk", "\u16a0", "\u16a1", "\u16a2", "\u16a3", "\u16a4", "\u16a5", "\u16a6", "\u16a7", "\u16a8", "\u16a9", "\u16aa", "\u16ab", "\u16ac", "\u16ad", "\u16ae", "\u16af", "\u16b0", "\u16b1", "\u16b2", "\u16b3", "\u16b4", "\u16b5", "\u16b6", "\u16b7", "\u16b8", "\u16b9", "\u16ba", "\u16bb", "\u16bc", "\u16bd", "\u16be", "\u16bf", "\u16c0", "\u16c1", "\u16c2", "\u16c3", "\u16c4", "\u16c5", "\u16c6", "\u16c7", "\u16c8", "\u16c9", "\u16ca", "\u16cb", "\u16cc", "\u16cd", "\u16ce", "\u16cf", "\u16d0", "\u16d1", "\u16d2", "\u16d3", "\u16d4", "\u16d5", "\u16d6", "\u16d7", "\u16d8", "\u16d9", "\u16da", "\u16db", "\u16dc", "\u16dd", "\u16de", "\u16df", "\u16e0", "\u16e1", "\u16e2", "\u16e3", "\u16e4", "\u16e5", "\u16e6", "\u16e7", "\u16e8", "\u16e9", "\u16ea", "\u16eb", "\u16ec", "\u16ed", "\u16ee", "\u16ef", "\u16f0", "\u16f1", "\u16f2", "\u16f3", "\u16f4", "\u16f5", "\u16f6", "\u16f7", "\u16f8"]
\ No newline at end of file
This diff is collapsed.
[{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":8},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":16},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":10}]
[{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":128},{"layerName":"ReLU"},{"layerName":"Fully connected","hiddenUnits":32},{"layerName":"ReLU"},{"layerName":"Fully connected","hiddenUnits":10}]
{
"Bitsoko": {
"data": [{
"name": "images",
"path": "bitsoko_images.png",
"dataType": "png",
"shape": [64, 64, 3]
}, {
"name": "labels",
"path": "bitsoko_labels",
"dataType": "uint8",
"shape": [4]
}],
"labelClassNames": ["banana", "cabbage", "tomato", "watermelon"],
"modelConfigs": {
"Fully connected": {
"path": "bitsoko-fully-connected.json"
},
"Convolutional": {
"path": "bitsoko-conv.json"
}
}
},
"MNIST": {
"data": [{
"name": "images",
"path": "https://storage.googleapis.com/learnjs-data/model-builder/mnist_images.png",
"dataType": "png",
"shape": [28, 28, 1]
}, {
"name": "labels",
"path": "https://storage.googleapis.com/learnjs-data/model-builder/mnist_labels_uint8",
"dataType": "uint8",
"shape": [10]
}],
"modelConfigs": {
"Fully connected": {
"path": "mnist-fully-connected.json"
},
"Convolutional": {
"path": "mnist-conv.json"
}
}
},
"Fashion MNIST": {
"data": [{
"name": "images",
"path": "https://storage.googleapis.com/learnjs-data/model-builder/fashion_mnist_images.png",
"dataType": "png",
"shape": [28, 28, 1]
}, {
"name": "labels",
"path": "https://storage.googleapis.com/learnjs-data/model-builder/fashion_mnist_labels_uint8",
"dataType": "uint8",
"shape": [10]
}],
"labelClassNames": ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"],
"modelConfigs": {
"Fully connected": {
"path": "mnist-fully-connected.json"
},
"Convolutional": {
"path": "mnist-conv.json"
}
}
},
"CIFAR 10": {
"data": [{
"name": "images",
"path": "https://storage.googleapis.com/learnjs-data/model-builder/cifar10_images.png",
"dataType": "png",
"shape": [32, 32, 3]
}, {
"name": "labels",
"path": "https://storage.googleapis.com/learnjs-data/model-builder/cifar10_labels_uint8",
"dataType": "uint8",
"shape": [10]
}],
"labelClassNames": ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"],
"modelConfigs": {
"Convolutional": {
"path": "cifar10-conv.json"
}
}
},
"Runes": {
"data": [{
"name": "images",
"path": "rune_images.png",
"dataType": "png",
"shape": [32, 32, 1]
}, {
"name": "labels",
"path": "rune_labels",
"dataType": "uint8",
"shape": [90]
}],
"modelConfigs": {
"Fully connected": {
"path": "runes-fully-connected.json"
},
"Convolutional": {
"path": "runes-conv.json"
}
}
}
}
This diff is collapsed.
This diff is collapsed.
<!-- Copyright 2017 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================-->
<link rel="import" href="../node_modules/@bower_components/polymer/polymer.html">
<link rel="import" href="../node_modules/@bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../node_modules/@bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../node_modules/@bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../node_modules/@bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../node_modules/@bower_components/paper-item/paper-item.html">
<style>
#model-layer-container {
display: flex;
}
#layer-container {
border: 1px solid #ccc;
border-radius: 7px;
display: table-cell;
padding: 10px;
text-align: center;
width: 337px;
}
#layer-container > div {
padding: 0 12px;
}
#error-container {
background-color: #fbb;
text-align: left;
padding: 5px;
}
.param-container {
margin: 0 auto;
}
.param-input {
display: inline-block;
margin-left: 10px;
}
.error-message {
padding: 12px;
}
#input-shape, #output-shape {
text-align: left;
font-size: 12px;
}
#layer-top-bar, #layer-bottom-bar {
position: relative;
}
#layer-top-bar {
margin-bottom: 24px;
}
#layer-bottom-bar {
margin-top: 24px;
}
#remove-layer, #input-shape {
position: absolute;
}
#remove-layer {
font-size: 12px;
right: -6px;
top: -6px;
}
#input-shape {
top: 4px;
left: 4px;
}
#output-shape {
position: absolute;
bottom: 4px;
left: 4px;
}
paper-icon-button {
border-radius: 50%;
}
paper-icon-button[active] {
color: white;
background-color: #880E4F;
}
</style>
<dom-module id="model-layer">
<template>
<div id="model-layer-container">
<div id="layer-container">
<div id="layer-top-bar">
<div id="input-shape">[[inputShapeDisplay]]</div>
<div id="remove-layer" hidden$="[[isStatic]]">
<paper-icon-button icon="clear"></paper-icon-button>
</div>
</div>
<div hidden$="[[!isStatic]]">
<div id="layer-name">[[layerName]]</div>
</div>
<div hidden$="[[isStatic]]">
<paper-dropdown-menu no-animations label="Op type">
<paper-listbox attr-for-selected="value" class="dropdown-content" selected="{{selectedLayerName}}" slot="dropdown-content">
<template is="dom-repeat" items="[[layerNames]]">
<paper-item value="[[item]]" label="[[item]]">
[[item]]
</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
<div class="param-container"></div>
</div>
<div id="error-container" hidden$="[[!hasError]]">
<ul>
<template is="dom-repeat" items="[[errorMessages]]">
<li class="error-message">[[item]]</li>
</template>
</ul>
</div>
<div id="layer-bottom-bar">
<div id="output-shape">[[outputShapeDisplay]]</div>
</div>
</div>
</div>
</template>
</dom-module>
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
import {Graph, Tensor} from 'deeplearn';
import {PolymerElement, PolymerHTMLElement} from '../polymer-spec';
import * as layer_builder from './layer_builder';
import {LayerBuilder, LayerName, LayerWeightsDict} from './layer_builder';
import {ModelBuilder} from './model-builder';
import * as model_builder_util from './model_builder_util';
// tslint:disable-next-line:variable-name
export let ModelLayerPolymer: new () => PolymerHTMLElement = PolymerElement({
is: 'model-layer',
properties: {
layerName: String,
inputShapeDisplay: String,
outputShapeDisplay: String,
isStatic: {type: Boolean, value: false},
layerNames: Array,
selectedLayerName: String,
hasError: {type: Boolean, value: false},
errorMessages: Array,
}
});
export class ModelLayer extends ModelLayerPolymer {
// Polymer properties.
inputShapeDisplay: string;
outputShapeDisplay: string;
layerNames: LayerName[];
selectedLayerName: LayerName;
hasError: boolean;
errorMessages: string[];
private modelBuilder: ModelBuilder;
layerBuilder: LayerBuilder;
private inputShape: number[];
private outputShape: number[];
private paramContainer: HTMLDivElement;
initialize(modelBuilder: ModelBuilder, inputShape: number[]) {
this.modelBuilder = modelBuilder;
this.paramContainer =
this.querySelector('.param-container') as HTMLDivElement;
this.layerNames = [
'Fully connected', 'ReLU', 'Convolution', 'Max pool', 'Reshape', 'Flatten'
];
this.inputShape = inputShape;
this.buildParamsUI('Fully connected', this.inputShape);
this.querySelector('.dropdown-content')
.addEventListener(
// tslint:disable-next-line:no-any
'iron-activate', (event: any) => {
this.buildParamsUI(
event.detail.selected as LayerName, this.inputShape);
});
this.querySelector('#remove-layer').addEventListener('click', (event) => {
modelBuilder.removeLayer(this);
});
}
setInputShape(shape: number[]): number[] {
this.inputShape = shape;
this.inputShapeDisplay =
model_builder_util.getDisplayShape(this.inputShape);
const errors: string[] = [];
const validationErrors = this.layerBuilder.validate(this.inputShape);
if (validationErrors != null) {
for (let i = 0; i < validationErrors.length; i++) {
errors.push('Error: ' + validationErrors[i]);
}
}
try {
this.outputShape = this.layerBuilder.getOutputShape(this.inputShape);
} catch (e) {
errors.push(e);
}
this.outputShapeDisplay =
model_builder_util.getDisplayShape(this.outputShape);
if (errors.length > 0) {
this.hasError = true;
this.errorMessages = errors;
} else {
this.hasError = false;
this.errorMessages = [];
}
return this.outputShape;
}
isValid(): boolean {
return !this.hasError;
}
getOutputShape(): number[] {
return this.outputShape;
}
addLayer(
g: Graph, network: Tensor, index: number,
weights: LayerWeightsDict|null): Tensor {
return this.layerBuilder.addLayer(
g, network, this.inputShape, index, weights);
}
/**
* Build parameters for the UI for a given op type. This is called when the
* op is added, and when the op type changes.
*/
buildParamsUI(
layerName: LayerName, inputShape: number[],
layerBuilderJson?: LayerBuilder) {
this.selectedLayerName = layerName;
this.layerBuilder =
layer_builder.getLayerBuilder(layerName, layerBuilderJson);
// Clear any existing parameters.
this.paramContainer.innerHTML = '';
// Add all the parameters to the UI.
const layerParams = this.layerBuilder.getLayerParams();
for (let i = 0; i < layerParams.length; i++) {
const initialValue = layerBuilderJson != null ?
layerParams[i].getValue() :
layerParams[i].initialValue(inputShape);
this.addParamField(
layerParams[i].label, initialValue, layerParams[i].setValue,
layerParams[i].type, layerParams[i].min, layerParams[i].max);
}
this.modelBuilder.layerParamChanged();
}
loadParamsFromLayerBuilder(
inputShape: number[], layerBuilderJson: LayerBuilder) {
this.buildParamsUI(
layerBuilderJson.layerName, inputShape, layerBuilderJson);
}
private addParamField(
label: string, initialValue: number|string,
setValue: (value: number|string) => void, type: 'number'|'text',
min?: number, max?: number) {
const input = document.createElement('paper-input');
input.setAttribute('always-float-label', 'true');
input.setAttribute('label', label);
input.setAttribute('value', initialValue.toString());
input.setAttribute('type', type);
if (type === 'number') {
input.setAttribute('min', min.toString());
input.setAttribute('max', max.toString());
}
input.className = 'param-input';
this.paramContainer.appendChild(input);
// Update the parent when this changes.
input.addEventListener('input', (event) => {
if (type === 'number') {
// tslint:disable-next-line:no-any
setValue((event.target as any).valueAsNumber as number);
} else {
// tslint:disable-next-line:no-any
setValue((event.target as any).value as string);
}
this.modelBuilder.layerParamChanged();
});
setValue(initialValue);
}
}
document.registerElement(ModelLayer.prototype.is, ModelLayer);
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
export function getDisplayShape(shape: number[]) {
return `[${shape}]`;
}
[{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":8},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Convolution","fieldSize":5,"stride":1,"zeroPad":2,"outputDepth":16},{"layerName":"ReLU"},{"layerName":"Max pool","fieldSize":2,"stride":2,"zeroPad":0},{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":90}]
[{"layerName":"Flatten"},{"layerName":"Fully connected","hiddenUnits":90},{"layerName":"ReLU"},{"layerName":"Fully connected","hiddenUnits":90},{"layerName":"ReLU"},{"layerName":"Fully connected","hiddenUnits":90}]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment