From f4aec291c5ad0637f6d8f593b3bae3c20c87c378 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Fri, 22 Dec 2017 12:30:40 -0500 Subject: [PATCH 1/9] save --- demos/adder/adder.ts | 4 +- .../batchnormalization3d_benchmark.ts | 8 +- demos/benchmarks/benchmark_util.ts | 35 +- demos/benchmarks/benchmarks.ts | 58 +- demos/benchmarks/conv_benchmarks.ts | 4 +- demos/benchmarks/matmul_benchmarks.ts | 10 +- demos/benchmarks/pool_benchmarks.ts | 12 +- demos/benchmarks/reduction_ops_benchmark.ts | 8 +- demos/benchmarks/unary_ops_benchmark.ts | 9 +- .../complementary-color-prediction.ts | 64 +-- .../fast-style-transfer.ts | 43 +- demos/fast-style-transfer/net.ts | 6 +- demos/imagenet/imagenet.ts | 24 +- demos/intro/intro.ts | 188 ++++--- demos/latent-space-explorer/App.vue | 3 +- .../components/BasisDimensions.vue | 26 +- .../latent-space-explorer/components/Tray.vue | 4 +- .../latent-space-explorer/utils/FontModel.ts | 31 +- demos/latent-space-explorer/utils/Utils.ts | 10 +- demos/mnist/mnist.ts | 15 +- demos/model-builder/model-builder.ts | 13 +- demos/ndarray-logits-visualizer.ts | 32 +- demos/nn-art/cppn.ts | 48 +- demos/package.json | 2 +- demos/performance_rnn/performance_rnn.ts | 103 ++-- demos/util.ts | 10 +- demos/yarn.lock | 508 ++++++++++++------ 27 files changed, 704 insertions(+), 574 deletions(-) diff --git a/demos/adder/adder.ts b/demos/adder/adder.ts index 55ee2cd9d9..36dc9e58ef 100644 --- a/demos/adder/adder.ts +++ b/demos/adder/adder.ts @@ -15,13 +15,13 @@ * ============================================================================= */ -import {NDArrayMathGPU, Scalar} from 'deeplearn'; +import {ENV, Scalar} from 'deeplearn'; const outputElement = document.getElementById('output'); const inA: HTMLInputElement = document.getElementById('A') as HTMLInputElement; const inB: HTMLInputElement = document.getElementById('B') as HTMLInputElement; -const math = new NDArrayMathGPU(); +const math = ENV.math; export async function execute(event?: Event) { const a = Scalar.new(+inA.value); diff --git a/demos/benchmarks/batchnormalization3d_benchmark.ts b/demos/benchmarks/batchnormalization3d_benchmark.ts index eb6fd1db62..453131a54a 100644 --- a/demos/benchmarks/batchnormalization3d_benchmark.ts +++ b/demos/benchmarks/batchnormalization3d_benchmark.ts @@ -15,7 +15,7 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array1D, Array3D, NDArrayMathCPU, NDArrayMathGPU} from 'deeplearn'; +import {Array1D, Array3D, ENV, NDArrayMath} from 'deeplearn'; import {BenchmarkTest, LAST_RUN_CPU_CUTOFF_MS} from './benchmark'; import * as benchmark_util from './benchmark_util'; @@ -29,7 +29,8 @@ export class BatchNormalization3DCPUBenchmark implements BenchmarkTest { resolve(-1); }); } - const math = new NDArrayMathCPU(); + const math = new NDArrayMath('cpu', false); + ENV.setMath(math); const x = Array3D.randUniform([size, size, 8], -1, 1); const mean = Array1D.new([0]); const variance = Array1D.new([1]); @@ -48,7 +49,8 @@ export class BatchNormalization3DCPUBenchmark implements BenchmarkTest { export class BatchNormalization3DGPUBenchmark implements BenchmarkTest { async run(size: number) { - const math = new NDArrayMathGPU(); + const math = new NDArrayMath('webgl', false); + ENV.setMath(math); const x = Array3D.randUniform([size, size, 8], -1, 1); const mean = Array1D.new([0]); const variance = Array1D.new([1]); diff --git a/demos/benchmarks/benchmark_util.ts b/demos/benchmarks/benchmark_util.ts index 08c31d3f79..0db349ef11 100644 --- a/demos/benchmarks/benchmark_util.ts +++ b/demos/benchmarks/benchmark_util.ts @@ -1,35 +1,12 @@ -import {ENV, NDArray, NDArrayMathGPU} from 'deeplearn'; +import {NDArray, NDArrayMath} from 'deeplearn'; export async function warmupAndBenchmarkGPU( - math: NDArrayMathGPU, benchmark: () => NDArray): Promise { - const gpgpu = math.getGPGPUContext(); - - let out: NDArray; - const saveOutputBenchmark = () => { - out = benchmark(); - }; - + math: NDArrayMath, benchmark: () => NDArray): Promise { // Warmup. - if (ENV.get('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED')) { - await gpgpu.runQuery(saveOutputBenchmark); - } else { - saveOutputBenchmark(); - out.dataSync(); - } - out.dispose(); - - let totalTime: number; - if (ENV.get('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE')) { - totalTime = await gpgpu.runQuery(saveOutputBenchmark); - } else { - const start = performance.now(); - - saveOutputBenchmark(); - out.dataSync(); - - totalTime = performance.now() - start; - } + const out = benchmark(); + await out.data(); out.dispose(); - return totalTime; + // Real timing. + return math.time(benchmark); } diff --git a/demos/benchmarks/benchmarks.ts b/demos/benchmarks/benchmarks.ts index 70fe4abb2f..529ec15dc4 100644 --- a/demos/benchmarks/benchmarks.ts +++ b/demos/benchmarks/benchmarks.ts @@ -179,7 +179,7 @@ export class MathBenchmark extends MathBenchmarkPolymer { return runNumberRowElement; } - private runBenchmarkSteps( + private async runBenchmarkSteps( chart: Chart, runGroup: BenchmarkRunGroup, benchmarkRunGroupIndex: number, step: number) { const runNumbersTable = @@ -207,7 +207,6 @@ export class MathBenchmark extends MathBenchmarkPolymer { const runNumberRowElement = document.createElement('div'); runNumberRowElement.className = 'run-numbers-row math-benchmark'; - const runPromises: Array> = []; const rowValues: string[] = [step.toString()]; for (let i = 0; i < runGroup.benchmarkRuns.length; i++) { const run = runGroup.benchmarkRuns[i]; @@ -218,48 +217,23 @@ export class MathBenchmark extends MathBenchmarkPolymer { step; const opType = runGroup.selectedOption; - runPromises.push(test.run(size, opType, runGroup.params[opType])); - } - - Promise.all(runPromises).then(results => { - for (let i = 0; i < runGroup.benchmarkRuns.length; i++) { - const benchmarkRun = runGroup.benchmarkRuns[i]; - - const size = runGroup.stepToSizeTransformation != null ? - runGroup.stepToSizeTransformation(step) : - step; - - let resultString: string; - let logString: string; - let time = 0; - let success = true; - try { - time = results[i]; - resultString = time.toFixed(3) + 'ms'; - logString = resultString; - } catch (e) { - success = false; - resultString = 'Error'; - logString = e.message; - } + const time = await test.run(size, opType, runGroup.params[opType]); + const resultString = time.toFixed(3) + 'ms'; - if (time >= 0) { - if (success) { - benchmarkRun.chartData.push({x: step, y: time}); - } - rowValues.push(resultString); - } - console.log(`${benchmarkRun.name}[${size}]: ${logString}`); + if (time >= 0) { + run.chartData.push({x: step, y: time}); + rowValues.push(resultString); } - runNumbersTable.appendChild(this.buildRunNumbersRow(rowValues)); - - step += runGroup.stepSize; - // Allow the UI to update. - setTimeout( - () => this.runBenchmarkSteps( - chart, runGroup, benchmarkRunGroupIndex, step), - 100); - }); + console.log(`${run.name}[${size}]: ${resultString}`); + } + runNumbersTable.appendChild(this.buildRunNumbersRow(rowValues)); + + step += runGroup.stepSize; + // Allow the UI to update. + setTimeout( + () => this.runBenchmarkSteps( + chart, runGroup, benchmarkRunGroupIndex, step), + 100); } } document.registerElement(MathBenchmark.prototype.is, MathBenchmark); diff --git a/demos/benchmarks/conv_benchmarks.ts b/demos/benchmarks/conv_benchmarks.ts index e9c2d6124c..4b7d33d936 100644 --- a/demos/benchmarks/conv_benchmarks.ts +++ b/demos/benchmarks/conv_benchmarks.ts @@ -16,7 +16,7 @@ */ // tslint:disable-next-line:max-line-length -import {Array1D, Array3D, Array4D, conv_util, NDArray, NDArrayMathGPU} from 'deeplearn'; +import {Array1D, Array3D, Array4D, conv_util, ENV, NDArray} from 'deeplearn'; import {BenchmarkTest} from './benchmark'; import * as benchmark_util from './benchmark_util'; @@ -34,7 +34,7 @@ export interface DepthwiseConvParams extends ConvParams { channelMul: number; } export class ConvGPUBenchmark implements BenchmarkTest { async run(size: number, opType: string, params: ConvParams): Promise { - const math = new NDArrayMathGPU(); + const math = ENV.math; const inDepth = params.inDepth; const inShape: [number, number, number] = [size, size, inDepth]; diff --git a/demos/benchmarks/matmul_benchmarks.ts b/demos/benchmarks/matmul_benchmarks.ts index e22e1ad818..d7eb4a4b7a 100644 --- a/demos/benchmarks/matmul_benchmarks.ts +++ b/demos/benchmarks/matmul_benchmarks.ts @@ -15,7 +15,8 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array2D, NDArrayMathCPU, NDArrayMathGPU} from 'deeplearn'; +import {Array2D, ENV, NDArrayMath} from 'deeplearn'; + import {BenchmarkTest, LAST_RUN_CPU_CUTOFF_MS} from './benchmark'; import * as benchmark_util from './benchmark_util'; @@ -27,7 +28,8 @@ export class MatmulCPUBenchmark implements BenchmarkTest { resolve(-1); }); } - const math = new NDArrayMathCPU(); + const math = new NDArrayMath('cpu', false); + ENV.setMath(math); const a = Array2D.randUniform([size, size], -1, 1); const b = Array2D.randUniform([size, size], -1, 1); const start = performance.now(); @@ -41,8 +43,8 @@ export class MatmulCPUBenchmark implements BenchmarkTest { export class MatmulGPUBenchmark implements BenchmarkTest { async run(size: number): Promise { - const math = new NDArrayMathGPU(); - + const math = new NDArrayMath('webgl', false); + ENV.setMath(math); const a = Array2D.randNormal([size, size]); const b = Array2D.randNormal([size, size]); diff --git a/demos/benchmarks/pool_benchmarks.ts b/demos/benchmarks/pool_benchmarks.ts index de1b52836f..e7bfe6afe9 100644 --- a/demos/benchmarks/pool_benchmarks.ts +++ b/demos/benchmarks/pool_benchmarks.ts @@ -16,7 +16,7 @@ */ // tslint:disable-next-line:max-line-length -import {Array3D, conv_util, NDArrayMath, NDArrayMathCPU, NDArrayMathGPU} from 'deeplearn'; +import {Array3D, conv_util, ENV, NDArrayMath} from 'deeplearn'; import {BenchmarkTest} from './benchmark'; import * as benchmark_util from './benchmark_util'; @@ -58,7 +58,8 @@ function getPoolingOp(option: string, math: NDArrayMath): ( export class PoolCPUBenchmark implements BenchmarkTest { run(size: number, option: string, params: PoolBenchmarkParams): Promise { - const math = new NDArrayMathCPU(); + const math = new NDArrayMath('cpu', false); + ENV.setMath(math); const outputDepth = params.depth; const xShape: [number, number, number] = [size, size, outputDepth]; const fieldSize = params.fieldSize; @@ -83,8 +84,8 @@ export class PoolCPUBenchmark implements BenchmarkTest { export class PoolGPUBenchmark implements BenchmarkTest { async run(size: number, option: string, params: PoolBenchmarkParams): Promise { - const math = new NDArrayMathGPU(); - + const math = new NDArrayMath('webgl', false); + ENV.setMath(math); const outputDepth = params.depth; const xShape: [number, number, number] = [size, size, outputDepth]; const fieldSize = params.fieldSize; @@ -93,11 +94,8 @@ export class PoolGPUBenchmark implements BenchmarkTest { const op = getPoolingOp(option, math); const benchmark = () => op(x, fieldSize, stride, 'same'); - const time = await benchmark_util.warmupAndBenchmarkGPU(math, benchmark); - x.dispose(); - math.dispose(); return time; } diff --git a/demos/benchmarks/reduction_ops_benchmark.ts b/demos/benchmarks/reduction_ops_benchmark.ts index 0844bf17b8..d98d937788 100644 --- a/demos/benchmarks/reduction_ops_benchmark.ts +++ b/demos/benchmarks/reduction_ops_benchmark.ts @@ -15,7 +15,7 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array2D, NDArray, NDArrayMath, NDArrayMathCPU, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array2D, ENV, NDArray, NDArrayMath, Scalar} from 'deeplearn'; import {BenchmarkTest} from './benchmark'; import * as benchmark_util from './benchmark_util'; @@ -42,7 +42,8 @@ function getReductionOp(option: string, math: NDArrayMath): (input: NDArray) => export class ReductionOpsCPUBenchmark implements BenchmarkTest { async run(size: number, option: string): Promise { - const math = new NDArrayMathCPU(); + const math = new NDArrayMath('cpu', false); + ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getReductionOp(option, math); const start = performance.now(); @@ -58,7 +59,8 @@ export class ReductionOpsCPUBenchmark implements BenchmarkTest { export class ReductionOpsGPUBenchmark implements BenchmarkTest { async run(size: number, option: string) { - const math = new NDArrayMathGPU(); + const math = new NDArrayMath('webgl', false); + ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getReductionOp(option, math); diff --git a/demos/benchmarks/unary_ops_benchmark.ts b/demos/benchmarks/unary_ops_benchmark.ts index c92070e2da..d0a89c72d3 100644 --- a/demos/benchmarks/unary_ops_benchmark.ts +++ b/demos/benchmarks/unary_ops_benchmark.ts @@ -16,7 +16,8 @@ */ // tslint:disable-next-line:max-line-length -import {Array2D, NDArray, NDArrayMath, NDArrayMathCPU, NDArrayMathGPU} from 'deeplearn'; +import {Array2D, ENV, NDArray, NDArrayMath} from 'deeplearn'; + import {BenchmarkTest} from './benchmark'; import * as benchmark_util from './benchmark_util'; @@ -61,7 +62,8 @@ function getUnaryOp(option: string, math: NDArrayMath) { export class UnaryOpsCPUBenchmark implements BenchmarkTest { async run(size: number, option: string): Promise { - const math = new NDArrayMathCPU(); + const math = new NDArrayMath('cpu', false); + ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getUnaryOp(option, math); const start = performance.now(); @@ -77,7 +79,8 @@ export class UnaryOpsCPUBenchmark implements BenchmarkTest { export class UnaryOpsGPUBenchmark implements BenchmarkTest { async run(size: number, option: string) { - const math = new NDArrayMathGPU(); + const math = new NDArrayMath('webgl', false); + ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getUnaryOp(option, math); diff --git a/demos/complementary-color-prediction/complementary-color-prediction.ts b/demos/complementary-color-prediction/complementary-color-prediction.ts index e184b278dc..dd6d40cb4d 100644 --- a/demos/complementary-color-prediction/complementary-color-prediction.ts +++ b/demos/complementary-color-prediction/complementary-color-prediction.ts @@ -16,14 +16,14 @@ */ // tslint:disable-next-line:max-line-length -import {Array1D, CostReduction, FeedEntry, Graph, InCPUMemoryShuffledInputProviderBuilder, NDArrayMath, NDArrayMathGPU, Session, SGDOptimizer, Tensor} from 'deeplearn'; +import {Array1D, CostReduction, ENV, FeedEntry, Graph, InCPUMemoryShuffledInputProviderBuilder, NDArrayMath, Session, SGDOptimizer, Tensor} from 'deeplearn'; class ComplementaryColorModel { // Runs training. session: Session; // Encapsulates math operations on the CPU and GPU. - math: NDArrayMath = new NDArrayMathGPU(); + math = ENV.math; // An optimizer with a certain initial learning rate. Used for training. initialLearningRate = 0.042; @@ -155,36 +155,38 @@ class ComplementaryColorModel { * to pass data into the model. Generates `exampleCount` data points. */ private generateTrainingData(exampleCount: number) { - this.math.scope(() => { - const rawInputs = new Array(exampleCount); - for (let i = 0; i < exampleCount; i++) { - rawInputs[i] = [ - this.generateRandomChannelValue(), this.generateRandomChannelValue(), - this.generateRandomChannelValue() - ]; - } - - // Store the data within Array1Ds so that learnjs can use it. - const inputArray: Array1D[] = - rawInputs.map(c => Array1D.new(this.normalizeColor(c))); - const targetArray: Array1D[] = rawInputs.map( - c => Array1D.new( - this.normalizeColor(this.computeComplementaryColor(c)))); - - // This provider will shuffle the training data (and will do so in a way - // that does not separate the input-target relationship). - const shuffledInputProviderBuilder = - new InCPUMemoryShuffledInputProviderBuilder( - [inputArray, targetArray]); - const [inputProvider, targetProvider] = - shuffledInputProviderBuilder.getInputProviders(); - - // Maps tensors to InputProviders. - this.feedEntries = [ - {tensor: this.inputTensor, data: inputProvider}, - {tensor: this.targetTensor, data: targetProvider} + const rawInputs = new Array(exampleCount); + const oldMath = ENV.math; + const math = new NDArrayMath('cpu', false); + ENV.setMath(math); + + for (let i = 0; i < exampleCount; i++) { + rawInputs[i] = [ + this.generateRandomChannelValue(), this.generateRandomChannelValue(), + this.generateRandomChannelValue() ]; - }); + } + + // Store the data within Array1Ds so that learnjs can use it. + const inputArray: Array1D[] = + rawInputs.map(c => Array1D.new(this.normalizeColor(c))); + const targetArray: Array1D[] = rawInputs.map( + c => Array1D.new( + this.normalizeColor(this.computeComplementaryColor(c)))); + + // This provider will shuffle the training data (and will do so in a way + // that does not separate the input-target relationship). + const shuffledInputProviderBuilder = + new InCPUMemoryShuffledInputProviderBuilder([inputArray, targetArray]); + const [inputProvider, targetProvider] = + shuffledInputProviderBuilder.getInputProviders(); + + // Maps tensors to InputProviders. + this.feedEntries = [ + {tensor: this.inputTensor, data: inputProvider}, + {tensor: this.targetTensor, data: targetProvider} + ]; + ENV.setMath(oldMath); } private generateRandomChannelValue() { diff --git a/demos/fast-style-transfer/fast-style-transfer.ts b/demos/fast-style-transfer/fast-style-transfer.ts index 7212007451..7322e27638 100644 --- a/demos/fast-style-transfer/fast-style-transfer.ts +++ b/demos/fast-style-transfer/fast-style-transfer.ts @@ -14,12 +14,9 @@ * limitations under the License. * ============================================================================= */ -// tslint:disable-next-line:max-line-length -import {Array3D, gpgpu_util, GPGPUContext, NDArrayMathGPU, render_ndarray_gpu_util} from 'deeplearn'; +import {Array3D, ENV} from 'deeplearn'; import {PolymerElement, PolymerHTMLElement} from '../polymer-spec'; - -// import * as imagenet_util from '../models/imagenet_util'; import {TransformNet} from './net'; // tslint:disable-next-line:variable-name @@ -59,11 +56,6 @@ export class StyleTransferDemo extends StyleTransferDemoPolymer { status: string; applicationState: ApplicationState; - // DeeplearnJS stuff - private math: NDArrayMathGPU; - private gpgpu: GPGPUContext; - private gl: WebGLRenderingContext; - private transformNet: TransformNet; // DOM Elements @@ -88,9 +80,6 @@ export class StyleTransferDemo extends StyleTransferDemoPolymer { ready() { // Initialize deeplearn.js stuff this.canvas = this.querySelector('#imageCanvas') as HTMLCanvasElement; - this.gl = gpgpu_util.createWebGLContext(this.canvas); - this.gpgpu = new GPGPUContext(this.gl); - this.math = new NDArrayMathGPU(this.gpgpu); // Initialize polymer properties this.applicationState = ApplicationState.IDLE; @@ -113,7 +102,7 @@ export class StyleTransferDemo extends StyleTransferDemoPolymer { this.styleImgElement.height = 250; this.transformNet = - new TransformNet(this.math, STYLE_MAPPINGS[this.selectedStyleName]); + new TransformNet(STYLE_MAPPINGS[this.selectedStyleName]); this.initWebcamVariables(); @@ -250,17 +239,11 @@ export class StyleTransferDemo extends StyleTransferDemoPolymer { } async runInference() { - await this.math.scope(async (keep, track) => { - - const preprocessed = track(Array3D.fromPixels(this.contentImgElement)); - + await ENV.math.scope(async () => { + const preprocessed = Array3D.fromPixels(this.contentImgElement); const inferenceResult = await this.transformNet.predict(preprocessed); - this.setCanvasShape(inferenceResult.shape); - this.renderShader = render_ndarray_gpu_util.getRenderRGBShader( - this.gpgpu, inferenceResult.shape[1]); - render_ndarray_gpu_util.renderToCanvas( - this.gpgpu, this.renderShader, inferenceResult.getTexture()); + renderToCanvas(inferenceResult, this.canvas); }); } @@ -277,4 +260,20 @@ export class StyleTransferDemo extends StyleTransferDemoPolymer { } } +function renderToCanvas(a: Array3D, canvas: HTMLCanvasElement) { + const [height, width, ] = a.shape; + const ctx = canvas.getContext('2d'); + const imageData = new ImageData(width, height); + const data = a.dataSync(); + for (let i = 0; i < height * width; ++i) { + const j = i * 4; + const k = i * 3; + imageData.data[j + 0] = Math.round(255 * data[k + 0]); + imageData.data[j + 1] = Math.round(255 * data[k + 1]); + imageData.data[j + 2] = Math.round(255 * data[k + 2]); + imageData.data[j + 3] = 255; + } + ctx.putImageData(imageData, 0, 0); +} + document.registerElement(StyleTransferDemo.prototype.is, StyleTransferDemo); diff --git a/demos/fast-style-transfer/net.ts b/demos/fast-style-transfer/net.ts index e7e9d77059..92a7fc03b2 100644 --- a/demos/fast-style-transfer/net.ts +++ b/demos/fast-style-transfer/net.ts @@ -15,7 +15,7 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array1D, Array3D, Array4D, CheckpointLoader, Model, NDArray, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, Array3D, Array4D, CheckpointLoader, ENV, Model, NDArray, NDArrayMath, Scalar} from 'deeplearn'; const GOOGLE_CLOUD_STORAGE_DIR = 'https://storage.googleapis.com/learnjs-data/checkpoint_zoo/transformnet/'; @@ -27,8 +27,10 @@ export class TransformNet implements Model { private timesScalar: NDArray; private plusScalar: NDArray; private epsilonScalar: NDArray; + private math: NDArrayMath; - constructor(private math: NDArrayMathGPU, private style: string) { + constructor(private style: string) { + this.math = ENV.math; this.variableDictionary = {}; this.timesScalar = Scalar.new(150); this.plusScalar = Scalar.new(255. / 2); diff --git a/demos/imagenet/imagenet.ts b/demos/imagenet/imagenet.ts index c68bec0452..0e9a831c0a 100644 --- a/demos/imagenet/imagenet.ts +++ b/demos/imagenet/imagenet.ts @@ -19,7 +19,7 @@ import '../demo-header'; import '../demo-footer'; // tslint:disable-next-line:max-line-length -import {Array3D, gpgpu_util, GPGPUContext, NDArrayMathGPU} from 'deeplearn'; +import {Array3D, ENV, gpgpu_util, GPGPUContext, MathBackendWebGL, NDArrayMath} from 'deeplearn'; import {ActivationName, SqueezeNet} from 'deeplearn-squeezenet'; import {PolymerElement, PolymerHTMLElement} from '../polymer-spec'; @@ -54,8 +54,8 @@ export class ImagenetDemo extends ImagenetDemoPolymer { inputNames: string[]; selectedInputName: string; - private math: NDArrayMathGPU; - private gl: WebGLRenderingContext; + private math: NDArrayMath; + private backend: MathBackendWebGL; private gpgpu: GPGPUContext; private renderGrayscaleChannelsCollageShader: WebGLShader; @@ -101,9 +101,11 @@ export class ImagenetDemo extends ImagenetDemoPolymer { } }); - this.gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); - this.gpgpu = new GPGPUContext(this.gl); - this.math = new NDArrayMathGPU(this.gpgpu); + const gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); + this.gpgpu = new GPGPUContext(gl); + this.backend = new MathBackendWebGL(this.gpgpu); + this.math = new NDArrayMath(this.backend, false); + ENV.setMath(this.math); this.renderGrayscaleChannelsCollageShader = imagenet_util.getRenderGrayscaleChannelsCollageShader(this.gpgpu); @@ -174,14 +176,14 @@ export class ImagenetDemo extends ImagenetDemoPolymer { const isWebcam = this.selectedInputName === 'webcam'; - await this.math.scope(async (keep, track) => { + await this.math.scope(async keep => { if (!this.isMediaLoaded) { return; } const element = isWebcam ? this.webcamVideoElement : this.staticImgElement; - const image = track(Array3D.fromPixels(element)); + const image = Array3D.fromPixels(element); const inferenceResult = await this.squeezeNet.predictWithActivation( image, this.selectedLayerName); @@ -226,8 +228,10 @@ export class ImagenetDemo extends ImagenetDemoPolymer { imagenet_util.renderGrayscaleChannelsCollage( this.gpgpu, this.renderGrayscaleChannelsCollageShader, - activationNDArray.getTexture(), minValues.getTexture(), - maxValues.getTexture(), activationNDArray.getTextureShapeRC(), + this.backend.getTexture(activationNDArray.id), + this.backend.getTexture(minValues.id), + this.backend.getTexture(maxValues.id), + this.backend.getTextureData(activationNDArray.id).texShape, activationNDArray.shape[0], activationNDArray.shape[2], this.inferenceCanvas.width, numRows); }); diff --git a/demos/intro/intro.ts b/demos/intro/intro.ts index c47bd7c3a4..b4a106ab95 100644 --- a/demos/intro/intro.ts +++ b/demos/intro/intro.ts @@ -16,7 +16,7 @@ */ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, CostReduction, FeedEntry, Graph, InCPUMemoryShuffledInputProviderBuilder, NDArrayMathGPU, Scalar, Session, SGDOptimizer} from 'deeplearn'; +import {Array1D, Array2D, CostReduction, ENV, FeedEntry, Graph, InCPUMemoryShuffledInputProviderBuilder, Scalar, Session, SGDOptimizer} from 'deeplearn'; // This file parallels (some of) the code in the introduction tutorial. @@ -24,106 +24,100 @@ import {Array1D, Array2D, CostReduction, FeedEntry, Graph, InCPUMemoryShuffledIn * 'NDArrayMathGPU' section of tutorial */ async function intro() { - { - const math = new NDArrayMathGPU(); + const math = ENV.math; + + const a = Array2D.new([2, 2], [1.0, 2.0, 3.0, 4.0]); + const b = Array2D.new([2, 2], [0.0, 2.0, 4.0, 6.0]); + + // Non-blocking math calls. + const diff = math.sub(a, b); + const squaredDiff = math.elementWiseMul(diff, diff); + const sum = math.sum(squaredDiff); + const size = Scalar.new(a.size); + const average = math.divide(sum, size); + + console.log(`mean squared difference: ${await average.val()}`); + + /** + * 'Graphs and Tensors' section of tutorial + */ + + const g = new Graph(); + + // Placeholders are input containers. This is the container for where we + // will feed an input NDArray when we execute the graph. + const inputShape = [3]; + const inputTensor = g.placeholder('input', inputShape); + + const labelShape = [1]; + const labelTensor = g.placeholder('label', labelShape); + + // Variables are containers that hold a value that can be updated from + // training. + // Here we initialize the multiplier variable randomly. + const multiplier = g.variable('multiplier', Array2D.randNormal([1, 3])); + + // Top level graph methods take Tensors and return Tensors. + const outputTensor = g.matmul(multiplier, inputTensor); + const costTensor = g.meanSquaredCost(labelTensor, outputTensor); + + // Tensors, like NDArrays, have a shape attribute. + console.log(outputTensor.shape); + + /** + * 'Session and FeedEntry' section of the tutorial. + */ + + const learningRate = .00001; + const batchSize = 3; + + const session = new Session(g, math); + const optimizer = new SGDOptimizer(learningRate); + + const inputs: Array1D[] = [ + Array1D.new([1.0, 2.0, 3.0]), Array1D.new([10.0, 20.0, 30.0]), + Array1D.new([100.0, 200.0, 300.0]) + ]; + + const labels: Array1D[] = + [Array1D.new([4.0]), Array1D.new([40.0]), Array1D.new([400.0])]; + + // Shuffles inputs and labels and keeps them mutually in sync. + const shuffledInputProviderBuilder = + new InCPUMemoryShuffledInputProviderBuilder([inputs, labels]); + const [inputProvider, labelProvider] = + shuffledInputProviderBuilder.getInputProviders(); + + // Maps tensors to InputProviders. + const feedEntries: FeedEntry[] = [ + {tensor: inputTensor, data: inputProvider}, + {tensor: labelTensor, data: labelProvider} + ]; + + const NUM_BATCHES = 10; + for (let i = 0; i < NUM_BATCHES; i++) { + // Wrap session.train in a scope so the cost gets cleaned up + // automatically. + await math.scope(async () => { + // Train takes a cost tensor to minimize. Trains one batch. Returns the + // average cost as a Scalar. + const cost = session.train( + costTensor, feedEntries, batchSize, optimizer, CostReduction.MEAN); + + console.log(`last average cost (${i}): ${await cost.val()}`); + }); + } - const a = Array2D.new([2, 2], [1.0, 2.0, 3.0, 4.0]); - const b = Array2D.new([2, 2], [0.0, 2.0, 4.0, 6.0]); + const testInput = Array1D.new([0.1, 0.2, 0.3]); - // Non-blocking math calls. - const diff = math.sub(a, b); - const squaredDiff = math.elementWiseMul(diff, diff); - const sum = math.sum(squaredDiff); - const size = Scalar.new(a.size); - const average = math.divide(sum, size); + // session.eval can take NDArrays as input data. + const testFeedEntries: FeedEntry[] = [{tensor: inputTensor, data: testInput}]; - console.log(`mean squared difference: ${await average.val()}`); - } + const testOutput = session.eval(outputTensor, testFeedEntries); - { - /** - * 'Graphs and Tensors' section of tutorial - */ - - const g = new Graph(); - - // Placeholders are input containers. This is the container for where we - // will feed an input NDArray when we execute the graph. - const inputShape = [3]; - const inputTensor = g.placeholder('input', inputShape); - - const labelShape = [1]; - const labelTensor = g.placeholder('label', labelShape); - - // Variables are containers that hold a value that can be updated from - // training. - // Here we initialize the multiplier variable randomly. - const multiplier = g.variable('multiplier', Array2D.randNormal([1, 3])); - - // Top level graph methods take Tensors and return Tensors. - const outputTensor = g.matmul(multiplier, inputTensor); - const costTensor = g.meanSquaredCost(labelTensor, outputTensor); - - // Tensors, like NDArrays, have a shape attribute. - console.log(outputTensor.shape); - - /** - * 'Session and FeedEntry' section of the tutorial. - */ - - const learningRate = .00001; - const batchSize = 3; - const math = new NDArrayMathGPU(); - - const session = new Session(g, math); - const optimizer = new SGDOptimizer(learningRate); - - const inputs: Array1D[] = [ - Array1D.new([1.0, 2.0, 3.0]), Array1D.new([10.0, 20.0, 30.0]), - Array1D.new([100.0, 200.0, 300.0]) - ]; - - const labels: Array1D[] = - [Array1D.new([4.0]), Array1D.new([40.0]), Array1D.new([400.0])]; - - // Shuffles inputs and labels and keeps them mutually in sync. - const shuffledInputProviderBuilder = - new InCPUMemoryShuffledInputProviderBuilder([inputs, labels]); - const [inputProvider, labelProvider] = - shuffledInputProviderBuilder.getInputProviders(); - - // Maps tensors to InputProviders. - const feedEntries: FeedEntry[] = [ - {tensor: inputTensor, data: inputProvider}, - {tensor: labelTensor, data: labelProvider} - ]; - - const NUM_BATCHES = 10; - for (let i = 0; i < NUM_BATCHES; i++) { - // Wrap session.train in a scope so the cost gets cleaned up - // automatically. - await math.scope(async () => { - // Train takes a cost tensor to minimize. Trains one batch. Returns the - // average cost as a Scalar. - const cost = session.train( - costTensor, feedEntries, batchSize, optimizer, CostReduction.MEAN); - - console.log(`last average cost (${i}): ${await cost.val()}`); - }); - } - - const testInput = Array1D.new([0.1, 0.2, 0.3]); - - // session.eval can take NDArrays as input data. - const testFeedEntries: FeedEntry[] = - [{tensor: inputTensor, data: testInput}]; - - const testOutput = session.eval(outputTensor, testFeedEntries); - - console.log('---inference output---'); - console.log(`shape: ${testOutput.shape}`); - console.log(`value: ${await testOutput.val(0)}`); - } + console.log('---inference output---'); + console.log(`shape: ${testOutput.shape}`); + console.log(`value: ${await testOutput.val(0)}`); } intro(); diff --git a/demos/latent-space-explorer/App.vue b/demos/latent-space-explorer/App.vue index 2cd4c2bf57..6617ec681a 100644 --- a/demos/latent-space-explorer/App.vue +++ b/demos/latent-space-explorer/App.vue @@ -82,8 +82,7 @@ import BasisDimensions from './components/BasisDimensions.vue'; import FontChooser from './components/FontChooser.vue'; import Alphabet from './components/Alphabet.vue'; import {FontModel} from './utils/FontModel'; - -import {Array1D, NDArray, NDArrayMathCPU} from 'deeplearn'; +import {Array1D} from 'deeplearn'; export default { components: { diff --git a/demos/latent-space-explorer/components/BasisDimensions.vue b/demos/latent-space-explorer/components/BasisDimensions.vue index e26bfde1b5..99bd150fd5 100644 --- a/demos/latent-space-explorer/components/BasisDimensions.vue +++ b/demos/latent-space-explorer/components/BasisDimensions.vue @@ -39,14 +39,23 @@ limitations under the License. import Sample from './Sample.vue'; import Tray from './Tray.vue'; import {range} from 'd3-array'; -import {Array1D, NDArrayMathCPU} from 'deeplearn'; +import {Array1D, ENV} from 'deeplearn'; -const math = new NDArrayMathCPU(false); +const math = ENV.math; export default { components: {Sample, Tray}, data() { return { + basisDimensions: [] + }; + }, + watch: { + model: function(m) { + const dims = m ? m.dimensions: 0; + this.basisDimensions = range(dims).map(dim => { + return math.oneHot(Array1D.new([dim]), dims).as1D(); + }); } }, props: { @@ -59,19 +68,6 @@ export default { vals: { type: Array, default: function() { return []; }}, scrollY: {default: 0} }, - computed: { - dimensions: function() { - return this.model ? this.model.dimensions : 0; - }, - basisDimensions: function() { - let output = range(this.dimensions).map(dim => { - let dir = Array1D.zeros([this.dimensions]); - dir.set(1, dim); - return dir; - }); - return output; - } - }, methods: { select: function(event) { this.$emit("select", event); diff --git a/demos/latent-space-explorer/components/Tray.vue b/demos/latent-space-explorer/components/Tray.vue index 5ac3e30aa4..08a6034652 100644 --- a/demos/latent-space-explorer/components/Tray.vue +++ b/demos/latent-space-explorer/components/Tray.vue @@ -48,9 +48,9 @@ import utils from '../utils/Utils'; import {range} from 'd3-array'; import {format} from 'd3-format'; import {scaleLinear, scaleBand} from 'd3-scale'; -import {Scalar, Array1D, NDArrayMathCPU} from 'deeplearn'; +import {Scalar, Array1D, ENV} from 'deeplearn'; -const math = new NDArrayMathCPU(false); +const math = ENV.math; export default { components: {Sample, Axis}, diff --git a/demos/latent-space-explorer/utils/FontModel.ts b/demos/latent-space-explorer/utils/FontModel.ts index c5f2eabdad..b40db49cac 100644 --- a/demos/latent-space-explorer/utils/FontModel.ts +++ b/demos/latent-space-explorer/utils/FontModel.ts @@ -13,7 +13,7 @@ limitations under the License. ==============================================================================*/ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, CheckpointLoader, NDArray, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, Array2D, CheckpointLoader, ENV, NDArray, NDArrayMath, Scalar} from 'deeplearn'; import {Cache} from './ModelCache'; @@ -26,7 +26,7 @@ export class FontModel { range = 0.4; charIdMap: {[id: string]: number}; private variables: {[varName: string]: NDArray}; - private math: NDArrayMathGPU; + private math: NDArrayMath; private inferCache = new Cache(this, this.infer); private numberOfValidChars = 62; private multiplierScalar = Scalar.new(255); @@ -56,7 +56,6 @@ export class FontModel { get(id: number, args: Array<{}>, priority: number) { args.push(this.metaData); - return new Promise((resolve, reject) => { args.push(() => resolve()); this.inferCache.get(id, args); @@ -64,7 +63,7 @@ export class FontModel { } init() { - this.math = new NDArrayMathGPU(); + this.math = ENV.math; } infer(args: Array<{}>) { @@ -75,11 +74,11 @@ export class FontModel { const charId = this.charIdMap[char.charAt(0)]; if (charId == null) { - throw(new Error('Invalid character id')); + throw (new Error('Invalid character id')); } - const adjusted = this.math.scope((keep, track) => { - const idx = track(Array1D.new([charId])); + const adjusted = this.math.scope(keep => { + const idx = Array1D.new([charId]); const onehotVector = this.math.oneHot(idx, this.numberOfValidChars).as1D(); @@ -110,24 +109,20 @@ export class FontModel { const d = adjusted.as3D(IMAGE_SIZE, IMAGE_SIZE, 1); - d.data().then(() => { + d.data().then(values => { const imageData = ctx.createImageData(IMAGE_SIZE, IMAGE_SIZE); let pixelOffset = 0; - for (let i = 0; i < d.shape[0]; i++) { - for (let j = 0; j < d.shape[1]; j++) { - const value = d.get(i, j, 0); - imageData.data[pixelOffset++] = value; - imageData.data[pixelOffset++] = value; - imageData.data[pixelOffset++] = value; - imageData.data[pixelOffset++] = 255; - } + for (let i = 0; i < values.length; i++) { + const value = values[i]; + imageData.data[pixelOffset++] = value; + imageData.data[pixelOffset++] = value; + imageData.data[pixelOffset++] = value; + imageData.data[pixelOffset++] = 255; } ctx.putImageData(imageData, 0, 0); - d.dispose(); - cb(); }); } diff --git a/demos/latent-space-explorer/utils/Utils.ts b/demos/latent-space-explorer/utils/Utils.ts index 29081ed03a..3094287fe8 100644 --- a/demos/latent-space-explorer/utils/Utils.ts +++ b/demos/latent-space-explorer/utils/Utils.ts @@ -12,9 +12,9 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -import {Array1D, NDArray, NDArrayMathCPU, Scalar} from 'deeplearn'; +import {Array1D, ENV, NDArray, Scalar} from 'deeplearn'; -const math = new NDArrayMathCPU(); +const math = ENV.math; export function interpolateLinear( embedding0: Array1D, embedding1: Array1D, ratio: Scalar) { @@ -45,9 +45,5 @@ export function norm(v: NDArray) { } export function unit(v: NDArray) { - const n = Scalar.new(norm(v).get()); - if (n.get() === 0) { - console.warn('Divide by zero'); - } - return math.arrayDividedByScalar(v, n); + return math.arrayDividedByScalar(v, norm(v)); } diff --git a/demos/mnist/mnist.ts b/demos/mnist/mnist.ts index 174459a98b..76d5716742 100644 --- a/demos/mnist/mnist.ts +++ b/demos/mnist/mnist.ts @@ -16,7 +16,7 @@ */ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, CheckpointLoader, NDArray, NDArrayMath, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, Array2D, CheckpointLoader, ENV, NDArray, Scalar} from 'deeplearn'; // manifest.json lives in the same directory as the mnist demo. const reader = new CheckpointLoader('.'); @@ -26,7 +26,7 @@ reader.getAllVariables().then(vars => { xhr.open('GET', 'sample_data.json'); xhr.onload = async () => { const data = JSON.parse(xhr.responseText) as SampleData; - const math = new NDArrayMathGPU(); + const math = ENV.math; // Wrap everything in a math.scope so we clean up intermediate NDArrays. math.scope(async () => { @@ -37,7 +37,7 @@ reader.getAllVariables().then(vars => { const x = Array1D.new(data.images[i]); // Infer through the model to get a prediction. - const predictedLabel = Math.round(await infer(math, x, vars).val()); + const predictedLabel = Math.round(await infer(x, vars).val()); console.log(`Item ${i}, predicted label ${predictedLabel}.`); // Aggregate correctness to show accuracy. @@ -71,15 +71,14 @@ export interface SampleData { * is the lowest level user-facing API in deeplearn.js giving the most control * to the user. Math commands execute immediately, like numpy. */ -export function infer( - math: NDArrayMath, x: Array1D, vars: {[varName: string]: NDArray}): Scalar { +export function infer(x: Array1D, vars: {[varName: string]: NDArray}): Scalar { const hidden1W = vars['hidden1/weights'] as Array2D; const hidden1B = vars['hidden1/biases'] as Array1D; const hidden2W = vars['hidden2/weights'] as Array2D; const hidden2B = vars['hidden2/biases'] as Array1D; const softmaxW = vars['softmax_linear/weights'] as Array2D; const softmaxB = vars['softmax_linear/biases'] as Array1D; - + const math = ENV.math; const hidden1 = math.relu(math.add(math.vectorTimesMatrix(x, hidden1W), hidden1B)) as Array1D; @@ -99,9 +98,9 @@ function renderMnistImage(array: Array1D) { canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); - const float32Array = array.getData().values; + const float32Array = array.dataSync(); const imageData = ctx.createImageData(width, height); - for (let i = 0; i < float32Array.length; i++) { + for (let i = 0; i < float32Array.length; ++i) { const j = i * 4; const value = Math.round(float32Array[i] * 255); imageData.data[j + 0] = value; diff --git a/demos/model-builder/model-builder.ts b/demos/model-builder/model-builder.ts index 05a53b9efe..4f85761b6f 100644 --- a/demos/model-builder/model-builder.ts +++ b/demos/model-builder/model-builder.ts @@ -22,7 +22,8 @@ import '../demo-header'; import '../demo-footer'; // tslint:disable-next-line:max-line-length -import {AdadeltaOptimizer, AdagradOptimizer, AdamaxOptimizer, AdamOptimizer, Array1D, Array3D, DataStats, FeedEntry, Graph, GraphRunner, GraphRunnerEventObserver, InCPUMemoryShuffledInputProviderBuilder, InMemoryDataset, MetricReduction, MomentumOptimizer, NDArray, NDArrayMath, NDArrayMathCPU, NDArrayMathGPU, Optimizer, RMSPropOptimizer, Scalar, Session, SGDOptimizer, Tensor, util, xhr_dataset, XhrDataset, XhrDatasetConfig} from 'deeplearn'; +import {AdadeltaOptimizer, AdagradOptimizer, AdamaxOptimizer, AdamOptimizer, Array1D, Array3D, DataStats, ENV, FeedEntry, Graph, GraphRunner, GraphRunnerEventObserver, InCPUMemoryShuffledInputProviderBuilder, InMemoryDataset, MetricReduction, MomentumOptimizer, NDArray, NDArrayMath, Optimizer, RMSPropOptimizer, Scalar, Session, SGDOptimizer, Tensor, util, xhr_dataset, XhrDataset, XhrDatasetConfig} from 'deeplearn'; + import {NDArrayImageVisualizer} from '../ndarray-image-visualizer'; import {NDArrayLogitsVisualizer} from '../ndarray-logits-visualizer'; import {PolymerElement, PolymerHTMLElement} from '../polymer-spec'; @@ -187,15 +188,9 @@ export class ModelBuilder extends ModelBuilderPolymer { private layersContainer: HTMLDivElement; private math: NDArrayMath; - // Keep one instance of each NDArrayMath so we don't create a user-initiated - // number of NDArrayMathGPU's. - private mathGPU: NDArrayMathGPU; - private mathCPU: NDArrayMathCPU; ready() { - this.mathGPU = new NDArrayMathGPU(); - this.mathCPU = new NDArrayMathCPU(); - this.math = this.mathGPU; + this.math = ENV.math; this.createGraphRunner(); this.optimizer = new MomentumOptimizer(this.learningRate, this.momentum); @@ -823,7 +818,7 @@ export class ModelBuilder extends ModelBuilderPolymer { // Draw the logits. for (let i = 0; i < inputFeeds.length; i++) { - const softmaxLogits = this.math.softmax(logits[i]); + const softmaxLogits = this.math.softmax(logits[i]).asType('float32'); this.outputNDArrayVisualizers[i].drawLogits( softmaxLogits, labels[i], diff --git a/demos/ndarray-logits-visualizer.ts b/demos/ndarray-logits-visualizer.ts index 606d9747d5..618a9dc35c 100644 --- a/demos/ndarray-logits-visualizer.ts +++ b/demos/ndarray-logits-visualizer.ts @@ -15,7 +15,7 @@ * ============================================================================= */ -import {Array1D, NDArrayMathCPU} from 'deeplearn'; +import {Array1D, ENV} from 'deeplearn'; import {PolymerElement, PolymerHTMLElement} from './polymer-spec'; @@ -69,14 +69,13 @@ export class NDArrayLogitsVisualizer extends NDArrayLogitsVisualizerPolymer { } drawLogits( - predictedLogits: Array1D, labelLogits: Array1D, + predictedLogits: Array1D<'float32'>, labelLogits: Array1D, labelClassNames?: string[]) { - const mathCpu = new NDArrayMathCPU(); - const labelClass = mathCpu.argMax(labelLogits).get(); + const labelClass = ENV.math.argMax(labelLogits).get(); - const topk = mathCpu.topK(predictedLogits, TOP_K); - const topkIndices = topk.indices.getValues(); - const topkValues = topk.values.getValues(); + const topk = this.topK(predictedLogits.dataSync(), TOP_K); + const topkIndices = topk.indices; + const topkValues = topk.values; for (let i = 0; i < topkIndices.length; i++) { const index = topkIndices[i]; @@ -93,6 +92,25 @@ export class NDArrayLogitsVisualizer extends NDArrayLogitsVisualizerPolymer { `${(100 * topkValues[i]).toFixed(1)}%`; } } + + private topK(values: Float32Array, k: number): + {values: Float32Array, indices: Int32Array} { + const valuesAndIndices: Array<{value: number, index: number}> = []; + for (let i = 0; i < values.length; i++) { + valuesAndIndices.push({value: values[i], index: i}); + } + valuesAndIndices.sort((a, b) => { + return b.value - a.value; + }); + + const topkValues = new Float32Array(k); + const topkIndices = new Int32Array(k); + for (let i = 0; i < k; i++) { + topkValues[i] = valuesAndIndices[i].value; + topkIndices[i] = valuesAndIndices[i].index; + } + return {values: topkValues, indices: topkIndices}; + } } document.registerElement( diff --git a/demos/nn-art/cppn.ts b/demos/nn-art/cppn.ts index db9a02371f..0bc754c448 100644 --- a/demos/nn-art/cppn.ts +++ b/demos/nn-art/cppn.ts @@ -16,8 +16,7 @@ */ // tslint:disable-next-line:max-line-length -import {Array2D, gpgpu_util, GPGPUContext, NDArrayMathGPU, webgl_util} from 'deeplearn'; - +import {Array2D, ENV, gpgpu_util, GPGPUContext, MathBackendWebGL, NDArray, NDArrayMath, webgl_util} from 'deeplearn'; import * as nn_art_util from './nn_art_util'; const MAX_LAYERS = 10; @@ -35,21 +34,21 @@ const colorModeOutputDimensions: {[colorMode in ColorMode]: number} = { export type ActivationFunction = 'tanh'|'sin'|'relu'|'step'; const activationFunctionMap: { - [activationFunction in ActivationFunction]: ( - math: NDArrayMathGPU, ndarray: Array2D) => Array2D + [activationFunction in ActivationFunction]: + (math: NDArrayMath, ndarray: Array2D) => Array2D } = { - 'tanh': (math: NDArrayMathGPU, ndarray: Array2D) => math.tanh(ndarray), - 'sin': (math: NDArrayMathGPU, ndarray: Array2D) => math.sin(ndarray), - 'relu': (math: NDArrayMathGPU, ndarray: Array2D) => math.relu(ndarray), - 'step': (math: NDArrayMathGPU, ndarray: Array2D) => math.step(ndarray) + 'tanh': (math: NDArrayMath, ndarray: Array2D) => math.tanh(ndarray), + 'sin': (math: NDArrayMath, ndarray: Array2D) => math.sin(ndarray), + 'relu': (math: NDArrayMath, ndarray: Array2D) => math.relu(ndarray), + 'step': (math: NDArrayMath, ndarray: Array2D) => math.step(ndarray) }; const NUM_IMAGE_SPACE_VARIABLES = 3; // x, y, r const NUM_LATENT_VARIABLES = 2; export class CPPN { - private math: NDArrayMathGPU; - private gl: WebGLRenderingContext; + private math: NDArrayMath; + private backend: MathBackendWebGL; private gpgpu: GPGPUContext; private renderShader: WebGLProgram; private addLatentVariablesShader: WebGLProgram; @@ -72,11 +71,13 @@ export class CPPN { private isInferring = false; constructor(private inferenceCanvas: HTMLCanvasElement) { - this.gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); - this.gpgpu = new GPGPUContext(this.gl); - this.math = new NDArrayMathGPU(this.gpgpu); + const gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); + this.gpgpu = new GPGPUContext(gl); + this.backend = new MathBackendWebGL(this.gpgpu); + this.math = new NDArrayMath(this.backend, false); + ENV.setMath(this.math); - const maxTextureSize = webgl_util.queryMaxTextureSize(this.gl); + const maxTextureSize = webgl_util.queryMaxTextureSize(gl); const canvasSize = Math.floor(Math.sqrt(maxTextureSize)); this.inferenceCanvas.width = canvasSize; this.inferenceCanvas.height = canvasSize; @@ -145,19 +146,14 @@ export class CPPN { const z1 = Math.sin(this.z1Counter); const z2 = Math.cos(this.z2Counter); - const intermediateResults = []; - // Add the latent variables. - const addLatentVariablesResultTex = - this.math.getTextureManager().acquireTexture(this.inputAtlas.shape); + const inputAtlasWithLatentVariables = + NDArray.make(this.inputAtlas.shape, {}) as Array2D; nn_art_util.addLatentVariables( - this.gpgpu, this.addLatentVariablesShader, this.inputAtlas.getTexture(), - addLatentVariablesResultTex, this.inputAtlas.shape, z1, z2); - const inputAtlasWithLatentVariables = Array2D.make(this.inputAtlas.shape, { - texture: addLatentVariablesResultTex, - textureShapeRC: this.inputAtlas.shape - }) as Array2D; - intermediateResults.push(inputAtlasWithLatentVariables); + this.gpgpu, this.addLatentVariablesShader, + this.backend.getTexture(this.inputAtlas.id), + this.backend.getTexture(inputAtlasWithLatentVariables.id), + this.inputAtlas.shape, z1, z2); let lastOutput = inputAtlasWithLatentVariables; @@ -171,7 +167,7 @@ export class CPPN { this.math, matmulResult); } nn_art_util.render( - this.gpgpu, this.renderShader, lastOutput.getTexture(), + this.gpgpu, this.renderShader, this.backend.getTexture(lastOutput.id), outputDimensions, colorModeIndex); }); diff --git a/demos/package.json b/demos/package.json index bab058e3cb..ef6497e16f 100644 --- a/demos/package.json +++ b/demos/package.json @@ -51,7 +51,7 @@ "@bower_components/polymer": "Polymer/polymer#1.*.*", "@bower_components/web-animations-js": "web-animations/web-animations-js#^2.2.0", "@bower_components/webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.24", - "deeplearn": "0.3.13", + "deeplearn": "0.3.15", "deeplearn-knn-image-classifier": "~0.2.0", "deeplearn-squeezenet": "~0.1.6", "tslint": "~5.8.0", diff --git a/demos/performance_rnn/performance_rnn.ts b/demos/performance_rnn/performance_rnn.ts index 1cf3ca479d..ef6a8e1bed 100644 --- a/demos/performance_rnn/performance_rnn.ts +++ b/demos/performance_rnn/performance_rnn.ts @@ -14,9 +14,8 @@ limitations under the License. ==============================================================================*/ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, CheckpointLoader, NDArray, NDArrayMath, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, Array2D, CheckpointLoader, ENV, NDArray, NDArrayMath, Scalar} from 'deeplearn'; import * as demo_util from '../util'; - import {KeyboardElement} from './keyboard_element'; // tslint:disable-next-line:no-require-imports @@ -106,8 +105,8 @@ const keyboardInterface = new KeyboardElement(container); const piano = new Piano({velocities: 4}).toMaster(); -const SALAMANDER_URL = 'https://storage.googleapis.com/learnjs-data/' + - 'Piano/Salamander/'; +// const SALAMANDER_URL = 'https://storage.googleapis.com/learnjs-data/' + +// 'Piano/Salamander/'; const CHECKPOINT_URL = 'https://storage.googleapis.com/learnjs-data/' + 'checkpoint_zoo/performance_rnn_v2'; @@ -121,41 +120,37 @@ if (!isDeviceSupported) { start(); } -const math = new NDArrayMathGPU(); +const math = ENV.math; let modelReady = false; function start() { - piano.load(SALAMANDER_URL) - .then(() => { - const reader = new CheckpointLoader(CHECKPOINT_URL); - return reader.getAllVariables(); - }) - .then((vars: {[varName: string]: NDArray}) => { - document.querySelector('#status').classList.add('hidden'); - document.querySelector('#controls').classList.remove('hidden'); - document.querySelector('#keyboard').classList.remove('hidden'); - - lstmKernel1 = - vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/kernel'] as Array2D; - lstmBias1 = - vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/bias'] as Array1D; - - lstmKernel2 = - vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/kernel'] as Array2D; - lstmBias2 = - vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/bias'] as Array1D; - - lstmKernel3 = - vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/kernel'] as Array2D; - lstmBias3 = - vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/bias'] as Array1D; - - fullyConnectedBiases = vars['fully_connected/biases'] as Array1D; - fullyConnectedWeights = vars['fully_connected/weights'] as Array2D; - modelReady = true; - resetRnn(); - }); + const reader = new CheckpointLoader(CHECKPOINT_URL); + reader.getAllVariables().then((vars: {[varName: string]: NDArray}) => { + document.querySelector('#status').classList.add('hidden'); + document.querySelector('#controls').classList.remove('hidden'); + document.querySelector('#keyboard').classList.remove('hidden'); + + lstmKernel1 = + vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/kernel'] as Array2D; + lstmBias1 = + vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/bias'] as Array1D; + + lstmKernel2 = + vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/kernel'] as Array2D; + lstmBias2 = + vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/bias'] as Array1D; + + lstmKernel3 = + vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/kernel'] as Array2D; + lstmBias3 = + vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/bias'] as Array1D; + + fullyConnectedBiases = vars['fully_connected/biases'] as Array1D; + fullyConnectedWeights = vars['fully_connected/weights'] as Array2D; + modelReady = true; + resetRnn(); + }); } function resetRnn() { @@ -276,14 +271,14 @@ function disableConditioning() { } function updateConditioningParams() { - const pitchHistogram = pitchHistogramElements.map((e) => { + const pitchHistogram = pitchHistogramElements.map(e => { return parseInt(e.value, 10) || 0; }); updateDisplayHistogram(pitchHistogram); - if (noteDensityEncoding !== undefined) { + if (noteDensityEncoding != null) { noteDensityEncoding.dispose(); - noteDensityEncoding = undefined; + noteDensityEncoding = null; } window.location.assign( @@ -297,9 +292,9 @@ function updateConditioningParams() { noteDensityEncoding = Array1D.zeros([DENSITY_BIN_RANGES.length + 1]); noteDensityEncoding.set(1.0, noteDensityIdx + 1); - if (pitchHistogramEncoding !== undefined) { + if (pitchHistogramEncoding != null) { pitchHistogramEncoding.dispose(); - pitchHistogramEncoding = undefined; + pitchHistogramEncoding = null; } pitchHistogramEncoding = Array1D.zeros([PITCH_HISTOGRAM_SIZE]); const pitchHistogramTotal = pitchHistogram.reduce((prev, val) => { @@ -311,7 +306,7 @@ function updateConditioningParams() { } document.getElementById('note-density').oninput = updateConditioningParams; -pitchHistogramElements.map((e) => { +pitchHistogramElements.forEach(e => { e.oninput = updateConditioningParams; }); updateConditioningParams(); @@ -389,20 +384,20 @@ document.getElementById('save-2').onclick = () => { }; function getConditioning(math: NDArrayMath): Array1D { - return math.scope((keep, track) => { + return math.scope(keep => { if (!conditioned) { // TODO(nsthorat): figure out why we have to cast these shapes to numbers. // The linter is complaining, though VSCode can infer the types. const size = 1 + (noteDensityEncoding.shape[0] as number) + (pitchHistogramEncoding.shape[0] as number); - const conditioning = track(Array1D.zeros([size])); + const conditioning = Array1D.zeros([size]); conditioning.set(1.0, 0); return conditioning; } else { const conditioningValues = math.concat1D(noteDensityEncoding, pitchHistogramEncoding); return math.concat1D( - track(Scalar.new(0.0).as1D()), // conditioning on. + Scalar.new(0.0).as1D(), // conditioning on. conditioningValues); } }); @@ -413,7 +408,7 @@ async function generateStep(loopId: number) { // Was part of an outdated generateStep() scheduled via setTimeout. return; } - await math.scope(async (keep, track) => { + await math.scope(async keep => { const lstm1 = math.basicLSTMCell.bind(math, forgetBias, lstmKernel1, lstmBias1); const lstm2 = @@ -421,12 +416,6 @@ async function generateStep(loopId: number) { const lstm3 = math.basicLSTMCell.bind(math, forgetBias, lstmKernel3, lstmBias3); - c.map(val => { - track(val); - }); - h.map(val => { - track(val); - }); const outputs: Scalar[] = []; // Generate some notes. for (let i = 0; i < STEPS_PER_GENERATE_CALL; i++) { @@ -455,12 +444,8 @@ async function generateStep(loopId: number) { lastSample = sampledOutput; } - c.map(val => { - keep(val); - }); - h.map(val => { - keep(val); - }); + c.forEach(val => keep(val)); + h.forEach(val => keep(val)); await outputs[outputs.length - 1].data(); @@ -468,10 +453,6 @@ async function generateStep(loopId: number) { playOutput(await outputs[i].val()); } - // Pro-actively upload the last sample to the gpu again and keep it - // for next time. - lastSample.getTexture(); - if (piano.now() - currentPianoTimeSec > MAX_GENERATION_LAG_SECONDS) { console.warn( `Generation is ${ diff --git a/demos/util.ts b/demos/util.ts index 6e828ec19f..58b5c5a52f 100644 --- a/demos/util.ts +++ b/demos/util.ts @@ -15,16 +15,10 @@ * ============================================================================= */ -import {NDArrayMathGPU} from 'deeplearn'; +import {ENV} from 'deeplearn'; export function isWebGLSupported(): boolean { - try { - const math = new NDArrayMathGPU(); - math.dispose(); - return true; - } catch (e) { - return false; - } + return ENV.getBackend('webgl') != null; } export function isSafari(): boolean { diff --git a/demos/yarn.lock b/demos/yarn.lock index 0a33dc195a..24f77579fb 100644 --- a/demos/yarn.lock +++ b/demos/yarn.lock @@ -180,7 +180,7 @@ "@bower_components/polymer@Polymer/polymer#1.*.*": version "0.0.0" - resolved "https://codeload.github.com/Polymer/polymer/tar.gz/ec0ca2cc0e6d044ab812cb5be331af817013345b" + resolved "https://codeload.github.com/Polymer/polymer/tar.gz/1dcf3839b3ce058d2d87737674a25ecdd7343f9a" "@bower_components/web-animations-js@web-animations/web-animations-js#^2.2.0": version "2.3.1" @@ -197,8 +197,8 @@ "@types/chai" "*" "@types/chai@*": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.5.tgz#b6e250e281b47e0192e236619e9b1afe62fd345c" + version "4.0.10" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.10.tgz#0eb222c7353adde8e0980bea04165d4d3b6afef3" "@types/chalk@^0.4.30": version "0.4.31" @@ -235,12 +235,12 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.37.tgz#48949c1516d46139c1e521195f9e12993b69d751" "@types/node@*": - version "8.0.53" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" + version "8.5.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.1.tgz#4ec3020bcdfe2abffeef9ba3fbf26fca097514b5" "@types/node@^6.0.0": - version "6.0.92" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.92.tgz#e7f721ae282772e12ba2579968c00d9cce422c5d" + version "6.0.94" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.94.tgz#70e509b07ed9f961c8f6f4a73a61d922be5029a7" "@types/parse5@^2.2.32", "@types/parse5@^2.2.34": version "2.2.34" @@ -259,8 +259,8 @@ resolved "https://registry.yarnpkg.com/@types/webcomponents.js/-/webcomponents.js-0.6.32.tgz#aba4bbfcb6889205aa8f8e0adec0bfc595b4f6cd" JSONStream@^1.0.3: - version "1.3.1" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" + version "1.3.2" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" dependencies: jsonparse "^1.2.0" through ">=2.2.7 <3" @@ -316,8 +316,8 @@ ajv@^4.9.1: json-stable-stringify "^1.0.1" ajv@^5.0.0, ajv@^5.1.5: - version "5.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9" + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -381,7 +381,7 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" -aproba@^1.0.3: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -463,6 +463,10 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asn1.js@^4.0.0: version "4.9.2" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a" @@ -525,14 +529,14 @@ autoprefixer@^6.3.1: postcss-value-parser "^3.2.3" autoprefixer@^7.1.2: - version "7.1.6" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.6.tgz#fb933039f74af74a83e71225ce78d9fd58ba84d7" + version "7.2.3" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.3.tgz#c2841e38b7940c2d0a9bbffd72c75f33637854f8" dependencies: - browserslist "^2.5.1" - caniuse-lite "^1.0.30000748" + browserslist "^2.10.0" + caniuse-lite "^1.0.30000783" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^6.0.13" + postcss "^6.0.14" postcss-value-parser "^3.2.3" aws-sign2@~0.6.0: @@ -691,8 +695,8 @@ babel-helper-replace-supers@^6.24.1: babel-types "^6.24.1" babel-helper-vue-jsx-merge-props@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.2.tgz#aceb1c373588279e2755ea1cfd35c22394fd33f8" + version "2.0.3" + resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6" babel-helpers@^6.24.1: version "6.24.1" @@ -743,9 +747,9 @@ babel-plugin-jsx-v-model@^2.0.1: html-tags "^2.0.0" svg-tags "^1.0.0" -babel-plugin-jsx-vue-functional@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jsx-vue-functional/-/babel-plugin-jsx-vue-functional-2.1.0.tgz#5630a0c86fe1904d28c30465e6bf1cf71235a239" +babel-plugin-react-require@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-react-require/-/babel-plugin-react-require-3.0.0.tgz#2e4e7b4496b93a654a1c80042276de4e4eeb20e3" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -1055,11 +1059,12 @@ babel-preset-env@^1.6.1: invariant "^2.2.2" semver "^5.3.0" -babel-preset-poi@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-poi/-/babel-preset-poi-1.1.0.tgz#92e2bd185ebd83827d7d06db1858d33d06a302e3" +babel-preset-poi@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-poi/-/babel-preset-poi-1.1.2.tgz#b1a1812f1ee4a063000c15636fe441e18ee82de4" dependencies: babel-macros "^1.2.0" + babel-plugin-react-require "^3.0.0" babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-transform-class-properties "^6.24.1" babel-plugin-transform-decorators-legacy "^1.3.4" @@ -1067,17 +1072,16 @@ babel-preset-poi@^1.1.0: babel-plugin-transform-react-jsx "^6.24.1" babel-plugin-transform-runtime "^6.23.0" babel-preset-env "^1.6.1" - babel-preset-vue "^1.2.1" + babel-preset-vue "^2.0.0" babel-runtime "^6.26.0" -babel-preset-vue@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/babel-preset-vue/-/babel-preset-vue-1.2.1.tgz#b0de8977e0ce981fc6824cf0a537917a02a6fe87" +babel-preset-vue@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-vue/-/babel-preset-vue-2.0.0.tgz#441f7cf75836a0fa908a5df62bc243f8f9109d2c" dependencies: babel-helper-vue-jsx-merge-props "^2.0.2" babel-plugin-jsx-event-modifiers "^2.0.2" babel-plugin-jsx-v-model "^2.0.1" - babel-plugin-jsx-vue-functional "^2.1.0" babel-plugin-syntax-jsx "^6.18.0" babel-plugin-transform-vue-jsx "^3.5.0" @@ -1173,7 +1177,7 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.1.1, bluebird@^3.4.7, bluebird@^3.5.1: +bluebird@^3.1.1, bluebird@^3.4.7, bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1218,8 +1222,8 @@ boom@2.x.x: hoek "2.x.x" boxen@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.2.2.tgz#3f1d4032c30ffea9d4b02c322eaf2ea741dcbce5" + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" dependencies: ansi-align "^2.0.0" camelcase "^4.0.0" @@ -1227,7 +1231,7 @@ boxen@^1.2.1: cli-boxes "^1.0.0" string-width "^2.0.0" term-size "^1.2.0" - widest-line "^1.0.0" + widest-line "^2.0.0" brace-expansion@^1.1.7: version "1.1.8" @@ -1375,12 +1379,12 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^2.1.2, browserslist@^2.5.1: - version "2.9.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.9.1.tgz#b72d3982ab01b5cd24da62ff6d45573886aff275" +browserslist@^2.1.2, browserslist@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346" dependencies: - caniuse-lite "^1.0.30000770" - electron-to-chromium "^1.3.27" + caniuse-lite "^1.0.30000780" + electron-to-chromium "^1.3.28" buffer-indexof@^1.0.0: version "1.1.1" @@ -1428,6 +1432,24 @@ cac@^4.0.0: string-width "^2.1.1" text-table "^0.2.0" +cacache@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.1.tgz#3e05f6e616117d9b54665b1b20c8aeb93ea5d36f" + dependencies: + bluebird "^3.5.0" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^1.3.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.1" + ssri "^5.0.0" + unique-filename "^1.1.0" + y18n "^3.2.1" + cached-path-relative@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7" @@ -1480,12 +1502,12 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000772" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b" + version "1.0.30000783" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000783.tgz#16b30d47266a4f515cc69ae0316b670c9603cdbe" -caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000770: - version "1.0.30000772" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000772.tgz#78129622cabfed7af1ff38b64ab680a6a0865420" +caniuse-lite@^1.0.30000780, caniuse-lite@^1.0.30000783: + version "1.0.30000783" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000783.tgz#9b5499fb1b503d2345d12aa6b8612852f4276ffd" capture-stack-trace@^1.0.0: version "1.0.0" @@ -1539,6 +1561,10 @@ chokidar@^1.0.0, chokidar@^1.6.0, chokidar@^1.7.0: optionalDependencies: fsevents "^1.0.0" +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1681,14 +1707,10 @@ command-line-usage@^3.0.3: table-layout "^0.3.0" typical "^2.6.0" -commander@2.12.x, commander@~2.12.1: +commander@2.12.x, commander@^2.9.0, commander@~2.12.1: version "2.12.2" resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" -commander@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1715,6 +1737,14 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +concat-stream@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + concat-stream@~1.5.0, concat-stream@~1.5.1: version "1.5.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" @@ -1766,11 +1796,7 @@ content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" -convert-source-map@^1.1.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" - -convert-source-map@^1.5.0: +convert-source-map@^1.1.0, convert-source-map@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" @@ -1786,20 +1812,35 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + copy-webpack-plugin@^4.0.1: - version "4.2.3" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.2.3.tgz#4a3c61089f3b635777f0f0af346c338b39d63755" + version "4.3.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.3.0.tgz#cfdf4d131c78d66917a1bb863f86630497aacf42" dependencies: - bluebird "^3.5.1" - glob "^7.1.2" + cacache "^10.0.1" + find-cache-dir "^1.0.0" + globby "^7.1.1" is-glob "^4.0.0" loader-utils "^0.2.15" lodash "^4.3.0" minimatch "^3.0.4" + p-limit "^1.0.0" + pify "^3.0.0" + serialize-javascript "^1.4.0" core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -1995,6 +2036,10 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + d3-array@^1.2.0, d3-array@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc" @@ -2093,17 +2138,13 @@ deeplearn-knn-image-classifier@~0.2.0: dependencies: deeplearn-squeezenet "~0.1.5" -deeplearn-squeezenet@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/deeplearn-squeezenet/-/deeplearn-squeezenet-0.1.5.tgz#db2e6ac320555a178278b238442000e3beea4683" - -deeplearn-squeezenet@~0.1.6: +deeplearn-squeezenet@~0.1.5, deeplearn-squeezenet@~0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/deeplearn-squeezenet/-/deeplearn-squeezenet-0.1.6.tgz#f73c25d8627de514d72425471a3d69436c754ecf" -deeplearn@0.3.13: - version "0.3.13" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.13.tgz#12033ab21581fb277dede662250bd58d86457d44" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" @@ -2172,18 +2213,18 @@ detect-indent@^4.0.0: repeating "^2.0.0" detect-libc@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1" + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" detect-node@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" detective@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" + version "4.7.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.0.tgz#6276e150f9e50829ad1f90ace4d9a2304188afcf" dependencies: - acorn "^4.0.3" + acorn "^5.2.1" defined "^1.0.0" diff@^3.2.0: @@ -2198,6 +2239,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -2216,11 +2264,10 @@ dns-txt@^2.0.2: buffer-indexof "^1.0.0" doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + version "2.0.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" dependencies: esutils "^2.0.2" - isarray "^1.0.0" dom-converter@~0.1: version "0.1.4" @@ -2292,6 +2339,15 @@ duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" +duplexify@^3.1.2, duplexify@^3.4.2: + version "3.5.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -2302,9 +2358,9 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.27: - version "1.3.27" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.28: + version "1.3.28" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz#8dd4e6458086644e9f9f0a1cf32e2a1f9dffd9ee" elliptic@^6.0.0: version "6.4.0" @@ -2326,6 +2382,12 @@ encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + dependencies: + once "^1.4.0" + enhanced-resolve@^3.0.0, enhanced-resolve@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" @@ -2340,10 +2402,10 @@ entities@~1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" errno@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + version "0.1.6" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026" dependencies: - prr "~0.0.0" + prr "~1.0.1" error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" @@ -2605,10 +2667,14 @@ extract-text-webpack-plugin@^3.0.0: schema-utils "^0.3.0" webpack-sources "^1.0.1" -extsprintf@1.3.0, extsprintf@^1.2.0: +extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" @@ -2638,14 +2704,14 @@ faye-websocket@~0.11.0: websocket-driver ">=0.5.1" feature-detect-es6@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/feature-detect-es6/-/feature-detect-es6-1.3.1.tgz#f888736af9cb0c91f55663bfa4762eb96ee7047f" + version "1.4.0" + resolved "https://registry.yarnpkg.com/feature-detect-es6/-/feature-detect-es6-1.4.0.tgz#82697c2f25f1c45fa1d885c4d74c5be308da6527" dependencies: array-back "^1.0.3" file-loader@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.5.tgz#91c25b6b6fbe56dae99f10a425fd64933b5c9daa" + version "1.1.6" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.6.tgz#7b9a8f2c58f00a77fddf49e940f7ac978a3ea0e8" dependencies: loader-utils "^1.0.2" schema-utils "^0.3.0" @@ -2708,6 +2774,13 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" +flush-write-stream@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2742,6 +2815,22 @@ fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2849,6 +2938,17 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -3101,6 +3201,14 @@ ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore@^3.3.5: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -3156,14 +3264,10 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@^1.3.4: +ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - inline-source-map@~0.6.0: version "0.6.2" resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5" @@ -3345,8 +3449,8 @@ is-path-in-cwd@^1.0.0: is-path-inside "^1.0.0" is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" dependencies: path-is-inside "^1.0.1" @@ -3425,8 +3529,8 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" js-base64@^2.1.9: - version "2.3.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf" + version "2.4.0" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" @@ -3503,8 +3607,8 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" jsonschema@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.0.tgz#d6ebaf70798db7b3a20c544f6c9ef9319b077de2" + version "1.2.2" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.2.tgz#83ab9c63d65bf4d596f91d81195e78772f6452bc" jsprim@^1.2.2: version "1.4.1" @@ -3766,8 +3870,8 @@ miller-rabin@^4.0.0: brorand "^1.0.1" "mime-db@>= 1.30.0 < 2": - version "1.31.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.31.0.tgz#a49cd8f3ebf3ed1a482b60561d9105ad40ca74cb" + version "1.32.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414" mime-db@~1.30.0: version "1.30.0" @@ -3820,6 +3924,21 @@ minimost@^1.0.0: camelcase-keys "^4.0.0" minimist "^1.2.0" +mississippi@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-1.3.0.tgz#d201583eb12327e3c5c1642a404a9cacf94e34f5" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^1.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -3846,6 +3965,17 @@ module-deps@^4.0.8: through2 "^2.0.0" xtend "^4.0.0" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -4043,7 +4173,7 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@^1.3.0, once@^1.3.3: +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -4115,7 +4245,7 @@ p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" -p-limit@^1.1.0: +p-limit@^1.0.0, p-limit@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" @@ -4142,6 +4272,14 @@ pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + param-case@2.1.x: version "2.1.1" resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" @@ -4249,6 +4387,12 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + pbkdf2@^3.0.3: version "3.0.14" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" @@ -4291,9 +4435,9 @@ poi-dev-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/poi-dev-utils/-/poi-dev-utils-1.0.1.tgz#c3089d1db60e9d2c56343decc6a3b9647d577c14" -poi-load-config@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/poi-load-config/-/poi-load-config-1.1.2.tgz#5db24d0e2d149ada2c35369f4de21d1924365bda" +poi-load-config@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/poi-load-config/-/poi-load-config-1.1.3.tgz#2b71d64b4f20c0f7b246709074a6e0808a2fdb03" dependencies: babel-core "^6.24.1" babel-load-config "^1.0.0" @@ -4311,14 +4455,14 @@ poi-webpack-node-externals@^2.0.0: resolved "https://registry.yarnpkg.com/poi-webpack-node-externals/-/poi-webpack-node-externals-2.0.0.tgz#3e23ae0673705f5f44b23ecd194b85c724de91fa" poi@~9.5.4: - version "9.5.5" - resolved "https://registry.yarnpkg.com/poi/-/poi-9.5.5.tgz#a34ccc0710312beb0441d54d4435bb692b3c4023" + version "9.5.11" + resolved "https://registry.yarnpkg.com/poi/-/poi-9.5.11.tgz#fee8e4e61b79c727bccecff0621cfa8988f25ed7" dependencies: address "^1.0.1" autoprefixer "^7.1.2" babel-core "^6.24.1" babel-loader "^7.0.0" - babel-preset-poi "^1.1.0" + babel-preset-poi "^1.1.2" cac "^4.0.0" case-sensitive-paths-webpack-plugin "^2.0.0" chalk "^2.0.1" @@ -4340,7 +4484,7 @@ poi@~9.5.4: opn "^5.0.0" parse-json-config "^0.2.0" poi-dev-utils "^1.0.1" - poi-load-config "^1.1.2" + poi-load-config "^1.1.3" poi-webpack-node-externals "^2.0.0" post-compile-webpack-plugin "^0.1.1" postcss-loader "^2.0.6" @@ -4685,7 +4829,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.13, postcss@^6.0.8: +postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.14, postcss@^6.0.8: version "6.0.14" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885" dependencies: @@ -4706,8 +4850,8 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" prettier@^1.7.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" + version "1.9.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827" pretty-error@^2.0.2: version "2.1.1" @@ -4728,6 +4872,10 @@ process@^0.11.10, process@~0.11.0: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + promise.series@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/promise.series/-/promise.series-0.2.0.tgz#2cc7ebe959fc3a6619c04ab4dbdc9e452d864bbd" @@ -4739,9 +4887,9 @@ proxy-addr@~2.0.2: forwarded "~0.1.2" ipaddr.js "1.5.2" -prr@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" pseudomap@^1.0.2: version "1.0.2" @@ -4757,6 +4905,21 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" +pump@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b" + dependencies: + duplexify "^3.1.2" + inherits "^2.0.1" + pump "^1.0.0" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -4886,16 +5049,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@1.0: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -4907,6 +5061,15 @@ readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@1.0: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -4964,8 +5127,8 @@ regenerate@^1.2.1: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" regenerator-transform@^0.10.0: version "0.10.1" @@ -5125,7 +5288,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -5138,6 +5301,12 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^2.0.0" inherits "^2.0.1" +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -5194,6 +5363,10 @@ send@0.16.1: range-parser "~1.2.0" statuses "~1.3.1" +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" + serve-index@^1.7.2: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -5387,6 +5560,12 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" +ssri@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.0.0.tgz#13c19390b606c821f2a10d02b351c1729b94d8cf" + dependencies: + safe-buffer "^5.1.0" + stable@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.6.tgz#910f5d2aed7b520c6e777499c1f32e139fdecb10" @@ -5413,6 +5592,13 @@ stream-combiner2@^1.1.1: duplexer2 "~0.1.0" readable-stream "^2.0.2" +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + stream-http@^2.0.0, stream-http@^2.7.2: version "2.7.2" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" @@ -5423,6 +5609,10 @@ stream-http@^2.0.0, stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + stream-splicer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83" @@ -5708,8 +5898,8 @@ tsconfig@^5.0.3: strip-json-comments "^2.0.0" tsify@~3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/tsify/-/tsify-3.0.3.tgz#a032e1a6a71c2621c3f25c0415459d53b70b9ec0" + version "3.0.4" + resolved "https://registry.yarnpkg.com/tsify/-/tsify-3.0.4.tgz#3c862c934aeeff705290de9ad2af8d197ac5bb03" dependencies: convert-source-map "^1.1.0" fs.realpath "^1.0.0" @@ -5718,9 +5908,9 @@ tsify@~3.0.3: through2 "^2.0.0" tsconfig "^5.0.3" -tslib@^1.7.1: - version "1.8.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.0.tgz#dc604ebad64bcbf696d613da6c954aa0e7ea1eb6" +tslib@^1.7.1, tslib@^1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac" tslint@~5.8.0: version "5.8.0" @@ -5739,10 +5929,10 @@ tslint@~5.8.0: tsutils "^2.12.1" tsutils@^2.12.1: - version "2.12.2" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.12.2.tgz#ad58a4865d17ec3ddb6631b6ca53be14a5656ff3" + version "2.13.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.13.1.tgz#d6d1cc0f7c04cf9fb3b28a292973cffb9cfbe09a" dependencies: - tslib "^1.7.1" + tslib "^1.8.0" tty-browserify@0.0.0, tty-browserify@~0.0.0: version "0.0.0" @@ -5771,7 +5961,7 @@ type-is@~1.6.15: media-typer "0.3.0" mime-types "~2.1.15" -typedarray@~0.0.5: +typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -5784,8 +5974,8 @@ typical@^2.6.0: resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" uglify-js@3.2.x: - version "3.2.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.2.0.tgz#cb411ee4ca0e0cadbfe3a4e1a1da97e6fa0d19c1" + version "3.2.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.2.2.tgz#870e4b34ed733d179284f9998efd3293f7fd73f6" dependencies: commander "~2.12.1" source-map "~0.6.1" @@ -5837,6 +6027,18 @@ uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + unique-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" @@ -5983,8 +6185,8 @@ vue-hot-reload-api@^2.2.0: resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz#683bd1d026c0d3b3c937d5875679e9a87ec6cd8f" vue-loader@^13.0.0: - version "13.5.0" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.5.0.tgz#52f7b3790a267eff80012b77ea187a54586dd5d4" + version "13.6.0" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.6.0.tgz#c1c9570e1e57475f8acb02cda35551b812f88086" dependencies: consolidate "^0.14.0" hash-sum "^1.0.2" @@ -6008,8 +6210,8 @@ vue-style-loader@^3.0.0: loader-utils "^1.0.2" vue-template-compiler@^2.3.3: - version "2.5.9" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.9.tgz#7fabc73c8d3d12d32340cd86c5fc33e00e86d686" + version "2.5.11" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.11.tgz#7dda6905e464ff173c8e70e1dfd1769a7888b7e8" dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -6019,8 +6221,8 @@ vue-template-es2015-compiler@^1.6.0: resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18" vue@^2.3.3, vue@~2.5.9: - version "2.5.9" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.9.tgz#b2380cd040915dca69881dafd121d760952e65f7" + version "2.5.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.11.tgz#80ca2657aa81f03545cd8dd5a2f55454641e6405" ware@^1.3.0: version "1.3.0" @@ -6071,8 +6273,8 @@ webpack-dev-middleware@^1.11.0: time-stamp "^2.0.0" webpack-dev-server@^2.9.2: - version "2.9.5" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz#79336fba0087a66ae491f4869f6545775b18daa8" + version "2.9.7" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz#100ad6a14775478924d417ca6dcfb9d52a98faed" dependencies: ansi-html "0.0.7" array-includes "^3.0.3" @@ -6120,8 +6322,8 @@ webpack-sources@^1.0.1: source-map "~0.6.1" webpack@^3.7.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83" + version "3.10.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -6181,11 +6383,11 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" -widest-line@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" +widest-line@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" dependencies: - string-width "^1.0.1" + string-width "^2.1.1" window-size@0.1.0: version "0.1.0" From 753ddbd2201df7f792a68c647894a0ddd7bbb483 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Fri, 22 Dec 2017 15:16:49 -0500 Subject: [PATCH 2/9] save --- demos/latent-space-explorer/App.vue | 1 + .../latent-space-explorer/components/Tray.vue | 20 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/demos/latent-space-explorer/App.vue b/demos/latent-space-explorer/App.vue index 6617ec681a..db4190c602 100644 --- a/demos/latent-space-explorer/App.vue +++ b/demos/latent-space-explorer/App.vue @@ -139,6 +139,7 @@ export default { this.parseUrlHash(); } else { this.selectedSample = event.selectedSample + console.log('selected sample in app.vue changed to', this.selectedSample); this.updateHash(); } }, diff --git a/demos/latent-space-explorer/components/Tray.vue b/demos/latent-space-explorer/components/Tray.vue index 08a6034652..8e3fa7e77f 100644 --- a/demos/latent-space-explorer/components/Tray.vue +++ b/demos/latent-space-explorer/components/Tray.vue @@ -18,7 +18,7 @@ limitations under the License.
- + /> -->
{{format(selectedValue)}}
@@ -48,7 +47,7 @@ import utils from '../utils/Utils'; import {range} from 'd3-array'; import {format} from 'd3-format'; import {scaleLinear, scaleBand} from 'd3-scale'; -import {Scalar, Array1D, ENV} from 'deeplearn'; +import {Scalar, ENV} from 'deeplearn'; const math = ENV.math; @@ -71,15 +70,13 @@ export default { numSamples: { type: Number, default: 9 }, width: { type: Number, default: 200 }, initialValue: { type: Number, default: 1}, - selectedSample: { default: () => {[]}}, - direction: { default: () => {[]}}, + selectedSample: null, + direction: null, range: { type: Number, default: 1 }, scrollY: {default: 0} }, computed: { extent: function() { return [-this.range, this.range]; }, - dimensions: function() { return this.model ? this.model.dimensions : 0; }, - zero: function() { return Array1D.zeros([this.dimensions]); }, hoverScale: function() { return this.interpolate.domain([0, this.width]).range( this.extent).clamp(true); @@ -98,8 +95,8 @@ export default { return math.divide(this.direction, length); }, selectedValue: function() { - const scalar = math.dotProduct(this.unitDirection, this.selectedSample) - return scalar.getValues()[0] + const scalar = math.dotProduct(this.unitDirection, this.selectedSample); + return scalar.getValues()[0]; }, selectedX: function() { return this.hoverScale.invert(this.selectedValue); @@ -113,10 +110,7 @@ export default { watch: { selectedSample: function(value) { this.recomputeSamples(); }, model: function() { this.recomputeSamples(); }, - selectedValue: function() { this.recomputeSamples(); }, width: function() { this.recomputeSamples(); }, - pos: function() { this.recomputeSamples(); }, - bands: function() { this.recomputeSamples(); }, scrollY: function(val) { this.checkVisibility(); } }, methods: { From f047f3b1fb390a4a0e576f7d5864cffab0d35790 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Fri, 22 Dec 2017 17:15:15 -0500 Subject: [PATCH 3/9] save --- demos/latent-space-explorer/App.vue | 8 ++-- .../latent-space-explorer/components/Tray.vue | 39 +++++++++++-------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/demos/latent-space-explorer/App.vue b/demos/latent-space-explorer/App.vue index db4190c602..7b6c61374c 100644 --- a/demos/latent-space-explorer/App.vue +++ b/demos/latent-space-explorer/App.vue @@ -138,18 +138,18 @@ export default { if (event.isInitialSelection && window.location.hash) { this.parseUrlHash(); } else { - this.selectedSample = event.selectedSample - console.log('selected sample in app.vue changed to', this.selectedSample); + this.selectedSample = event.selectedSample; this.updateHash(); } }, updateHash: function() { if (this.selectedSample) { - const vals = this.selectedSample.getValues(); - const hashStr = '#' + Array.from(vals).map( + this.selectedSample.data().then(vals => { + const hashStr = '#' + Array.from(vals).map( val => parseFloat(val).toFixed(3)) .join(','); history.replaceState(undefined, undefined, hashStr); + }); } }, parseUrlHash: function() { diff --git a/demos/latent-space-explorer/components/Tray.vue b/demos/latent-space-explorer/components/Tray.vue index 8e3fa7e77f..75a6c86f47 100644 --- a/demos/latent-space-explorer/components/Tray.vue +++ b/demos/latent-space-explorer/components/Tray.vue @@ -18,7 +18,7 @@ limitations under the License.
- + />
@@ -61,7 +61,9 @@ export default { formatter: format(",.3f"), visible: false, samples: [], - offset: 0 + offset: 0, + selectedX: 0, + selectedValue: 0 } }, props: { @@ -89,31 +91,34 @@ export default { return this.position.domain([0, this.numSamples - 1]).range(this.extent); }, sampleWidth: function() { return this.bands.bandwidth(); }, - height: function() { return this.sampleWidth; }, - unitDirection: function() { - let length = math.sum(math.multiply(this.direction, this.direction)); - return math.divide(this.direction, length); - }, - selectedValue: function() { - const scalar = math.dotProduct(this.unitDirection, this.selectedSample); - return scalar.getValues()[0]; - }, - selectedX: function() { - return this.hoverScale.invert(this.selectedValue); - }, + height: function() { return this.sampleWidth; } }, mounted() { + this.computeDirection(); this.recomputeSamples(); this.checkVisibility(); }, watch: { - selectedSample: function(value) { this.recomputeSamples(); }, + selectedSample: function() { + this.computeDirection(); + }, model: function() { this.recomputeSamples(); }, width: function() { this.recomputeSamples(); }, - scrollY: function(val) { this.checkVisibility(); } + scrollY: function(val) { this.checkVisibility(); }, + direction: function() { this.computeDirection(); }, }, methods: { + computeDirection() { + let length = math.sum(math.multiply(this.direction, this.direction)); + this.unitDirection = math.divide(this.direction, length); + const scalar = math.dotProduct(this.unitDirection, this.selectedSample); + scalar.data().then(values => { + this.selectedValue = values[0]; + this.selectedX = this.hoverScale.invert(this.selectedValue); + this.recomputeSamples(); + }); + }, dragStart: function(event) { document.addEventListener("mousemove", this.dragUpdate); document.addEventListener("mouseup", this.dragEnd); From 6ffa1f5c8c68ed797127a18f076ed680d93bd841 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Fri, 22 Dec 2017 19:07:08 -0500 Subject: [PATCH 4/9] save --- README.md | 6 +-- demos/intro/intro.ts | 2 +- demos/lstm/lstm.ts | 18 +++---- demos/ml_beginners/ml_beginners.ts | 24 ++++----- demos/mnist/mnist.md | 4 +- demos/one_plus_one/one_plus_one.ts | 5 +- demos/performance_rnn/performance_rnn.ts | 60 ++++++++++++---------- demos/teachable_gaming/teachable_gaming.ts | 22 ++++---- demos/xor/learn-xor.ts | 8 ++- docs/tutorials/intro.md | 18 +++---- docs/tutorials/ml_beginners.md | 28 +++++----- docs/tutorials/performance.md | 26 +++------- src/graph/session_util_test.ts | 2 +- starter/es6/main.js | 4 +- starter/es6/package.json | 2 +- starter/es6/yarn.lock | 6 +-- starter/typescript/main.ts | 4 +- starter/typescript/package.json | 2 +- starter/typescript/yarn.lock | 6 +-- 19 files changed, 113 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index d606418cd7..1b6c9ada14 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ See the [TypeScript starter project](https://github.com/PAIR-code/deeplearnjs/tr short example that sums an array with a scalar (broadcasted): ```ts -import {Array1D, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, ENV, Scalar} from 'deeplearn'; -const math = new NDArrayMathGPU(); +const math = ENV.math; const a = Array1D.new([1, 2, 3]); const b = Scalar.new(2); @@ -63,7 +63,7 @@ After importing the library, the API will be available as `dl` in the global namespace. ```js -var math = new dl.NDArrayMathGPU(); +var math = dl.ENV.math; var a = dl.Array1D.new([1, 2, 3]); var b = dl.Scalar.new(2); diff --git a/demos/intro/intro.ts b/demos/intro/intro.ts index b4a106ab95..34858ed5fb 100644 --- a/demos/intro/intro.ts +++ b/demos/intro/intro.ts @@ -21,7 +21,7 @@ import {Array1D, Array2D, CostReduction, ENV, FeedEntry, Graph, InCPUMemoryShuff // This file parallels (some of) the code in the introduction tutorial. /** - * 'NDArrayMathGPU' section of tutorial + * 'NDArrayMath with WebGL backend' section of tutorial */ async function intro() { const math = ENV.math; diff --git a/demos/lstm/lstm.ts b/demos/lstm/lstm.ts index 2133d072a7..ff28bc8fe6 100644 --- a/demos/lstm/lstm.ts +++ b/demos/lstm/lstm.ts @@ -15,14 +15,14 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, CheckpointLoader, NDArrayMathGPU, Scalar, util} from 'deeplearn'; +import {Array1D, Array2D, CheckpointLoader, ENV, Scalar, util} from 'deeplearn'; // manifest.json lives in the same directory. const reader = new CheckpointLoader('.'); reader.getAllVariables().then(async vars => { const primerData = 3; const expected = [1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4]; - const math = new NDArrayMathGPU(); + const math = ENV.math; const lstmKernel1 = vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/kernel'] as Array2D; @@ -39,25 +39,25 @@ reader.getAllVariables().then(async vars => { const results: number[] = []; - await math.scope(async (keep, track) => { - const forgetBias = track(Scalar.new(1.0)); + await math.scope(async () => { + const forgetBias = Scalar.new(1.0); const lstm1 = math.basicLSTMCell.bind(math, forgetBias, lstmKernel1, lstmBias1); const lstm2 = math.basicLSTMCell.bind(math, forgetBias, lstmKernel2, lstmBias2); let c = [ - track(Array2D.zeros([1, lstmBias1.shape[0] / 4])), - track(Array2D.zeros([1, lstmBias2.shape[0] / 4])) + Array2D.zeros([1, lstmBias1.shape[0] / 4]), + Array2D.zeros([1, lstmBias2.shape[0] / 4]) ]; let h = [ - track(Array2D.zeros([1, lstmBias1.shape[0] / 4])), - track(Array2D.zeros([1, lstmBias2.shape[0] / 4])) + Array2D.zeros([1, lstmBias1.shape[0] / 4]), + Array2D.zeros([1, lstmBias2.shape[0] / 4]) ]; let input = primerData; for (let i = 0; i < expected.length; i++) { - const onehot = track(Array2D.zeros([1, 10])); + const onehot = Array2D.zeros([1, 10]); onehot.set(1.0, 0, input); const output = math.multiRNNCell([lstm1, lstm2], onehot, c, h); diff --git a/demos/ml_beginners/ml_beginners.ts b/demos/ml_beginners/ml_beginners.ts index ea9af747be..f81ac812eb 100644 --- a/demos/ml_beginners/ml_beginners.ts +++ b/demos/ml_beginners/ml_beginners.ts @@ -16,13 +16,13 @@ */ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, CostReduction, Graph, InCPUMemoryShuffledInputProviderBuilder, NDArray, NDArrayMathGPU, Scalar, Session, SGDOptimizer, Tensor} from 'deeplearn'; +import {Array1D, Array2D, CostReduction, ENV, Graph, InCPUMemoryShuffledInputProviderBuilder, NDArray, Scalar, Session, SGDOptimizer, Tensor} from 'deeplearn'; async function mlBeginners() { + const math = ENV.math; + // This file parallels (some of) the code in the ML Beginners tutorial. { - const math = new NDArrayMathGPU(); - const matrixShape: [number, number] = [2, 3]; // 2 rows, 3 columns. const matrix = Array2D.new(matrixShape, [10, 20, 30, 40, 50, 60]); const vector = Array1D.new([0, 1, 2]); @@ -54,10 +54,9 @@ async function mlBeginners() { // At this point the graph is set up, but has not yet been evaluated. // **deeplearn.js** needs a Session object to evaluate a graph. - const math = new NDArrayMathGPU(); const session = new Session(graph, math); - await math.scope(async (keep, track) => { + await math.scope(async () => { /** * Inference */ @@ -65,8 +64,7 @@ async function mlBeginners() { // providing a value 4 for "x". // NOTE: "a", "b", and "c" are randomly initialized, so this will give us // something random. - let result: NDArray = - session.eval(y, [{tensor: x, data: track(Scalar.new(4))}]); + let result: NDArray = session.eval(y, [{tensor: x, data: Scalar.new(4)}]); console.log(result.shape); console.log(result.getValues()); @@ -77,13 +75,10 @@ async function mlBeginners() { // To do this, we need to provide examples of x and y. // The values given here are for values a = 3, b = 2, c = 1, with random // noise added to the output so it's not a perfect fit. - const xs: Scalar[] = [ - track(Scalar.new(0)), track(Scalar.new(1)), track(Scalar.new(2)), - track(Scalar.new(3)) - ]; + const xs: Scalar[] = + [Scalar.new(0), Scalar.new(1), Scalar.new(2), Scalar.new(3)]; const ys: Scalar[] = [ - track(Scalar.new(1.1)), track(Scalar.new(5.9)), track(Scalar.new(16.8)), - track(Scalar.new(33.9)) + Scalar.new(1.1), Scalar.new(5.9), Scalar.new(16.8), Scalar.new(33.9) ]; // When training, it's important to shuffle your data! const shuffledInputProviderBuilder = @@ -114,9 +109,8 @@ async function mlBeginners() { } // Now print the value from the trained model for x = 4, should be ~57.0. - result = session.eval(y, [{tensor: x, data: track(Scalar.new(4))}]); + result = session.eval(y, [{tensor: x, data: Scalar.new(4)}]); console.log('result should be ~57.0:'); - console.log(result.shape); console.log(await result.data()); }); } diff --git a/demos/mnist/mnist.md b/demos/mnist/mnist.md index bbe38ef133..971cadde44 100644 --- a/demos/mnist/mnist.md +++ b/demos/mnist/mnist.md @@ -75,11 +75,11 @@ to write our model. Here is a snippet demonstrating the use of `CheckpointLoader`: ```ts -import {CheckpointLoader} from 'deeplearn'; +import {CheckpointLoader, ENV} from 'deeplearn'; // manifest.json is in the same dir as index.html. const varLoader = new CheckpointLoader('.'); varLoader.getAllVariables().then(async vars => { - const math = new NDArrayMathGPU(); + const math = ENV.math; // Get NDArray of variables casted with expected dimension. const hidden1W = vars['hidden1/weights'] as Array2D; diff --git a/demos/one_plus_one/one_plus_one.ts b/demos/one_plus_one/one_plus_one.ts index 6c94634251..0788795f47 100644 --- a/demos/one_plus_one/one_plus_one.ts +++ b/demos/one_plus_one/one_plus_one.ts @@ -15,11 +15,10 @@ * ============================================================================= */ -// tslint:disable-next-line:max-line-length -import {NDArrayMathGPU, Scalar} from 'deeplearn'; +import {ENV, Scalar} from 'deeplearn'; async function onePlusOne() { - const math = new NDArrayMathGPU(); + const math = ENV.math; const a = Scalar.new(1); const b = Scalar.new(1); diff --git a/demos/performance_rnn/performance_rnn.ts b/demos/performance_rnn/performance_rnn.ts index ef6a8e1bed..b43741b4d5 100644 --- a/demos/performance_rnn/performance_rnn.ts +++ b/demos/performance_rnn/performance_rnn.ts @@ -105,8 +105,8 @@ const keyboardInterface = new KeyboardElement(container); const piano = new Piano({velocities: 4}).toMaster(); -// const SALAMANDER_URL = 'https://storage.googleapis.com/learnjs-data/' + -// 'Piano/Salamander/'; +const SALAMANDER_URL = 'https://storage.googleapis.com/learnjs-data/' + + 'Piano/Salamander/'; const CHECKPOINT_URL = 'https://storage.googleapis.com/learnjs-data/' + 'checkpoint_zoo/performance_rnn_v2'; @@ -125,32 +125,36 @@ const math = ENV.math; let modelReady = false; function start() { - const reader = new CheckpointLoader(CHECKPOINT_URL); - reader.getAllVariables().then((vars: {[varName: string]: NDArray}) => { - document.querySelector('#status').classList.add('hidden'); - document.querySelector('#controls').classList.remove('hidden'); - document.querySelector('#keyboard').classList.remove('hidden'); - - lstmKernel1 = - vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/kernel'] as Array2D; - lstmBias1 = - vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/bias'] as Array1D; - - lstmKernel2 = - vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/kernel'] as Array2D; - lstmBias2 = - vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/bias'] as Array1D; - - lstmKernel3 = - vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/kernel'] as Array2D; - lstmBias3 = - vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/bias'] as Array1D; - - fullyConnectedBiases = vars['fully_connected/biases'] as Array1D; - fullyConnectedWeights = vars['fully_connected/weights'] as Array2D; - modelReady = true; - resetRnn(); - }); + piano.load(SALAMANDER_URL) + .then(() => { + const reader = new CheckpointLoader(CHECKPOINT_URL); + return reader.getAllVariables(); + }) + .then((vars: {[varName: string]: NDArray}) => { + document.querySelector('#status').classList.add('hidden'); + document.querySelector('#controls').classList.remove('hidden'); + document.querySelector('#keyboard').classList.remove('hidden'); + + lstmKernel1 = + vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/kernel'] as Array2D; + lstmBias1 = + vars['rnn/multi_rnn_cell/cell_0/basic_lstm_cell/bias'] as Array1D; + + lstmKernel2 = + vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/kernel'] as Array2D; + lstmBias2 = + vars['rnn/multi_rnn_cell/cell_1/basic_lstm_cell/bias'] as Array1D; + + lstmKernel3 = + vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/kernel'] as Array2D; + lstmBias3 = + vars['rnn/multi_rnn_cell/cell_2/basic_lstm_cell/bias'] as Array1D; + + fullyConnectedBiases = vars['fully_connected/biases'] as Array1D; + fullyConnectedWeights = vars['fully_connected/weights'] as Array2D; + modelReady = true; + resetRnn(); + }); } function resetRnn() { diff --git a/demos/teachable_gaming/teachable_gaming.ts b/demos/teachable_gaming/teachable_gaming.ts index b64a340fa0..15d54dd917 100644 --- a/demos/teachable_gaming/teachable_gaming.ts +++ b/demos/teachable_gaming/teachable_gaming.ts @@ -19,9 +19,8 @@ import '../demo-header'; import '../demo-footer'; // tslint:disable-next-line:max-line-length -import {Array3D, ENV, gpgpu_util, GPGPUContext, NDArrayMathGPU} from 'deeplearn'; +import {Array3D, ENV, gpgpu_util, GPGPUContext, MathBackendWebGL, NDArrayMath} from 'deeplearn'; import {KNNImageClassifier} from 'deeplearn-knn-image-classifier'; - import {PolymerElement, PolymerHTMLElement} from '../polymer-spec'; // tslint:disable-next-line:no-any @@ -79,9 +78,7 @@ export class TeachableGamingDemo extends TeachableGamingDemoPolymer { predicting: boolean; selectedGameIndex = 0; - private math: NDArrayMathGPU; - private gl: WebGLRenderingContext; - private gpgpu: GPGPUContext; + private math: NDArrayMath; private selectedIndex: number; private predictedIndex: number; private hasAnyTrainedClass: boolean; @@ -207,9 +204,10 @@ export class TeachableGamingDemo extends TeachableGamingDemoPolymer { }); } - this.gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); - this.gpgpu = new GPGPUContext(this.gl); - this.math = new NDArrayMathGPU(this.gpgpu); + const gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); + const gpgpu = new GPGPUContext(gl); + const backend = new MathBackendWebGL(gpgpu); + this.math = new NDArrayMath(backend, false); this.classifier = new KNNImageClassifier( TeachableGamingDemo.maxControls, TeachableGamingDemo.knnKValue, this.math); @@ -334,8 +332,8 @@ export class TeachableGamingDemo extends TeachableGamingDemoPolymer { this.previousFrameTime = frameTimeStart; if (this.selectedIndex >= 0) { this.predicting = false; - await this.math.scope(async (keep, track) => { - const image = track(Array3D.fromPixels(this.webcamVideoElement)); + await this.math.scope(async () => { + const image = Array3D.fromPixels(this.webcamVideoElement); const indicators = document.querySelectorAll('.indicators'); for (let i = 0; i < indicators.length; i++) { (indicators[i] as HTMLElement).style.backgroundColor = 'lightgray'; @@ -347,8 +345,8 @@ export class TeachableGamingDemo extends TeachableGamingDemoPolymer { }); } else if (this.hasAnyTrainedClass) { this.predicting = true; - await this.math.scope(async (keep, track) => { - const image = track(Array3D.fromPixels(this.webcamVideoElement)); + await this.math.scope(async () => { + const image = Array3D.fromPixels(this.webcamVideoElement); const timeStart = performance.now(); const results = await this.classifier.predictClass(image); this.predictTimes.add(performance.now() - timeStart); diff --git a/demos/xor/learn-xor.ts b/demos/xor/learn-xor.ts index 55243d7cb2..e742697a4d 100644 --- a/demos/xor/learn-xor.ts +++ b/demos/xor/learn-xor.ts @@ -14,10 +14,8 @@ limitations under the License. ==============================================================================*/ 'use strict'; -import {Array1D, CostReduction, Graph, NDArrayMathGPU} from 'deeplearn'; -import {InCPUMemoryShuffledInputProviderBuilder} from 'deeplearn'; -import {Session, SGDOptimizer, Tensor} from 'deeplearn'; -import {Scalar} from 'deeplearn'; +// tslint:disable-next-line:max-line-length +import {Scalar, Session, SGDOptimizer, Tensor, Array1D, CostReduction, Graph, ENV, InCPUMemoryShuffledInputProviderBuilder} from 'deeplearn'; const EPSILON = 1e-7; @@ -32,7 +30,7 @@ export const learnXOR = async () => { let cost: Scalar; const graph = new Graph(); - const math = new NDArrayMathGPU(); + const math = ENV.math; const input = graph.placeholder('input', [2]); const y = graph.placeholder('y', [1]); diff --git a/docs/tutorials/intro.md b/docs/tutorials/intro.md index c637b680d4..4018685a53 100644 --- a/docs/tutorials/intro.md +++ b/docs/tutorials/intro.md @@ -57,7 +57,7 @@ as it is an implementation detail. If `NDArray` data is stored on the CPU, the first time a GPU mathematical operation is called the data will be uploaded to a texture automatically. If you call -`NDArray.getValuesAsync()` on a GPU-resident `NDArray`, the +`NDArray.data()` on a GPU-resident `NDArray`, the library will download the texture to the CPU and delete the texture. ### NDArrayMath @@ -65,12 +65,12 @@ library will download the texture to the CPU and delete the texture. The library provides a `NDArrayMath` base class which defines a set of mathematical functions that operate on `NDArray`s. -#### NDArrayMathGPU +#### NDArrayMath with WebGL backend -When using the `NDArrayMathGPU` implementation, these mathematical +When using the `NDArrayMath` with the WebGL backend, these mathematical operations enqueue shader programs to be executed on the GPU. Unlike in -`NDArrayMathCPU`, **these operations are not blocking**, but the user can -synchronize the cpu with the gpu by calling `getValuesAsync()` on +CPU backend, **these operations are not blocking**, but the user can +synchronize the cpu with the gpu by calling `data()` on the `NDArray`, as we describe in detail below. These shaders read and write from `WebGLTexture`s which are owned by @@ -81,7 +81,7 @@ performance. Example of taking the mean squared difference between two matrices: ```js -const math = new NDArrayMathGPU(); +const math = ENV.math; const a = Array2D.new([2, 2], [1.0, 2.0, 3.0, 4.0]); const b = Array2D.new([2, 2], [0.0, 2.0, 4.0, 6.0]); @@ -96,9 +96,9 @@ const average = math.divide(sum, size); console.log('mean squared difference: ' + await average.val()); ``` -> TIP: Avoid calling `get()` or `getValuesAsync()` between mathematical GPU +> TIP: Avoid calling `data()/dataSync()` between mathematical GPU operations unless you are debugging. This forces a texture download, and -subsequent `NDArrayMathGPU` calls will have to re-upload the data to a new +subsequent operation calls will have to re-upload the data to a new texture. #### NDArrayMathCPU @@ -172,7 +172,7 @@ Training with the `Graph` object from above: ```js const learningRate = .00001; const batchSize = 3; -const math = new NDArrayMathGPU(); +const math = ENV.math; const session = new Session(g, math); const optimizer = new SGDOptimizer(learningRate); diff --git a/docs/tutorials/ml_beginners.md b/docs/tutorials/ml_beginners.md index bc91a6d1b6..e1be9836bf 100644 --- a/docs/tutorials/ml_beginners.md +++ b/docs/tutorials/ml_beginners.md @@ -107,7 +107,7 @@ a `NDArrayMath` object. For example, if you want to compute a matrix times a vector on the GPU: ```ts -const math = new NDArrayMathGPU(); +const math = ENV.math; const matrixShape = [2, 3]; // 2 rows, 3 columns. const matrix = Array2D.new(matrixShape, [10, 20, 30, 40, 50, 60]); @@ -246,11 +246,11 @@ const cost: Tensor = graph.meanSquaredCost(y, yLabel); // At this point the graph is set up, but has not yet been evaluated. // **deeplearn.js** needs a Session object to evaluate a graph. -const math = new NDArrayMathGPU(); +const math = ENV.math; const session = new Session(graph, math); -// For more information on scope / track, check out the [tutorial on performance](performance.md). -await math.scope(async (keep, track) => { +// For more information on scope, check out the [tutorial on performance](performance.md). +await math.scope(async () => { /** * Inference */ @@ -259,7 +259,7 @@ await math.scope(async (keep, track) => { // NOTE: "a", "b", and "c" are randomly initialized, so this will give us // something random. let result: NDArray = - session.eval(y, [{tensor: x, data: track(Scalar.new(4))}]); + session.eval(y, [{tensor: x, data: Scalar.new(4)}]); console.log(result.shape); console.log('result', await result.data()); @@ -271,16 +271,16 @@ await math.scope(async (keep, track) => { // The values given here are for values a = 3, b = 2, c = 1, with random // noise added to the output so it's not a perfect fit. const xs: Scalar[] = [ - track(Scalar.new(0)), - track(Scalar.new(1)), - track(Scalar.new(2)), - track(Scalar.new(3)) + Scalar.new(0), + Scalar.new(1), + Scalar.new(2), + Scalar.new(3) ]; const ys: Scalar[] = [ - track(Scalar.new(1.1)), - track(Scalar.new(5.9)), - track(Scalar.new(16.8)), - track(Scalar.new(33.9)) + Scalar.new(1.1), + Scalar.new(5.9), + Scalar.new(16.8), + Scalar.new(33.9) ]; // When training, it's important to shuffle your data! const shuffledInputProviderBuilder = @@ -311,7 +311,7 @@ await math.scope(async (keep, track) => { } // Now print the value from the trained model for x = 4, should be ~57.0. - result = session.eval(y, [{tensor: x, data: track(Scalar.new(4))}]); + result = session.eval(y, [{tensor: x, data: Scalar.new(4)}]); console.log('result should be ~57.0:'); console.log(result.shape); console.log(await result.data()); diff --git a/docs/tutorials/performance.md b/docs/tutorials/performance.md index 1bb68ec6c4..6e5f4527c5 100644 --- a/docs/tutorials/performance.md +++ b/docs/tutorials/performance.md @@ -79,33 +79,19 @@ closure as shown in the example below. The results of math operations in this scope will get disposed at the end of the scope, unless they are the value returned in the scope. -Two functions are passed to the function closure, `keep()` and `track()`. +A function is passed to the function closure, `keep()`. `keep()` ensures that the NDArray passed to keep will not be cleaned up automatically when the scope ends. -`track()` tracks any NDArrays that you may construct directly inside of a -scope. When the scope ends, any manually tracked `NDArray`s will get -cleaned up. Results of all `math.method()` functions, as well as results of -many other core library functions are automatically cleaned up, so you don't -have to manually track them. - ```ts -const math = new NDArrayMathGPU(); +const math = ENV.math; let output; -math.scope((keep, track) => { - // CORRECT: By default, math wont track NDArrays that are constructed - // directly. You can call track() on the NDArray for it to get tracked and - // cleaned up at the end of the scope. - const a = track(Scalar.new(2)); - - // INCORRECT: This is a texture leak!! - // math doesn't know about b, so it can't track it. When the scope ends, the - // GPU-resident NDArray will not get cleaned up, even though b goes out of - // scope. Make sure you call track() on NDArrays you create. - const b = Scalar.new(2); +math.scope(keep => { + // CORRECT: By default, math tracks all NDArrays that are constructed. + const a = Scalar.new(2); // CORRECT: By default, math tracks all outputs of math functions. const c = math.neg(math.exp(a)); @@ -113,7 +99,7 @@ math.scope((keep, track) => { // CORRECT: d is tracked by the parent scope. const d = math.scope(() => { // CORRECT: e will get cleaned up when this inner scope ends. - const e = track(Scalar.new(3)); + const e = Scalar.new(3); // CORRECT: The result of this math function is tracked. Since it is the // return value of this scope, it will not get cleaned up with this inner diff --git a/src/graph/session_util_test.ts b/src/graph/session_util_test.ts index acb82a916d..2b0311f498 100644 --- a/src/graph/session_util_test.ts +++ b/src/graph/session_util_test.ts @@ -183,7 +183,7 @@ describe('loadInputsFromFeedDictionaryToTensorArrayMap', () => { // right value. return ndarray; }, - // No need to dispose when not using NDArrayMathGPU. + // No need to dispose when not using the webgl backend. disposeCopy() {} }; const fd = new FeedDictionary([{tensor, data: provider}]); diff --git a/starter/es6/main.js b/starter/es6/main.js index 8dbcc1b99f..bb0668cb69 100644 --- a/starter/es6/main.js +++ b/starter/es6/main.js @@ -1,9 +1,9 @@ import 'babel-polyfill'; -import {Array1D, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, ENV, Scalar} from 'deeplearn'; /** Runs the example. */ async function runExample() { - const math = new NDArrayMathGPU(); + const math = ENV.math; const a = Array1D.new([1, 2, 3]); const b = Scalar.new(2); diff --git a/starter/es6/package.json b/starter/es6/package.json index 211bbc8229..b8ccdebd7c 100644 --- a/starter/es6/package.json +++ b/starter/es6/package.json @@ -4,7 +4,7 @@ "description": "Starter project for using deeplearn.js with es6", "dependencies": { "babel-polyfill": "~6.26.0", - "deeplearn": "~0.3.3" + "deeplearn": "0.3.15" }, "devDependencies": { "babel-plugin-syntax-async-functions": "~6.13.0", diff --git a/starter/es6/yarn.lock b/starter/es6/yarn.lock index c138675080..55ca02219e 100644 --- a/starter/es6/yarn.lock +++ b/starter/es6/yarn.lock @@ -1036,9 +1036,9 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" -deeplearn@~0.3.3: - version "0.3.11" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.11.tgz#b851281158da16d6745f490dc6ae8c9db851bc03" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" diff --git a/starter/typescript/main.ts b/starter/typescript/main.ts index cec37399ad..adb600ad29 100644 --- a/starter/typescript/main.ts +++ b/starter/typescript/main.ts @@ -1,7 +1,7 @@ -import {Array1D, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, ENV, Scalar} from 'deeplearn'; async function runExample() { - const math = new NDArrayMathGPU(); + const math = ENV.math; const a = Array1D.new([1, 2, 3]); const b = Scalar.new(2); diff --git a/starter/typescript/package.json b/starter/typescript/package.json index 611aa3522d..aca6255d29 100644 --- a/starter/typescript/package.json +++ b/starter/typescript/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Starter project for using deeplearn.js with TypeScript", "dependencies": { - "deeplearn": "~0.3.3" + "deeplearn": "0.3.15" }, "devDependencies": { "mkdirp": "~0.5.1", diff --git a/starter/typescript/yarn.lock b/starter/typescript/yarn.lock index 76ee3e67ea..fc3a874639 100644 --- a/starter/typescript/yarn.lock +++ b/starter/typescript/yarn.lock @@ -526,9 +526,9 @@ deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" -deeplearn@~0.3.3: - version "0.3.11" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.11.tgz#b851281158da16d6745f490dc6ae8c9db851bc03" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" From 54518c52e7520bc0bb5440840cd8d727ddf192db Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Fri, 22 Dec 2017 20:20:44 -0500 Subject: [PATCH 5/9] save --- .../latent-space-explorer/components/Tray.vue | 2 - demos/latent-space-explorer/utils/Utils.ts | 49 ---- models/squeezenet/demo.html | 5 +- models/squeezenet/package.json | 13 +- models/squeezenet/squeezenet.ts | 42 ++-- models/squeezenet/yarn.lock | 210 +++++++++++++++++- 6 files changed, 238 insertions(+), 83 deletions(-) delete mode 100644 demos/latent-space-explorer/utils/Utils.ts diff --git a/demos/latent-space-explorer/components/Tray.vue b/demos/latent-space-explorer/components/Tray.vue index 75a6c86f47..8505baddb0 100644 --- a/demos/latent-space-explorer/components/Tray.vue +++ b/demos/latent-space-explorer/components/Tray.vue @@ -42,8 +42,6 @@ limitations under the License. - +
@@ -16,7 +15,7 @@ if (dl == null) { await new Promise(resolve => setTimeout(resolve, 1000)); } - const math = new dl.NDArrayMathGPU(); + const math = dl.ENV.math; const squeezeNet = new squeezenet.SqueezeNet(math); await squeezeNet.load(); diff --git a/models/squeezenet/package.json b/models/squeezenet/package.json index 4a24d14f0d..1e3e8fbf4b 100644 --- a/models/squeezenet/package.json +++ b/models/squeezenet/package.json @@ -6,7 +6,7 @@ "unpkg": "dist/bundle.js", "types": "dist/index.d.ts", "peerDependencies": { - "deeplearn": "~0.3.13" + "deeplearn": "0.3.15" }, "repository": { "type": "git", @@ -14,7 +14,8 @@ }, "devDependencies": { "browserify": "~14.4.0", - "deeplearn": "0.3.13", + "browserify-shim": "~3.8.14", + "deeplearn": "0.3.15", "mkdirp": "~0.5.1", "tsify": "~3.0.3", "tslint": "~5.8.0", @@ -24,9 +25,15 @@ }, "scripts": { "prep": "yarn && mkdirp dist", - "build": "tsc --sourceMap false && browserify --standalone squeezenet squeezenet.ts -p [tsify] -o dist/bundle.js", + "build": "tsc --sourceMap false && browserify --standalone squeezenet index.ts -p [tsify] -o dist/bundle.js", "lint": "tslint -p . -t verbose", "publish-npm": "yarn build && yarn publish" }, + "browserify-shim": { + "deeplearn": "global:dl" + }, + "browserify": { + "transform": ["browserify-shim"] + }, "license": "Apache-2.0" } diff --git a/models/squeezenet/squeezenet.ts b/models/squeezenet/squeezenet.ts index 03c7640d07..021b9679b4 100644 --- a/models/squeezenet/squeezenet.ts +++ b/models/squeezenet/squeezenet.ts @@ -15,8 +15,7 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array1D, Array3D, Array4D, CheckpointLoader, initializeGPU, Model, NDArray, NDArrayMath, NDArrayMathCPU, NDArrayMathGPU} from 'deeplearn'; - +import {Array1D, Array3D, Array4D, CheckpointLoader, Model, NDArray, NDArrayMath} from 'deeplearn'; import {IMAGENET_CLASSES} from './imagenet_classes'; const GOOGLE_CLOUD_STORAGE_DIR = @@ -30,15 +29,7 @@ export class SqueezeNet implements Model { private preprocessOffset = Array1D.new([103.939, 116.779, 123.68]); - constructor(private math: NDArrayMath) { - // TODO(nsthorat): This awful hack is because we need to share the global - // GPGPU between deeplearn loaded from standalone as well as the internal - // deeplearn that gets compiled as part of this model. Remove this once we - // decouple NDArray from storage mechanism. - initializeGPU( - (this.math as NDArrayMathGPU).getGPGPUContext(), - (this.math as NDArrayMathGPU).getTextureManager()); - } + constructor(private math: NDArrayMath) {} /** * Loads necessary variables for SqueezeNet. @@ -184,10 +175,10 @@ export class SqueezeNet implements Model { */ async getTopKClasses(logits: Array1D, topK: number): Promise<{[className: string]: number}> { - const predictions = this.math.softmax(logits); - const topk = new NDArrayMathCPU().topK(predictions, topK); - const topkIndices = await topk.indices.data(); - const topkValues = await topk.values.data(); + const predictions = this.math.softmax(logits).asType('float32'); + const topk = this.topK(await predictions.data(), topK); + const topkIndices = topk.indices; + const topkValues = topk.values; const topClassesToProbability: {[className: string]: number} = {}; for (let i = 0; i < topkIndices.length; i++) { @@ -196,10 +187,29 @@ export class SqueezeNet implements Model { return topClassesToProbability; } + private topK(values: Float32Array, k: number): + {values: Float32Array, indices: Int32Array} { + const valuesAndIndices: Array<{value: number, index: number}> = []; + for (let i = 0; i < values.length; i++) { + valuesAndIndices.push({value: values[i], index: i}); + } + valuesAndIndices.sort((a, b) => { + return b.value - a.value; + }); +  + const topkValues = new Float32Array(k); + const topkIndices = new Int32Array(k); + for (let i = 0; i < k; i++) { + topkValues[i] = valuesAndIndices[i].value; + topkIndices[i] = valuesAndIndices[i].index; + } + return {values: topkValues, indices: topkIndices}; + } + dispose() { this.preprocessOffset.dispose(); for (const varName in this.variables) { this.variables[varName].dispose(); } } -} \ No newline at end of file +} diff --git a/models/squeezenet/yarn.lock b/models/squeezenet/yarn.lock index 2b1d2a7e56..3b86e506db 100644 --- a/models/squeezenet/yarn.lock +++ b/models/squeezenet/yarn.lock @@ -13,6 +13,14 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +accessory@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/accessory/-/accessory-1.1.0.tgz#7833e9839a32ded76d26021f36a41707a520f593" + dependencies: + ap "~0.2.0" + balanced-match "~0.2.0" + dot-parts "~1.0.0" + acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -28,6 +36,10 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -53,6 +65,10 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +ap@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ap/-/ap-0.2.0.tgz#ae0942600b29912f0d2b14ec60c45e8f330b6110" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -150,6 +166,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +balanced-match@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.2.1.tgz#7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7" + base64-js@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" @@ -249,6 +269,16 @@ browserify-rsa@^4.0.0: bn.js "^4.1.0" randombytes "^2.0.1" +browserify-shim@^3.8.14: + version "3.8.14" + resolved "https://registry.yarnpkg.com/browserify-shim/-/browserify-shim-3.8.14.tgz#bf1057026932d3253c75ef7dd714f3b877edec6b" + dependencies: + exposify "~0.5.0" + mothership "~0.2.0" + rename-function-calls "~0.1.0" + resolve "~0.6.1" + through "~2.3.4" + browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" @@ -588,9 +618,9 @@ deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" -deeplearn@~0.3.11: - version "0.3.13" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.13.tgz#12033ab21581fb277dede662250bd58d86457d44" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" @@ -633,6 +663,20 @@ detective@^4.0.0: acorn "^5.2.1" defined "^1.0.0" +detective@^4.5.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +detective@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-3.1.0.tgz#77782444ab752b88ca1be2e9d0a0395f1da25eed" + dependencies: + escodegen "~1.1.0" + esprima-fb "3001.1.0-dev-harmony-fb" + diff@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" @@ -649,6 +693,10 @@ domain-browser@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" +dot-parts@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dot-parts/-/dot-parts-1.0.1.tgz#884bd7bcfc3082ffad2fe5db53e494d8f3e0743f" + duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -679,14 +727,40 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.1.0.tgz#c663923f6e20aad48d0c0fa49f31c6d4f49360cf" + dependencies: + esprima "~1.0.4" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.30" + +esprima-fb@3001.1.0-dev-harmony-fb: + version "3001.1.0-dev-harmony-fb" + resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz#b77d37abcd38ea0b77426bb8bc2922ce6b426411" + +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + events@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -710,6 +784,16 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +exposify@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/exposify/-/exposify-0.5.0.tgz#f92d0094c265b3f553e1fa456a03a1883d1059cc" + dependencies: + globo "~1.1.0" + map-obj "~1.0.1" + replace-requires "~1.0.3" + through2 "~0.4.0" + transformify "~0.1.1" + extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -742,6 +826,10 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +find-parent-dir@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -839,6 +927,14 @@ glob@^7.0.5, glob@^7.1.0, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +globo@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/globo/-/globo-1.1.0.tgz#0d26098955dea422eb2001b104898b0a101caaf3" + dependencies: + accessory "~1.1.0" + is-defined "~1.0.0" + ternary "~1.0.0" + graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -864,6 +960,12 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-require@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/has-require/-/has-require-1.2.2.tgz#921675ab130dbd9768fc8da8f1a8e242dfa41774" + dependencies: + escape-string-regexp "^1.0.3" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -991,6 +1093,10 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-defined/-/is-defined-1.0.0.tgz#1f07ca67d571f594c4b14415a45f7bef88f92bf5" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -1049,14 +1155,14 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +isarray@0.0.1, isarray@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isarray@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -1142,6 +1248,10 @@ lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" +map-obj@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + md5.js@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" @@ -1232,6 +1342,12 @@ module-deps@^4.0.8: through2 "^2.0.0" xtend "^4.0.0" +mothership@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/mothership/-/mothership-0.2.0.tgz#93d48a2fbc3e50e2a5fc8ed586f5bc44c65f9a99" + dependencies: + find-parent-dir "~0.3.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1290,6 +1406,10 @@ object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1371,6 +1491,10 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +patch-text@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/patch-text/-/patch-text-1.0.2.tgz#4bf36e65e51733d6e98f0cf62e09034daa0348ac" + path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -1490,6 +1614,24 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -1520,6 +1662,12 @@ remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" +rename-function-calls@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/rename-function-calls/-/rename-function-calls-0.1.1.tgz#7f83369c007a3007f6abe3033ccf81686a108e01" + dependencies: + detective "~3.1.0" + repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" @@ -1528,6 +1676,15 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +replace-requires@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/replace-requires/-/replace-requires-1.0.4.tgz#014b7330b6b9e2557b71043b66fb02660c3bf667" + dependencies: + detective "^4.5.0" + has-require "~1.2.1" + patch-text "~1.0.2" + xtend "~4.0.0" + request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -1565,6 +1722,10 @@ resolve@^1.1.3, resolve@^1.1.4, resolve@^1.3.2: dependencies: path-parse "^1.0.5" +resolve@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" @@ -1631,6 +1792,12 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +source-map@~0.1.30: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -1761,6 +1928,10 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" +ternary@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ternary/-/ternary-1.0.0.tgz#45702725608c9499d46a9610e9b0e49ff26f789e" + through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -1768,7 +1939,14 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" -"through@>=2.2.7 <3": +through2@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +"through@>=2.2.7 <3", through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -1788,6 +1966,12 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +transformify@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/transformify/-/transformify-0.1.2.tgz#9a4f42a154433dd727b80575428a3c9e5489ebf1" + dependencies: + readable-stream "~1.1.9" + tsconfig@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-5.0.3.tgz#5f4278e701800967a8fc383fd19648878f2a6e3a" @@ -1925,6 +2109,12 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -xtend@^4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + dependencies: + object-keys "~0.4.0" From 500dc71bc1a082e94766a92c2cf580156dd8d726 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Fri, 22 Dec 2017 21:36:56 -0500 Subject: [PATCH 6/9] save --- models/knn_image_classifier/demo.html | 2 + .../knn_image_classifier.ts | 56 +++-- models/knn_image_classifier/package.json | 13 +- models/knn_image_classifier/yarn.lock | 214 +++++++++++++++++- models/squeezenet/package.json | 5 +- models/squeezenet/squeezenet.ts | 2 +- 6 files changed, 245 insertions(+), 47 deletions(-) create mode 100644 models/knn_image_classifier/demo.html diff --git a/models/knn_image_classifier/demo.html b/models/knn_image_classifier/demo.html new file mode 100644 index 0000000000..d4b688ad8d --- /dev/null +++ b/models/knn_image_classifier/demo.html @@ -0,0 +1,2 @@ + + diff --git a/models/knn_image_classifier/knn_image_classifier.ts b/models/knn_image_classifier/knn_image_classifier.ts index ccd66b63b1..2f63872385 100644 --- a/models/knn_image_classifier/knn_image_classifier.ts +++ b/models/knn_image_classifier/knn_image_classifier.ts @@ -15,7 +15,7 @@ * ============================================================================= */ // tslint:disable-next-line:max-line-length -import {Array1D, Array2D, Array3D, initializeGPU, Model, NDArrayMath, NDArrayMathCPU, NDArrayMathGPU, Scalar} from 'deeplearn'; +import {Array1D, Array2D, Array3D, Model, NDArrayMath, Scalar} from 'deeplearn'; import {SqueezeNet} from 'deeplearn-squeezenet'; export class KNNImageClassifier implements Model { @@ -29,8 +29,6 @@ export class KNNImageClassifier implements Model { private classExampleCount: number[] = []; private varsLoaded = false; - private mathCPU: NDArrayMathCPU; - private squashLogitsDenominator = Scalar.new(300); /** @@ -43,16 +41,6 @@ export class KNNImageClassifier implements Model { constructor( private numClasses: number, private k: number, private math: NDArrayMath) { - // TODO(nsthorat): This awful hack is because we need to share the global - // GPGPU between deeplearn loaded from standalone as well as the internal - // deeplearn that gets compiled as part of this model. Remove this once we - // decouple NDArray from storage mechanism. - initializeGPU( - (this.math as NDArrayMathGPU).getGPGPUContext(), - (this.math as NDArrayMathGPU).getTextureManager()); - - this.mathCPU = new NDArrayMathCPU(); - for (let i = 0; i < this.numClasses; i++) { this.classLogitsMatrices.push(null); this.classExampleCount.push(0); @@ -187,24 +175,17 @@ export class KNNImageClassifier implements Model { throw new Error('Cannot predict until vars have been loaded.'); } - const topKIndices = await this.math.scope(async (keep) => { - const knn = this.predict(image); - // mathCPU downloads the values, so we should wait until the GPU isdone - // so we don't block the UI thread. - await knn.data(); - - const numExamples = this.getNumExamples(); - - const kVal = Math.min(this.k, numExamples); - const topK = this.mathCPU.topK(knn, kVal); - return topK.indices; - }); + const knn = this.predict(image).asType('float32'); + const numExamples = this.getNumExamples(); + const kVal = Math.min(this.k, numExamples); + const topK = this.topK(await knn.data(), kVal); + knn.dispose(); + const topKIndices = topK.indices; if (topKIndices == null) { return {classIndex: imageClass, confidences}; } - const indices = topKIndices.dataSync(); const indicesForClasses = []; const topKCountsForClasses = []; for (let i = 0; i < this.numClasses; i++) { @@ -216,10 +197,10 @@ export class KNNImageClassifier implements Model { indicesForClasses.push(num); } - for (let i = 0; i < indices.length; i++) { + for (let i = 0; i < topKIndices.length; i++) { for (let classForEntry = 0; classForEntry < indicesForClasses.length; classForEntry++) { - if (indices[i] < indicesForClasses[classForEntry]) { + if (topKIndices[i] < indicesForClasses[classForEntry]) { topKCountsForClasses[classForEntry]++; break; } @@ -227,7 +208,6 @@ export class KNNImageClassifier implements Model { } let topConfidence = 0; - const kVal = Math.min(this.k, this.getNumExamples()); for (let i = 0; i < this.numClasses; i++) { const probability = topKCountsForClasses[i] / kVal; if (probability > topConfidence) { @@ -292,6 +272,24 @@ export class KNNImageClassifier implements Model { return total; } + private topK(values: Float32Array, k: number): + {values: Float32Array, indices: Int32Array} { + const valuesAndIndices: Array<{value: number, index: number}> = []; + for (let i = 0; i < values.length; i++) { + valuesAndIndices.push({value: values[i], index: i}); + } + valuesAndIndices.sort((a, b) => { + return b.value - a.value; + }); + const topkValues = new Float32Array(k); + const topkIndices = new Int32Array(k); + for (let i = 0; i < k; i++) { + topkValues[i] = valuesAndIndices[i].value; + topkIndices[i] = valuesAndIndices[i].index; + } + return {values: topkValues, indices: topkIndices}; + } + dispose() { this.squeezeNet.dispose(); this.clearTrainLogitsMatrix(); diff --git a/models/knn_image_classifier/package.json b/models/knn_image_classifier/package.json index 535312edf0..1836f82c88 100644 --- a/models/knn_image_classifier/package.json +++ b/models/knn_image_classifier/package.json @@ -6,7 +6,7 @@ "unpkg": "dist/bundle.js", "types": "dist/index.d.ts", "peerDependencies": { - "deeplearn": "~0.3.13" + "deeplearn": "0.3.15" }, "dependencies": { "deeplearn-squeezenet": "~0.1.6" @@ -17,7 +17,8 @@ }, "devDependencies": { "browserify": "~14.4.0", - "deeplearn": "0.3.13", + "browserify-shim": "~3.8.14", + "deeplearn": "0.3.15", "mkdirp": "~0.5.1", "tsify": "~3.0.3", "tslint": "~5.8.0", @@ -27,9 +28,15 @@ }, "scripts": { "prep": "yarn && mkdirp dist", - "build": "tsc --sourceMap false && browserify --standalone knn_image_classifier knn_image_classifier.ts -p [tsify] -o dist/bundle.js", + "build": "tsc --sourceMap false && browserify -g browserify-shim --standalone knn_image_classifier index.ts -p [tsify] -o dist/bundle.js", "lint": "tslint -p . -t verbose", "publish-npm": "yarn build && yarn publish" }, + "browserify-shim": { + "deeplearn": "global:dl" + }, + "browserify": { + "global-transform": ["browserify-shim"] + }, "license": "Apache-2.0" } diff --git a/models/knn_image_classifier/yarn.lock b/models/knn_image_classifier/yarn.lock index e93b7f4874..6422d29bba 100644 --- a/models/knn_image_classifier/yarn.lock +++ b/models/knn_image_classifier/yarn.lock @@ -13,10 +13,22 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +accessory@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/accessory/-/accessory-1.1.0.tgz#7833e9839a32ded76d26021f36a41707a520f593" + dependencies: + ap "~0.2.0" + balanced-match "~0.2.0" + dot-parts "~1.0.0" + acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" +acorn@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" + ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -24,6 +36,10 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -49,6 +65,10 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +ap@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ap/-/ap-0.2.0.tgz#ae0942600b29912f0d2b14ec60c45e8f330b6110" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -146,6 +166,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +balanced-match@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.2.1.tgz#7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7" + base64-js@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" @@ -245,6 +269,16 @@ browserify-rsa@^4.0.0: bn.js "^4.1.0" randombytes "^2.0.1" +browserify-shim@~3.8.14: + version "3.8.14" + resolved "https://registry.yarnpkg.com/browserify-shim/-/browserify-shim-3.8.14.tgz#bf1057026932d3253c75ef7dd714f3b877edec6b" + dependencies: + exposify "~0.5.0" + mothership "~0.2.0" + rename-function-calls "~0.1.0" + resolve "~0.6.1" + through "~2.3.4" + browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" @@ -588,9 +622,9 @@ deeplearn-squeezenet@~0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/deeplearn-squeezenet/-/deeplearn-squeezenet-0.1.6.tgz#f73c25d8627de514d72425471a3d69436c754ecf" -deeplearn@~0.3.13: - version "0.3.13" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.13.tgz#12033ab21581fb277dede662250bd58d86457d44" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" @@ -633,6 +667,20 @@ detective@^4.0.0: acorn "^4.0.3" defined "^1.0.0" +detective@^4.5.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +detective@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-3.1.0.tgz#77782444ab752b88ca1be2e9d0a0395f1da25eed" + dependencies: + escodegen "~1.1.0" + esprima-fb "3001.1.0-dev-harmony-fb" + diff@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" @@ -649,6 +697,10 @@ domain-browser@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" +dot-parts@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dot-parts/-/dot-parts-1.0.1.tgz#884bd7bcfc3082ffad2fe5db53e494d8f3e0743f" + duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -679,14 +731,40 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.1.0.tgz#c663923f6e20aad48d0c0fa49f31c6d4f49360cf" + dependencies: + esprima "~1.0.4" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.30" + +esprima-fb@3001.1.0-dev-harmony-fb: + version "3001.1.0-dev-harmony-fb" + resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz#b77d37abcd38ea0b77426bb8bc2922ce6b426411" + +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + events@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -710,6 +788,16 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +exposify@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/exposify/-/exposify-0.5.0.tgz#f92d0094c265b3f553e1fa456a03a1883d1059cc" + dependencies: + globo "~1.1.0" + map-obj "~1.0.1" + replace-requires "~1.0.3" + through2 "~0.4.0" + transformify "~0.1.1" + extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -738,6 +826,10 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +find-parent-dir@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -835,6 +927,14 @@ glob@^7.0.5, glob@^7.1.0, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +globo@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/globo/-/globo-1.1.0.tgz#0d26098955dea422eb2001b104898b0a101caaf3" + dependencies: + accessory "~1.1.0" + is-defined "~1.0.0" + ternary "~1.0.0" + graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -860,6 +960,12 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-require@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/has-require/-/has-require-1.2.2.tgz#921675ab130dbd9768fc8da8f1a8e242dfa41774" + dependencies: + escape-string-regexp "^1.0.3" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -987,6 +1093,10 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-defined/-/is-defined-1.0.0.tgz#1f07ca67d571f594c4b14415a45f7bef88f92bf5" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -1045,14 +1155,14 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +isarray@0.0.1, isarray@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isarray@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -1138,6 +1248,10 @@ lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" +map-obj@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + md5.js@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" @@ -1228,6 +1342,12 @@ module-deps@^4.0.8: through2 "^2.0.0" xtend "^4.0.0" +mothership@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/mothership/-/mothership-0.2.0.tgz#93d48a2fbc3e50e2a5fc8ed586f5bc44c65f9a99" + dependencies: + find-parent-dir "~0.3.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1286,6 +1406,10 @@ object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1367,6 +1491,10 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +patch-text@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/patch-text/-/patch-text-1.0.2.tgz#4bf36e65e51733d6e98f0cf62e09034daa0348ac" + path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -1486,6 +1614,24 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -1516,6 +1662,12 @@ remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" +rename-function-calls@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/rename-function-calls/-/rename-function-calls-0.1.1.tgz#7f83369c007a3007f6abe3033ccf81686a108e01" + dependencies: + detective "~3.1.0" + repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" @@ -1524,6 +1676,15 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +replace-requires@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/replace-requires/-/replace-requires-1.0.4.tgz#014b7330b6b9e2557b71043b66fb02660c3bf667" + dependencies: + detective "^4.5.0" + has-require "~1.2.1" + patch-text "~1.0.2" + xtend "~4.0.0" + request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -1561,6 +1722,10 @@ resolve@^1.1.3, resolve@^1.1.4, resolve@^1.3.2: dependencies: path-parse "^1.0.5" +resolve@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" @@ -1627,6 +1792,12 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +source-map@~0.1.30: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -1757,6 +1928,10 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" +ternary@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ternary/-/ternary-1.0.0.tgz#45702725608c9499d46a9610e9b0e49ff26f789e" + through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -1764,7 +1939,14 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" -"through@>=2.2.7 <3": +through2@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +"through@>=2.2.7 <3", through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -1784,6 +1966,12 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +transformify@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/transformify/-/transformify-0.1.2.tgz#9a4f42a154433dd727b80575428a3c9e5489ebf1" + dependencies: + readable-stream "~1.1.9" + tsconfig@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-5.0.3.tgz#5f4278e701800967a8fc383fd19648878f2a6e3a" @@ -1921,6 +2109,12 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -xtend@^4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + dependencies: + object-keys "~0.4.0" diff --git a/models/squeezenet/package.json b/models/squeezenet/package.json index 1e3e8fbf4b..cbfed5db2a 100644 --- a/models/squeezenet/package.json +++ b/models/squeezenet/package.json @@ -25,15 +25,12 @@ }, "scripts": { "prep": "yarn && mkdirp dist", - "build": "tsc --sourceMap false && browserify --standalone squeezenet index.ts -p [tsify] -o dist/bundle.js", + "build": "tsc --sourceMap false && browserify -g browserify-shim --standalone squeezenet index.ts -p [tsify] -o dist/bundle.js", "lint": "tslint -p . -t verbose", "publish-npm": "yarn build && yarn publish" }, "browserify-shim": { "deeplearn": "global:dl" }, - "browserify": { - "transform": ["browserify-shim"] - }, "license": "Apache-2.0" } diff --git a/models/squeezenet/squeezenet.ts b/models/squeezenet/squeezenet.ts index 021b9679b4..d0580f44a4 100644 --- a/models/squeezenet/squeezenet.ts +++ b/models/squeezenet/squeezenet.ts @@ -196,7 +196,7 @@ export class SqueezeNet implements Model { valuesAndIndices.sort((a, b) => { return b.value - a.value; }); -  + const topkValues = new Float32Array(k); const topkIndices = new Int32Array(k); for (let i = 0; i < k; i++) { From 21a5509c2bd12cecaea45e7d2cac1b27b5f2b678 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Sat, 23 Dec 2017 08:22:56 -0500 Subject: [PATCH 7/9] fix models --- models/knn_image_classifier/package.json | 6 +- models/knn_image_classifier/yarn.lock | 68 +------- models/mobilenet/demo.html | 5 +- models/mobilenet/mobilenet.ts | 174 ++++++++++--------- models/mobilenet/package.json | 16 +- models/mobilenet/yarn.lock | 212 +++++++++++++++++++++-- models/squeezenet/package.json | 2 +- models/squeezenet/yarn.lock | 70 +------- models/yolo_mobilenet/demo.html | 20 +-- models/yolo_mobilenet/mobilenet_utils.ts | 76 ++++---- models/yolo_mobilenet/package.json | 16 +- models/yolo_mobilenet/yarn.lock | 212 +++++++++++++++++++++-- models/yolo_mobilenet/yolo_mobilenet.ts | 175 +++++++++---------- 13 files changed, 661 insertions(+), 391 deletions(-) diff --git a/models/knn_image_classifier/package.json b/models/knn_image_classifier/package.json index 1836f82c88..4c54884037 100644 --- a/models/knn_image_classifier/package.json +++ b/models/knn_image_classifier/package.json @@ -16,7 +16,7 @@ "url": "https://github.com/PAIR-code/deeplearnjs.git" }, "devDependencies": { - "browserify": "~14.4.0", + "browserify": "~14.5.0", "browserify-shim": "~3.8.14", "deeplearn": "0.3.15", "mkdirp": "~0.5.1", @@ -36,7 +36,9 @@ "deeplearn": "global:dl" }, "browserify": { - "global-transform": ["browserify-shim"] + "global-transform": [ + "browserify-shim" + ] }, "license": "Apache-2.0" } diff --git a/models/knn_image_classifier/yarn.lock b/models/knn_image_classifier/yarn.lock index 6422d29bba..131697ec10 100644 --- a/models/knn_image_classifier/yarn.lock +++ b/models/knn_image_classifier/yarn.lock @@ -291,19 +291,13 @@ browserify-sign@^4.0.0: inherits "^2.0.1" parse-asn1 "^5.0.0" -browserify-zlib@~0.1.2: - version "0.1.4" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" - dependencies: - pako "~0.2.0" - browserify-zlib@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" dependencies: pako "~1.0.5" -browserify@^14.0.0: +browserify@^14.0.0, browserify@~14.5.0: version "14.5.0" resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" dependencies: @@ -355,58 +349,6 @@ browserify@^14.0.0: vm-browserify "~0.0.1" xtend "^4.0.0" -browserify@~14.4.0: - version "14.4.0" - resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.4.0.tgz#089a3463af58d0e48d8cd4070b3f74654d5abca9" - dependencies: - JSONStream "^1.0.3" - assert "^1.4.0" - browser-pack "^6.0.1" - browser-resolve "^1.11.0" - browserify-zlib "~0.1.2" - buffer "^5.0.2" - cached-path-relative "^1.0.0" - concat-stream "~1.5.1" - console-browserify "^1.1.0" - constants-browserify "~1.0.0" - crypto-browserify "^3.0.0" - defined "^1.0.0" - deps-sort "^2.0.0" - domain-browser "~1.1.0" - duplexer2 "~0.1.2" - events "~1.1.0" - glob "^7.1.0" - has "^1.0.0" - htmlescape "^1.1.0" - https-browserify "^1.0.0" - inherits "~2.0.1" - insert-module-globals "^7.0.0" - labeled-stream-splicer "^2.0.0" - module-deps "^4.0.8" - os-browserify "~0.1.1" - parents "^1.0.1" - path-browserify "~0.0.0" - process "~0.11.0" - punycode "^1.3.2" - querystring-es3 "~0.2.0" - read-only-stream "^2.0.0" - readable-stream "^2.0.2" - resolve "^1.1.4" - shasum "^1.0.0" - shell-quote "^1.6.1" - stream-browserify "^2.0.0" - stream-http "^2.0.0" - string_decoder "~1.0.0" - subarg "^1.0.0" - syntax-error "^1.1.1" - through2 "^2.0.0" - timers-browserify "^1.0.1" - tty-browserify "~0.0.0" - url "~0.11.0" - util "~0.10.1" - vm-browserify "~0.0.1" - xtend "^4.0.0" - buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1423,10 +1365,6 @@ once@^1.3.0, once@^1.3.3: dependencies: wrappy "1" -os-browserify@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" - os-browserify@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -1452,10 +1390,6 @@ outpipe@^1.1.0: dependencies: shell-quote "^1.4.2" -pako@~0.2.0: - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" diff --git a/models/mobilenet/demo.html b/models/mobilenet/demo.html index 9d3bd61cd6..c35a088dc1 100644 --- a/models/mobilenet/demo.html +++ b/models/mobilenet/demo.html @@ -1,6 +1,5 @@ - - +
@@ -12,7 +11,7 @@ resultElement.innerText = 'Loading mobilenet...'; - const math = new dl.NDArrayMathGPU(); + const math = dl.ENV.math; const mobileNet = new mobilenet.MobileNet(math); await mobileNet.load(); diff --git a/models/mobilenet/mobilenet.ts b/models/mobilenet/mobilenet.ts index f3aaa18a3f..52104fe945 100644 --- a/models/mobilenet/mobilenet.ts +++ b/models/mobilenet/mobilenet.ts @@ -14,36 +14,28 @@ * limitations under the License. * ============================================================================= */ -// tslint:disable-next-line:max-line-length -import {Array1D, Array3D, Array4D, CheckpointLoader, initializeGPU, Model, NDArray, NDArrayMathCPU, NDArrayMath, NDArrayMathGPU, Scalar} from 'deeplearn'; -import {IMAGENET_CLASSES} from './imagenet_classes'; +// tslint:disable-next-line:max-line-length +import {Array1D, Array3D, Array4D, CheckpointLoader, Model, NDArray, NDArrayMath, Scalar} from 'deeplearn'; +import {IMAGENET_CLASSES} from './imagenet_classes'; -const GOOGLE_CLOUD_STORAGE_DIR = +const GOOGLE_CLOUD_STORAGE_DIR = 'https://storage.googleapis.com/learnjs-data/checkpoint_zoo/'; - -export class MobileNet implements Model { + +export class MobileNet implements Model { private variables: {[varName: string]: NDArray}; // yolo variables - private PREPROCESS_DIVISOR = Scalar.new(255.0/2); - private ONE = Scalar.ONE; - - constructor(private math: NDArrayMath) { - // TODO(nsthorat): This awful hack is because we need to share the global - // GPGPU between deeplearn loaded from standalone as well as the internal - // deeplearn that gets compiled as part of this model. Remove this once we - // decouple NDArray from storage mechanism. - initializeGPU( - (this.math as NDArrayMathGPU).getGPGPUContext(), - (this.math as NDArrayMathGPU).getTextureManager()); - } + private PREPROCESS_DIVISOR = Scalar.new(255.0 / 2); + private ONE = Scalar.new(1); + + constructor(private math: NDArrayMath) {} /** * Loads necessary variables for MobileNet. */ async load(): Promise { - const checkpointLoader = new CheckpointLoader(GOOGLE_CLOUD_STORAGE_DIR + - 'mobilenet_v1_1.0_224/'); + const checkpointLoader = new CheckpointLoader( + GOOGLE_CLOUD_STORAGE_DIR + 'mobilenet_v1_1.0_224/'); this.variables = await checkpointLoader.getAllVariables(); } @@ -59,96 +51,91 @@ export class MobileNet implements Model { // Keep a map of named activations for rendering purposes. const netout = this.math.scope((keep) => { // Preprocess the input. - const preprocessedInput = this.math.subtract( - this.math.arrayDividedByScalar(input, - this.PREPROCESS_DIVISOR), this.ONE) as Array3D; + const preprocessedInput = + this.math.subtract( + this.math.arrayDividedByScalar(input, this.PREPROCESS_DIVISOR), + this.ONE) as Array3D; - const x1 = this.convBlock(preprocessedInput, [2, 2]); - const x2 = this.depthwiseConvBlock(x1, [1, 1], 1); + const x1 = this.convBlock(preprocessedInput, [2, 2]); + const x2 = this.depthwiseConvBlock(x1, [1, 1], 1); - const x3 = this.depthwiseConvBlock(x2, [2, 2], 2); - const x4 = this.depthwiseConvBlock(x3, [1, 1], 3); + const x3 = this.depthwiseConvBlock(x2, [2, 2], 2); + const x4 = this.depthwiseConvBlock(x3, [1, 1], 3); - const x5 = this.depthwiseConvBlock(x4, [2, 2], 4); - const x6 = this.depthwiseConvBlock(x5, [1, 1], 5); + const x5 = this.depthwiseConvBlock(x4, [2, 2], 4); + const x6 = this.depthwiseConvBlock(x5, [1, 1], 5); - const x7 = this.depthwiseConvBlock(x6, [2, 2], 6); - const x8 = this.depthwiseConvBlock(x7, [1, 1], 7); - const x9 = this.depthwiseConvBlock(x8, [1, 1], 8); - const x10 = this.depthwiseConvBlock(x9, [1, 1], 9); + const x7 = this.depthwiseConvBlock(x6, [2, 2], 6); + const x8 = this.depthwiseConvBlock(x7, [1, 1], 7); + const x9 = this.depthwiseConvBlock(x8, [1, 1], 8); + const x10 = this.depthwiseConvBlock(x9, [1, 1], 9); const x11 = this.depthwiseConvBlock(x10, [1, 1], 10); const x12 = this.depthwiseConvBlock(x11, [1, 1], 11); const x13 = this.depthwiseConvBlock(x12, [2, 2], 12); const x14 = this.depthwiseConvBlock(x13, [1, 1], 13); - const x15 = this.math.avgPool(x14, x14.shape[0], 1, 0); - const x16 = this.math.conv2d(x15, - this.variables['MobilenetV1/Logits/Conv2d_1c_1x1/weights'] as Array4D, - this.variables['MobilenetV1/Logits/Conv2d_1c_1x1/biases'] as Array1D, - 1, - 'same'); + const x15 = this.math.avgPool(x14, x14.shape[0], 1, 0); + const x16 = this.math.conv2d( + x15, + this.variables['MobilenetV1/Logits/Conv2d_1c_1x1/weights'] as Array4D, + this.variables['MobilenetV1/Logits/Conv2d_1c_1x1/biases'] as Array1D, + 1, 'same'); return x16.as1D(); }); return netout; - } + } - private convBlock(inputs: Array3D, strides: [number, number]) { + private convBlock(inputs: Array3D, strides: [number, number]) { const convPadding = 'MobilenetV1/Conv2d_0'; - const x1 = this.math.conv2d(inputs, - this.variables[convPadding + '/weights'] as Array4D, - null, // this convolutional layer does not use bias - strides, - 'same'); + const x1 = this.math.conv2d( + inputs, this.variables[convPadding + '/weights'] as Array4D, + null, // this convolutional layer does not use bias + strides, 'same'); - const x2 = this.math.batchNormalization3D(x1, - this.variables[convPadding + '/BatchNorm/moving_mean'] as Array1D, - this.variables[convPadding + '/BatchNorm/moving_variance'] as Array1D, - .001, - this.variables[convPadding + '/BatchNorm/gamma'] as Array1D, - this.variables[convPadding + '/BatchNorm/beta'] as Array1D); + const x2 = this.math.batchNormalization3D( + x1, this.variables[convPadding + '/BatchNorm/moving_mean'] as Array1D, + this.variables[convPadding + '/BatchNorm/moving_variance'] as Array1D, + .001, this.variables[convPadding + '/BatchNorm/gamma'] as Array1D, + this.variables[convPadding + '/BatchNorm/beta'] as Array1D); - return this.math.clip(x2, 0, 6); // simple implementation of Relu6 + return this.math.clip(x2, 0, 6); // simple implementation of Relu6 } - private depthwiseConvBlock(inputs: Array3D, - strides: [number, number], - blockID: number) { + private depthwiseConvBlock( + inputs: Array3D, strides: [number, number], blockID: number) { const dwPadding = 'MobilenetV1/Conv2d_' + String(blockID) + '_depthwise'; const pwPadding = 'MobilenetV1/Conv2d_' + String(blockID) + '_pointwise'; - const x1 = this.math.depthwiseConv2D(inputs, - this.variables[dwPadding + '/depthwise_weights'] as Array4D, - strides, - 'same') as Array3D; + const x1 = + this.math.depthwiseConv2D( + inputs, this.variables[dwPadding + '/depthwise_weights'] as Array4D, + strides, 'same') as Array3D; - const x2 = this.math.batchNormalization3D(x1, - this.variables[dwPadding + '/BatchNorm/moving_mean'] as Array1D, - this.variables[dwPadding + '/BatchNorm/moving_variance'] as Array1D, - .001, - this.variables[dwPadding + '/BatchNorm/gamma'] as Array1D, - this.variables[dwPadding + '/BatchNorm/beta'] as Array1D); + const x2 = this.math.batchNormalization3D( + x1, this.variables[dwPadding + '/BatchNorm/moving_mean'] as Array1D, + this.variables[dwPadding + '/BatchNorm/moving_variance'] as Array1D, + .001, this.variables[dwPadding + '/BatchNorm/gamma'] as Array1D, + this.variables[dwPadding + '/BatchNorm/beta'] as Array1D); const x3 = this.math.clip(x2, 0, 6); - const x4 = this.math.conv2d(x3, - this.variables[pwPadding + '/weights'] as Array4D, - null, // this convolutional layer does not use bias - [1, 1], - 'same'); + const x4 = this.math.conv2d( + x3, this.variables[pwPadding + '/weights'] as Array4D, + null, // this convolutional layer does not use bias + [1, 1], 'same'); - const x5 = this.math.batchNormalization3D(x4, - this.variables[pwPadding + '/BatchNorm/moving_mean'] as Array1D, - this.variables[pwPadding + '/BatchNorm/moving_variance'] as Array1D, - .001, - this.variables[pwPadding + '/BatchNorm/gamma'] as Array1D, - this.variables[pwPadding + '/BatchNorm/beta'] as Array1D); + const x5 = this.math.batchNormalization3D( + x4, this.variables[pwPadding + '/BatchNorm/moving_mean'] as Array1D, + this.variables[pwPadding + '/BatchNorm/moving_variance'] as Array1D, + .001, this.variables[pwPadding + '/BatchNorm/gamma'] as Array1D, + this.variables[pwPadding + '/BatchNorm/beta'] as Array1D); return this.math.clip(x5, 0, 6); - } + } /** * Get the topK classes for pre-softmax logits. Returns a map of className @@ -159,21 +146,40 @@ export class MobileNet implements Model { */ async getTopKClasses(logits: Array1D, topK: number): Promise<{[className: string]: number}> { - const predictions = this.math.softmax(logits); - const topk = new NDArrayMathCPU().topK(predictions, topK); - const topkIndices = await topk.indices.data(); - const topkValues = await topk.values.data(); + const predictions = this.math.softmax(logits).asType('float32'); + const topk = this.topK(await predictions.data(), topK); + const topkIndices = topk.indices; + const topkValues = topk.values; const topClassesToProbability: {[className: string]: number} = {}; for (let i = 0; i < topkIndices.length; i++) { topClassesToProbability[IMAGENET_CLASSES[topkIndices[i]]] = topkValues[i]; } return topClassesToProbability; - } + } + + private topK(values: Float32Array, k: number): + {values: Float32Array, indices: Int32Array} { + const valuesAndIndices: Array<{value: number, index: number}> = []; + for (let i = 0; i < values.length; i++) { + valuesAndIndices.push({value: values[i], index: i}); + } + valuesAndIndices.sort((a, b) => { + return b.value - a.value; + }); + + const topkValues = new Float32Array(k); + const topkIndices = new Int32Array(k); + for (let i = 0; i < k; i++) { + topkValues[i] = valuesAndIndices[i].value; + topkIndices[i] = valuesAndIndices[i].index; + } + return {values: topkValues, indices: topkIndices}; + } dispose() { for (const varName in this.variables) { this.variables[varName].dispose(); } } -} \ No newline at end of file +} diff --git a/models/mobilenet/package.json b/models/mobilenet/package.json index b6f6451cb5..834570191e 100644 --- a/models/mobilenet/package.json +++ b/models/mobilenet/package.json @@ -6,14 +6,16 @@ "unpkg": "dist/bundle.js", "types": "dist/index.d.ts", "peerDependencies": { - "deeplearn": "~0.3.11" + "deeplearn": "0.3.15" }, "repository": { "type": "git", "url": "https://github.com/PAIR-code/deeplearnjs.git" }, "devDependencies": { - "deeplearn": "0.3.13", + "browserify": "~14.5.0", + "browserify-shim": "~3.8.14", + "deeplearn": "0.3.15", "mkdirp": "~0.5.1", "tsify": "~3.0.3", "tslint": "~5.8.0", @@ -23,9 +25,17 @@ }, "scripts": { "prep": "yarn && mkdirp dist", - "build": "browserify --standalone mobilenet mobilenet.ts -p [tsify] -o dist/bundle.js", + "build": "browserify -g browserify-shim --standalone mobilenet index.ts -p [tsify] -o dist/bundle.js", "lint": "tslint -p . -t verbose", "publish-npm": "tsc --sourceMap false && yarn build && npm publish" }, + "browserify-shim": { + "deeplearn": "global:dl" + }, + "browserify": { + "global-transform": [ + "browserify-shim" + ] + }, "license": "Apache-2.0" } diff --git a/models/mobilenet/yarn.lock b/models/mobilenet/yarn.lock index 11adbb8d8f..f4c21dfa9a 100644 --- a/models/mobilenet/yarn.lock +++ b/models/mobilenet/yarn.lock @@ -13,6 +13,14 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +accessory@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/accessory/-/accessory-1.1.0.tgz#7833e9839a32ded76d26021f36a41707a520f593" + dependencies: + ap "~0.2.0" + balanced-match "~0.2.0" + dot-parts "~1.0.0" + acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -28,6 +36,10 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -53,6 +65,10 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +ap@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ap/-/ap-0.2.0.tgz#ae0942600b29912f0d2b14ec60c45e8f330b6110" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -150,6 +166,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +balanced-match@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.2.1.tgz#7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7" + base64-js@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" @@ -249,6 +269,16 @@ browserify-rsa@^4.0.0: bn.js "^4.1.0" randombytes "^2.0.1" +browserify-shim@~3.8.14: + version "3.8.14" + resolved "https://registry.yarnpkg.com/browserify-shim/-/browserify-shim-3.8.14.tgz#bf1057026932d3253c75ef7dd714f3b877edec6b" + dependencies: + exposify "~0.5.0" + mothership "~0.2.0" + rename-function-calls "~0.1.0" + resolve "~0.6.1" + through "~2.3.4" + browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" @@ -267,7 +297,7 @@ browserify-zlib@~0.2.0: dependencies: pako "~1.0.5" -browserify@^14.0.0: +browserify@^14.0.0, browserify@~14.5.0: version "14.5.0" resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" dependencies: @@ -530,9 +560,9 @@ deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" -deeplearn@~0.3.11: - version "0.3.13" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.13.tgz#12033ab21581fb277dede662250bd58d86457d44" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" @@ -575,6 +605,20 @@ detective@^4.0.0: acorn "^5.2.1" defined "^1.0.0" +detective@^4.5.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +detective@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-3.1.0.tgz#77782444ab752b88ca1be2e9d0a0395f1da25eed" + dependencies: + escodegen "~1.1.0" + esprima-fb "3001.1.0-dev-harmony-fb" + diff@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" @@ -591,6 +635,10 @@ domain-browser@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" +dot-parts@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dot-parts/-/dot-parts-1.0.1.tgz#884bd7bcfc3082ffad2fe5db53e494d8f3e0743f" + duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -621,14 +669,40 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.1.0.tgz#c663923f6e20aad48d0c0fa49f31c6d4f49360cf" + dependencies: + esprima "~1.0.4" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.30" + +esprima-fb@3001.1.0-dev-harmony-fb: + version "3001.1.0-dev-harmony-fb" + resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz#b77d37abcd38ea0b77426bb8bc2922ce6b426411" + +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + events@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -652,6 +726,16 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +exposify@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/exposify/-/exposify-0.5.0.tgz#f92d0094c265b3f553e1fa456a03a1883d1059cc" + dependencies: + globo "~1.1.0" + map-obj "~1.0.1" + replace-requires "~1.0.3" + through2 "~0.4.0" + transformify "~0.1.1" + extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -684,6 +768,10 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +find-parent-dir@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -781,6 +869,14 @@ glob@^7.0.5, glob@^7.1.0, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +globo@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/globo/-/globo-1.1.0.tgz#0d26098955dea422eb2001b104898b0a101caaf3" + dependencies: + accessory "~1.1.0" + is-defined "~1.0.0" + ternary "~1.0.0" + graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -806,6 +902,12 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-require@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/has-require/-/has-require-1.2.2.tgz#921675ab130dbd9768fc8da8f1a8e242dfa41774" + dependencies: + escape-string-regexp "^1.0.3" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -933,6 +1035,10 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-defined/-/is-defined-1.0.0.tgz#1f07ca67d571f594c4b14415a45f7bef88f92bf5" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -991,14 +1097,14 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +isarray@0.0.1, isarray@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isarray@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -1084,6 +1190,10 @@ lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" +map-obj@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + md5.js@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" @@ -1174,6 +1284,12 @@ module-deps@^4.0.8: through2 "^2.0.0" xtend "^4.0.0" +mothership@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/mothership/-/mothership-0.2.0.tgz#93d48a2fbc3e50e2a5fc8ed586f5bc44c65f9a99" + dependencies: + find-parent-dir "~0.3.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1232,6 +1348,10 @@ object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1305,6 +1425,10 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +patch-text@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/patch-text/-/patch-text-1.0.2.tgz#4bf36e65e51733d6e98f0cf62e09034daa0348ac" + path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -1424,6 +1548,24 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -1454,6 +1596,12 @@ remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" +rename-function-calls@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/rename-function-calls/-/rename-function-calls-0.1.1.tgz#7f83369c007a3007f6abe3033ccf81686a108e01" + dependencies: + detective "~3.1.0" + repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" @@ -1462,6 +1610,15 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +replace-requires@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/replace-requires/-/replace-requires-1.0.4.tgz#014b7330b6b9e2557b71043b66fb02660c3bf667" + dependencies: + detective "^4.5.0" + has-require "~1.2.1" + patch-text "~1.0.2" + xtend "~4.0.0" + request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -1499,6 +1656,10 @@ resolve@^1.1.3, resolve@^1.1.4, resolve@^1.3.2: dependencies: path-parse "^1.0.5" +resolve@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" @@ -1565,6 +1726,12 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +source-map@~0.1.30: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -1695,6 +1862,10 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" +ternary@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ternary/-/ternary-1.0.0.tgz#45702725608c9499d46a9610e9b0e49ff26f789e" + through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -1702,7 +1873,14 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" -"through@>=2.2.7 <3": +through2@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +"through@>=2.2.7 <3", through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -1722,6 +1900,12 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +transformify@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/transformify/-/transformify-0.1.2.tgz#9a4f42a154433dd727b80575428a3c9e5489ebf1" + dependencies: + readable-stream "~1.1.9" + tsconfig@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-5.0.3.tgz#5f4278e701800967a8fc383fd19648878f2a6e3a" @@ -1859,6 +2043,12 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -xtend@^4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + dependencies: + object-keys "~0.4.0" diff --git a/models/squeezenet/package.json b/models/squeezenet/package.json index cbfed5db2a..3e944c558d 100644 --- a/models/squeezenet/package.json +++ b/models/squeezenet/package.json @@ -13,7 +13,7 @@ "url": "https://github.com/PAIR-code/deeplearnjs.git" }, "devDependencies": { - "browserify": "~14.4.0", + "browserify": "~14.5.0", "browserify-shim": "~3.8.14", "deeplearn": "0.3.15", "mkdirp": "~0.5.1", diff --git a/models/squeezenet/yarn.lock b/models/squeezenet/yarn.lock index 3b86e506db..3c301c006d 100644 --- a/models/squeezenet/yarn.lock +++ b/models/squeezenet/yarn.lock @@ -269,7 +269,7 @@ browserify-rsa@^4.0.0: bn.js "^4.1.0" randombytes "^2.0.1" -browserify-shim@^3.8.14: +browserify-shim@~3.8.14: version "3.8.14" resolved "https://registry.yarnpkg.com/browserify-shim/-/browserify-shim-3.8.14.tgz#bf1057026932d3253c75ef7dd714f3b877edec6b" dependencies: @@ -291,19 +291,13 @@ browserify-sign@^4.0.0: inherits "^2.0.1" parse-asn1 "^5.0.0" -browserify-zlib@~0.1.2: - version "0.1.4" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" - dependencies: - pako "~0.2.0" - browserify-zlib@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" dependencies: pako "~1.0.5" -browserify@^14.0.0: +browserify@^14.0.0, browserify@~14.5.0: version "14.5.0" resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" dependencies: @@ -355,58 +349,6 @@ browserify@^14.0.0: vm-browserify "~0.0.1" xtend "^4.0.0" -browserify@~14.4.0: - version "14.4.0" - resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.4.0.tgz#089a3463af58d0e48d8cd4070b3f74654d5abca9" - dependencies: - JSONStream "^1.0.3" - assert "^1.4.0" - browser-pack "^6.0.1" - browser-resolve "^1.11.0" - browserify-zlib "~0.1.2" - buffer "^5.0.2" - cached-path-relative "^1.0.0" - concat-stream "~1.5.1" - console-browserify "^1.1.0" - constants-browserify "~1.0.0" - crypto-browserify "^3.0.0" - defined "^1.0.0" - deps-sort "^2.0.0" - domain-browser "~1.1.0" - duplexer2 "~0.1.2" - events "~1.1.0" - glob "^7.1.0" - has "^1.0.0" - htmlescape "^1.1.0" - https-browserify "^1.0.0" - inherits "~2.0.1" - insert-module-globals "^7.0.0" - labeled-stream-splicer "^2.0.0" - module-deps "^4.0.8" - os-browserify "~0.1.1" - parents "^1.0.1" - path-browserify "~0.0.0" - process "~0.11.0" - punycode "^1.3.2" - querystring-es3 "~0.2.0" - read-only-stream "^2.0.0" - readable-stream "^2.0.2" - resolve "^1.1.4" - shasum "^1.0.0" - shell-quote "^1.6.1" - stream-browserify "^2.0.0" - stream-http "^2.0.0" - string_decoder "~1.0.0" - subarg "^1.0.0" - syntax-error "^1.1.1" - through2 "^2.0.0" - timers-browserify "^1.0.1" - tty-browserify "~0.0.0" - url "~0.11.0" - util "~0.10.1" - vm-browserify "~0.0.1" - xtend "^4.0.0" - buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1423,10 +1365,6 @@ once@^1.3.0, once@^1.3.3: dependencies: wrappy "1" -os-browserify@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" - os-browserify@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -1452,10 +1390,6 @@ outpipe@^1.1.0: dependencies: shell-quote "^1.4.2" -pako@~0.2.0: - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" diff --git a/models/yolo_mobilenet/demo.html b/models/yolo_mobilenet/demo.html index 0f298f1816..5e1dce1281 100644 --- a/models/yolo_mobilenet/demo.html +++ b/models/yolo_mobilenet/demo.html @@ -1,22 +1,20 @@ + - - -
@@ -39,8 +37,8 @@ width = canvas.width; height = canvas.height; - const math = new dl.NDArrayMathGPU(); - const yoloMobileNet = new yolo_mobilenet.YoloMobileNetDetection(math); + const math = dl.ENV.math; + const yoloMobileNet = new yolo_mobilenet.YoloMobileNetDetection(math); resultElement.innerText = 'Downloading weights ...'; yoloMobileNet.load().then(loadImage); @@ -79,7 +77,7 @@ context.strokeStyle = box.getColor(); context.lineWidth = 5; context.rect(x,y,w,h); - context.stroke(); + context.stroke(); // draw the label and the probability const label = box.getLabel() + ' ' + box.getMaxProb().toFixed(2).toString(); @@ -90,13 +88,13 @@ context.fillStyle = box.getColor(); const textWidth = context.measureText(label).width; context.fillRect(x-2, y-24, textWidth, parseInt(font, 10)); - + context.fillStyle = 'rgb(255,255,255)'; - context.fillText(label, x-2, y-24); + context.fillText(label, x-2, y-24); } resultElement.innerText = 'Complete!, Inference time: ' + Math.round(inferenceTime) + 'ms' + - ', Post precessing time: ' + Math.round(postProcessingTime) + 'ms'; + ', Post precessing time: ' + Math.round(postProcessingTime) + 'ms'; } diff --git a/models/yolo_mobilenet/mobilenet_utils.ts b/models/yolo_mobilenet/mobilenet_utils.ts index 4525f7a84d..4147599e94 100644 --- a/models/yolo_mobilenet/mobilenet_utils.ts +++ b/models/yolo_mobilenet/mobilenet_utils.ts @@ -1,10 +1,27 @@ +/** + * @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 class BoundingBox { - public x : number; - public y : number; - public w : number; - public h : number; - public c : number; - public probs : Float32Array; + public x: number; + public y: number; + public w: number; + public h: number; + public c: number; + public probs: Float32Array; private maxProb = -1; private maxIndx = -1; @@ -12,12 +29,9 @@ export class BoundingBox { public static LABELS = ['raccoon']; public static COLORS = ['rgb(43,206,72)']; - constructor(x: number, - y: number, - w: number, - h: number, - conf: number, - probs: Float32Array) { + constructor( + x: number, y: number, w: number, h: number, conf: number, + probs: Float32Array) { this.x = x; this.y = y; this.w = w; @@ -27,52 +41,50 @@ export class BoundingBox { this.probs = probs; } - public getMaxProb() : number { + public getMaxProb(): number { if (this.maxProb === -1) { - this.maxProb = this.probs.reduce((a,b) => Math.max(a,b)); + this.maxProb = this.probs.reduce((a, b) => Math.max(a, b)); } return this.maxProb; } - public getLabel() : string { + public getLabel(): string { if (this.maxIndx === -1) { this.maxIndx = this.probs.indexOf(this.getMaxProb()); } - + return BoundingBox.LABELS[this.maxIndx]; } - public getColor() : string { + public getColor(): string { if (this.maxIndx === -1) { this.maxIndx = this.probs.indexOf(this.getMaxProb()); } - + return BoundingBox.COLORS[this.maxIndx]; } public iou(box: BoundingBox): number { const intersection = this.intersect(box); - const union = this.w*this.h + box.w*box.h - intersection; + const union = this.w * this.h + box.w * box.h - intersection; - return intersection/union; + return intersection / union; } private intersect(box: BoundingBox): number { - const width = this.overlap([this.x-this.w/2, - this.x+this.w/2], - [box.x-box.w/2, - box.x+box.w/2]); - const height = this.overlap([this.y-this.h/2, - this.y+this.h/2], - [box.y-box.h/2, - box.y+box.h/2]); + const width = this.overlap( + [this.x - this.w / 2, this.x + this.w / 2], + [box.x - box.w / 2, box.x + box.w / 2]); + const height = this.overlap( + [this.y - this.h / 2, this.y + this.h / 2], + [box.y - box.h / 2, box.y + box.h / 2]); return width * height; } - private overlap(intervalA: [number, number], - intervalB: [number, number]): number { + private overlap(intervalA: [number, number], intervalB: [number, number]): + number { const [x1, x2] = intervalA; const [x3, x4] = intervalB; @@ -80,13 +92,13 @@ export class BoundingBox { if (x4 < x1) { return 0; } else { - return Math.min(x2,x4) - x1; + return Math.min(x2, x4) - x1; } } else { if (x2 < x3) { return 0; } else { - return Math.min(x2,x4) - x3; + return Math.min(x2, x4) - x3; } } } diff --git a/models/yolo_mobilenet/package.json b/models/yolo_mobilenet/package.json index fbaa7b6f6d..51a3c7276b 100644 --- a/models/yolo_mobilenet/package.json +++ b/models/yolo_mobilenet/package.json @@ -6,14 +6,16 @@ "unpkg": "dist/bundle.js", "types": "dist/index.d.ts", "peerDependencies": { - "deeplearn": "~0.3.11" + "deeplearn": "0.3.15" }, "repository": { "type": "git", "url": "https://github.com/PAIR-code/deeplearnjs.git" }, "devDependencies": { - "deeplearn": "0.3.13", + "browserify": "~14.5.0", + "browserify-shim": "~3.8.14", + "deeplearn": "0.3.15", "mkdirp": "~0.5.1", "tsify": "~3.0.3", "tslint": "~5.8.0", @@ -23,9 +25,17 @@ }, "scripts": { "prep": "yarn && mkdirp dist", - "build": "browserify --standalone yolo_mobilenet yolo_mobilenet.ts -p [tsify] -o dist/bundle.js", + "build": "browserify -g browserify-shim --standalone yolo_mobilenet index.ts -p [tsify] -o dist/bundle.js", "lint": "tslint -p . -t verbose", "publish-npm": "tsc --sourceMap false && yarn build && npm publish" }, + "browserify-shim": { + "deeplearn": "global:dl" + }, + "browserify": { + "global-transform": [ + "browserify-shim" + ] + }, "license": "Apache-2.0" } diff --git a/models/yolo_mobilenet/yarn.lock b/models/yolo_mobilenet/yarn.lock index 11adbb8d8f..f4c21dfa9a 100644 --- a/models/yolo_mobilenet/yarn.lock +++ b/models/yolo_mobilenet/yarn.lock @@ -13,6 +13,14 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +accessory@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/accessory/-/accessory-1.1.0.tgz#7833e9839a32ded76d26021f36a41707a520f593" + dependencies: + ap "~0.2.0" + balanced-match "~0.2.0" + dot-parts "~1.0.0" + acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -28,6 +36,10 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -53,6 +65,10 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +ap@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ap/-/ap-0.2.0.tgz#ae0942600b29912f0d2b14ec60c45e8f330b6110" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -150,6 +166,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +balanced-match@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.2.1.tgz#7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7" + base64-js@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" @@ -249,6 +269,16 @@ browserify-rsa@^4.0.0: bn.js "^4.1.0" randombytes "^2.0.1" +browserify-shim@~3.8.14: + version "3.8.14" + resolved "https://registry.yarnpkg.com/browserify-shim/-/browserify-shim-3.8.14.tgz#bf1057026932d3253c75ef7dd714f3b877edec6b" + dependencies: + exposify "~0.5.0" + mothership "~0.2.0" + rename-function-calls "~0.1.0" + resolve "~0.6.1" + through "~2.3.4" + browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" @@ -267,7 +297,7 @@ browserify-zlib@~0.2.0: dependencies: pako "~1.0.5" -browserify@^14.0.0: +browserify@^14.0.0, browserify@~14.5.0: version "14.5.0" resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" dependencies: @@ -530,9 +560,9 @@ deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" -deeplearn@~0.3.11: - version "0.3.13" - resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.13.tgz#12033ab21581fb277dede662250bd58d86457d44" +deeplearn@0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/deeplearn/-/deeplearn-0.3.15.tgz#0cdc7a5171e932dbb312914b56ccdec2dbd873bc" dependencies: seedrandom "~2.4.3" @@ -575,6 +605,20 @@ detective@^4.0.0: acorn "^5.2.1" defined "^1.0.0" +detective@^4.5.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +detective@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-3.1.0.tgz#77782444ab752b88ca1be2e9d0a0395f1da25eed" + dependencies: + escodegen "~1.1.0" + esprima-fb "3001.1.0-dev-harmony-fb" + diff@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" @@ -591,6 +635,10 @@ domain-browser@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" +dot-parts@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dot-parts/-/dot-parts-1.0.1.tgz#884bd7bcfc3082ffad2fe5db53e494d8f3e0743f" + duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -621,14 +669,40 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.1.0.tgz#c663923f6e20aad48d0c0fa49f31c6d4f49360cf" + dependencies: + esprima "~1.0.4" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.30" + +esprima-fb@3001.1.0-dev-harmony-fb: + version "3001.1.0-dev-harmony-fb" + resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz#b77d37abcd38ea0b77426bb8bc2922ce6b426411" + +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + events@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -652,6 +726,16 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +exposify@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/exposify/-/exposify-0.5.0.tgz#f92d0094c265b3f553e1fa456a03a1883d1059cc" + dependencies: + globo "~1.1.0" + map-obj "~1.0.1" + replace-requires "~1.0.3" + through2 "~0.4.0" + transformify "~0.1.1" + extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -684,6 +768,10 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +find-parent-dir@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -781,6 +869,14 @@ glob@^7.0.5, glob@^7.1.0, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +globo@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/globo/-/globo-1.1.0.tgz#0d26098955dea422eb2001b104898b0a101caaf3" + dependencies: + accessory "~1.1.0" + is-defined "~1.0.0" + ternary "~1.0.0" + graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -806,6 +902,12 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-require@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/has-require/-/has-require-1.2.2.tgz#921675ab130dbd9768fc8da8f1a8e242dfa41774" + dependencies: + escape-string-regexp "^1.0.3" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -933,6 +1035,10 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-defined/-/is-defined-1.0.0.tgz#1f07ca67d571f594c4b14415a45f7bef88f92bf5" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -991,14 +1097,14 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +isarray@0.0.1, isarray@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isarray@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -1084,6 +1190,10 @@ lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" +map-obj@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + md5.js@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" @@ -1174,6 +1284,12 @@ module-deps@^4.0.8: through2 "^2.0.0" xtend "^4.0.0" +mothership@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/mothership/-/mothership-0.2.0.tgz#93d48a2fbc3e50e2a5fc8ed586f5bc44c65f9a99" + dependencies: + find-parent-dir "~0.3.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1232,6 +1348,10 @@ object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1305,6 +1425,10 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +patch-text@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/patch-text/-/patch-text-1.0.2.tgz#4bf36e65e51733d6e98f0cf62e09034daa0348ac" + path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -1424,6 +1548,24 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -1454,6 +1596,12 @@ remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" +rename-function-calls@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/rename-function-calls/-/rename-function-calls-0.1.1.tgz#7f83369c007a3007f6abe3033ccf81686a108e01" + dependencies: + detective "~3.1.0" + repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" @@ -1462,6 +1610,15 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +replace-requires@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/replace-requires/-/replace-requires-1.0.4.tgz#014b7330b6b9e2557b71043b66fb02660c3bf667" + dependencies: + detective "^4.5.0" + has-require "~1.2.1" + patch-text "~1.0.2" + xtend "~4.0.0" + request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -1499,6 +1656,10 @@ resolve@^1.1.3, resolve@^1.1.4, resolve@^1.3.2: dependencies: path-parse "^1.0.5" +resolve@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" @@ -1565,6 +1726,12 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +source-map@~0.1.30: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -1695,6 +1862,10 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" +ternary@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ternary/-/ternary-1.0.0.tgz#45702725608c9499d46a9610e9b0e49ff26f789e" + through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -1702,7 +1873,14 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" -"through@>=2.2.7 <3": +through2@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +"through@>=2.2.7 <3", through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -1722,6 +1900,12 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +transformify@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/transformify/-/transformify-0.1.2.tgz#9a4f42a154433dd727b80575428a3c9e5489ebf1" + dependencies: + readable-stream "~1.1.9" + tsconfig@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-5.0.3.tgz#5f4278e701800967a8fc383fd19648878f2a6e3a" @@ -1859,6 +2043,12 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -xtend@^4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + dependencies: + object-keys "~0.4.0" diff --git a/models/yolo_mobilenet/yolo_mobilenet.ts b/models/yolo_mobilenet/yolo_mobilenet.ts index 53406484cd..185bda9652 100644 --- a/models/yolo_mobilenet/yolo_mobilenet.ts +++ b/models/yolo_mobilenet/yolo_mobilenet.ts @@ -14,40 +14,34 @@ * limitations under the License. * ============================================================================= */ -// tslint:disable-next-line:max-line-length -import {Array1D, Array3D, Array4D, CheckpointLoader, initializeGPU, Model, NDArray, NDArrayMath, NDArrayMathGPU, Scalar} from 'deeplearn'; -import {BoundingBox} from './mobilenet_utils'; +// tslint:disable-next-line:max-line-length +import {Array1D, Array3D, Array4D, CheckpointLoader, Model, NDArray, NDArrayMath, Scalar} from 'deeplearn'; +import {BoundingBox} from './mobilenet_utils'; -const GOOGLE_CLOUD_STORAGE_DIR = +const GOOGLE_CLOUD_STORAGE_DIR = 'https://storage.googleapis.com/learnjs-data/checkpoint_zoo/'; - + export class YoloMobileNetDetection implements Model { private variables: {[varName: string]: NDArray}; // yolo variables - private PREPROCESS_DIVISOR = Scalar.new(255.0/2); - private ONE = Scalar.ONE; + private PREPROCESS_DIVISOR = Scalar.new(255.0 / 2); + private ONE = Scalar.new(1); private THRESHOLD = 0.3; private THRESHOLD_SCALAR = Scalar.new(this.THRESHOLD); - private ANCHORS: number[] = [0.57273, 0.677385, 1.87446, 2.06253, 3.33843, - 5.47434, 7.88282, 3.52778, 9.77052, 9.16828]; - - constructor(private math: NDArrayMath) { - // TODO(nsthorat): This awful hack is because we need to share the global - // GPGPU between deeplearn loaded from standalone as well as the internal - // deeplearn that gets compiled as part of this model. Remove this once we - // decouple NDArray from storage mechanism. - initializeGPU( - (this.math as NDArrayMathGPU).getGPGPUContext(), - (this.math as NDArrayMathGPU).getTextureManager()); - } + private ANCHORS: number[] = [ + 0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, + 9.77052, 9.16828 + ]; + + constructor(private math: NDArrayMath) {} /** * Loads necessary variables for MobileNet. */ async load(): Promise { - const checkpointLoader = new CheckpointLoader(GOOGLE_CLOUD_STORAGE_DIR + - 'yolo_mobilenet_v1_1.0_416/'); + const checkpointLoader = new CheckpointLoader( + GOOGLE_CLOUD_STORAGE_DIR + 'yolo_mobilenet_v1_1.0_416/'); this.variables = await checkpointLoader.getAllVariables(); } @@ -63,96 +57,88 @@ export class YoloMobileNetDetection implements Model { // Keep a map of named activations for rendering purposes. const netout = this.math.scope((keep) => { // Preprocess the input. - const preprocessedInput = this.math.subtract( - this.math.arrayDividedByScalar(input, this.PREPROCESS_DIVISOR), - this.ONE) as Array3D; + const preprocessedInput = + this.math.subtract( + this.math.arrayDividedByScalar(input, this.PREPROCESS_DIVISOR), + this.ONE) as Array3D; - const x1 = this.convBlock(preprocessedInput, [2, 2]); - const x2 = this.depthwiseConvBlock(x1, [1, 1], 1); + const x1 = this.convBlock(preprocessedInput, [2, 2]); + const x2 = this.depthwiseConvBlock(x1, [1, 1], 1); - const x3 = this.depthwiseConvBlock(x2, [2, 2], 2); - const x4 = this.depthwiseConvBlock(x3, [1, 1], 3); + const x3 = this.depthwiseConvBlock(x2, [2, 2], 2); + const x4 = this.depthwiseConvBlock(x3, [1, 1], 3); - const x5 = this.depthwiseConvBlock(x4, [2, 2], 4); - const x6 = this.depthwiseConvBlock(x5, [1, 1], 5); + const x5 = this.depthwiseConvBlock(x4, [2, 2], 4); + const x6 = this.depthwiseConvBlock(x5, [1, 1], 5); - const x7 = this.depthwiseConvBlock(x6, [2, 2], 6); - const x8 = this.depthwiseConvBlock(x7, [1, 1], 7); - const x9 = this.depthwiseConvBlock(x8, [1, 1], 8); - const x10 = this.depthwiseConvBlock(x9, [1, 1], 9); + const x7 = this.depthwiseConvBlock(x6, [2, 2], 6); + const x8 = this.depthwiseConvBlock(x7, [1, 1], 7); + const x9 = this.depthwiseConvBlock(x8, [1, 1], 8); + const x10 = this.depthwiseConvBlock(x9, [1, 1], 9); const x11 = this.depthwiseConvBlock(x10, [1, 1], 10); const x12 = this.depthwiseConvBlock(x11, [1, 1], 11); const x13 = this.depthwiseConvBlock(x12, [2, 2], 12); const x14 = this.depthwiseConvBlock(x13, [1, 1], 13); - const x15 = this.math.conv2d(x14, - this.variables['conv_23/kernel'] as Array4D, - this.variables['conv_23/bias'] as Array1D, - [1,1], - 'same'); - + const x15 = this.math.conv2d( + x14, this.variables['conv_23/kernel'] as Array4D, + this.variables['conv_23/bias'] as Array1D, [1, 1], 'same'); + return x15.as4D(13, 13, 5, 6); }); return netout; - } - - private convBlock(inputs: Array3D, strides: [number, number]) { + } - const x1 = this.math.conv2d(inputs, - this.variables['conv1/kernel'] as Array4D, - null, // this convolutional layer does not use bias - strides, - 'same'); + private convBlock(inputs: Array3D, strides: [number, number]) { + const x1 = this.math.conv2d( + inputs, this.variables['conv1/kernel'] as Array4D, + null, // this convolutional layer does not use bias + strides, 'same'); - const x2 = this.math.batchNormalization3D(x1, - this.variables['conv1_bn/moving_mean'] as Array1D, - this.variables['conv1_bn/moving_variance'] as Array1D, - .001, + const x2 = this.math.batchNormalization3D( + x1, this.variables['conv1_bn/moving_mean'] as Array1D, + this.variables['conv1_bn/moving_variance'] as Array1D, .001, this.variables['conv1_bn/gamma'] as Array1D, this.variables['conv1_bn/beta'] as Array1D); - return this.math.clip(x2, 0, 6); // simple implementation of Relu6 + return this.math.clip(x2, 0, 6); // simple implementation of Relu6 } - private depthwiseConvBlock(inputs: Array3D, - strides: [number, number], - blockID: number) { + private depthwiseConvBlock( + inputs: Array3D, strides: [number, number], blockID: number) { const dwPadding = 'conv_dw_' + String(blockID) + ''; - const pwPadding = 'conv_pw_' + String(blockID) + ''; + const pwPadding = 'conv_pw_' + String(blockID) + ''; - const x1 = this.math.depthwiseConv2D(inputs, - this.variables[dwPadding + '/depthwise_kernel'] as Array4D, - strides, - 'same') as Array3D; + const x1 = + this.math.depthwiseConv2D( + inputs, this.variables[dwPadding + '/depthwise_kernel'] as Array4D, + strides, 'same') as Array3D; - const x2 = this.math.batchNormalization3D(x1, - this.variables[dwPadding + '_bn/moving_mean'] as Array1D, - this.variables[dwPadding + '_bn/moving_variance'] as Array1D, - .001, + const x2 = this.math.batchNormalization3D( + x1, this.variables[dwPadding + '_bn/moving_mean'] as Array1D, + this.variables[dwPadding + '_bn/moving_variance'] as Array1D, .001, this.variables[dwPadding + '_bn/gamma'] as Array1D, this.variables[dwPadding + '_bn/beta'] as Array1D); const x3 = this.math.clip(x2, 0, 6); - const x4 = this.math.conv2d(x3, - this.variables[pwPadding + '/kernel'] as Array4D, - null, // this convolutional layer does not use bias - [1, 1], - 'same'); + const x4 = this.math.conv2d( + x3, this.variables[pwPadding + '/kernel'] as Array4D, + null, // this convolutional layer does not use bias + [1, 1], 'same'); - const x5 = this.math.batchNormalization3D(x4, - this.variables[pwPadding + '_bn/moving_mean'] as Array1D, - this.variables[pwPadding + '_bn/moving_variance'] as Array1D, - .001, + const x5 = this.math.batchNormalization3D( + x4, this.variables[pwPadding + '_bn/moving_mean'] as Array1D, + this.variables[pwPadding + '_bn/moving_variance'] as Array1D, .001, this.variables[pwPadding + '_bn/gamma'] as Array1D, this.variables[pwPadding + '_bn/beta'] as Array1D); return this.math.clip(x5, 0, 6); } - async interpretNetout(netout: Array4D): Promise { + async interpretNetout(netout: Array4D): Promise { // interpret the output by the network const GRID_H = netout.shape[0]; const GRID_W = netout.shape[1]; @@ -161,16 +147,15 @@ export class YoloMobileNetDetection implements Model { const boxes: BoundingBox[] = []; // adjust confidence predictions - const confidence = this.math.sigmoid(this.math.slice4D(netout, - [0, 0, 0, 4], - [GRID_H, GRID_W, BOX, 1])); + const confidence = this.math.sigmoid( + this.math.slice4D(netout, [0, 0, 0, 4], [GRID_H, GRID_W, BOX, 1])); // adjust class prediction - let classes = this.math.softmax(this.math.slice4D(netout, [0, 0, 0, 5], - [GRID_H, GRID_W, BOX, CLASS])); + let classes = this.math.softmax( + this.math.slice4D(netout, [0, 0, 0, 5], [GRID_H, GRID_W, BOX, CLASS])); classes = this.math.multiply(classes, confidence) as Array4D; - const mask = this.math.step(this.math.relu(this.math.subtract(classes, - this.THRESHOLD_SCALAR))); + const mask = this.math.step( + this.math.relu(this.math.subtract(classes, this.THRESHOLD_SCALAR))); classes = this.math.multiply(classes, mask) as Array4D; const objectLikelihood = this.math.sum(classes, 3); @@ -181,10 +166,11 @@ export class YoloMobileNetDetection implements Model { const [row, col, box] = objectLikelihood.indexToLoc(i) as number[]; const conf = confidence.get(row, col, box, 0); - const probs = this.math.slice4D(classes, - [row, col, box, 0], [1, 1, 1, CLASS]).getValues() as Float32Array; - const xywh = this.math.slice4D(netout, - [row, col, box, 0], [1, 1, 1, 4]).getValues(); + const probs = + this.math.slice4D(classes, [row, col, box, 0], [1, 1, 1, CLASS]) + .getValues() as Float32Array; + const xywh = this.math.slice4D(netout, [row, col, box, 0], [1, 1, 1, 4]) + .getValues(); let x = xywh[0]; let y = xywh[1]; @@ -195,7 +181,7 @@ export class YoloMobileNetDetection implements Model { w = this.ANCHORS[2 * box + 0] * Math.exp(w) / GRID_W; h = this.ANCHORS[2 * box + 1] * Math.exp(h) / GRID_H; - boxes.push(new BoundingBox(x, y, w, h, conf, probs)); + boxes.push(new BoundingBox(x, y, w, h, conf, probs)); } } @@ -208,7 +194,7 @@ export class YoloMobileNetDetection implements Model { indices[i] = i; } - indices.sort((a,b) => allProbs[a] > allProbs[b] ? 1 : 0); + indices.sort((a, b) => allProbs[a] > allProbs[b] ? 1 : 0); for (let i = 0; i < allProbs.length; i++) { const indexI = indices[i]; @@ -216,7 +202,7 @@ export class YoloMobileNetDetection implements Model { if (boxes[indexI].probs[cls] === 0) { continue; } else { - for (let j = i+1; j < allProbs.length; j++){ + for (let j = i + 1; j < allProbs.length; j++) { const indexJ = indices[j]; if (boxes[indexI].iou(boxes[indexJ]) > 0.4) { @@ -225,14 +211,13 @@ export class YoloMobileNetDetection implements Model { } } } - - } + } // obtain the most likely boxes const likelyBoxes = []; for (const box of boxes) { - if (box.getMaxProb() > this.THRESHOLD) { + if (box.getMaxProb() > this.THRESHOLD) { likelyBoxes.push(box); } } @@ -241,12 +226,12 @@ export class YoloMobileNetDetection implements Model { } private sigmoid(x: number): number { - return 1./ (1. + Math.exp(-x)); - } + return 1. / (1. + Math.exp(-x)); + } dispose() { for (const varName in this.variables) { this.variables[varName].dispose(); } } -} \ No newline at end of file +} From ea86f7ace2bd1cc71b4fba639b7ee46ee9518c11 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Sat, 23 Dec 2017 11:50:48 -0500 Subject: [PATCH 8/9] save --- .../batchnormalization3d_benchmark.ts | 6 ++-- demos/benchmarks/matmul_benchmarks.ts | 6 ++-- demos/benchmarks/pool_benchmarks.ts | 6 ++-- demos/benchmarks/reduction_ops_benchmark.ts | 6 ++-- demos/benchmarks/unary_ops_benchmark.ts | 6 ++-- .../complementary-color-prediction.ts | 3 +- demos/imagenet/imagenet.ts | 3 +- demos/latent-space-explorer/App.vue | 6 ++-- demos/ml_beginners/ml_beginners.ts | 3 +- demos/nn-art/cppn.ts | 3 +- demos/teachable_gaming/teachable_gaming.ts | 3 +- demos/util.ts | 2 +- .../knn_image_classifier.ts | 21 ++---------- models/knn_image_classifier/tsconfig.json | 3 +- models/mobilenet/mobilenet.ts | 22 ++---------- models/mobilenet/tsconfig.json | 4 ++- models/package.json | 6 ++++ models/squeezenet/squeezenet.ts | 22 ++---------- models/squeezenet/tsconfig.json | 3 +- models/util.ts | 34 +++++++++++++++++++ models/yolo_mobilenet/tsconfig.json | 3 +- 21 files changed, 88 insertions(+), 83 deletions(-) create mode 100644 models/package.json create mode 100644 models/util.ts diff --git a/demos/benchmarks/batchnormalization3d_benchmark.ts b/demos/benchmarks/batchnormalization3d_benchmark.ts index 453131a54a..0047bdfc34 100644 --- a/demos/benchmarks/batchnormalization3d_benchmark.ts +++ b/demos/benchmarks/batchnormalization3d_benchmark.ts @@ -29,7 +29,8 @@ export class BatchNormalization3DCPUBenchmark implements BenchmarkTest { resolve(-1); }); } - const math = new NDArrayMath('cpu', false); + const safeMode = false; + const math = new NDArrayMath('cpu', safeMode); ENV.setMath(math); const x = Array3D.randUniform([size, size, 8], -1, 1); const mean = Array1D.new([0]); @@ -49,7 +50,8 @@ export class BatchNormalization3DCPUBenchmark implements BenchmarkTest { export class BatchNormalization3DGPUBenchmark implements BenchmarkTest { async run(size: number) { - const math = new NDArrayMath('webgl', false); + const safeMode = false; + const math = new NDArrayMath('webgl', safeMode); ENV.setMath(math); const x = Array3D.randUniform([size, size, 8], -1, 1); const mean = Array1D.new([0]); diff --git a/demos/benchmarks/matmul_benchmarks.ts b/demos/benchmarks/matmul_benchmarks.ts index d7eb4a4b7a..a08d04a647 100644 --- a/demos/benchmarks/matmul_benchmarks.ts +++ b/demos/benchmarks/matmul_benchmarks.ts @@ -28,7 +28,8 @@ export class MatmulCPUBenchmark implements BenchmarkTest { resolve(-1); }); } - const math = new NDArrayMath('cpu', false); + const safeMode = false; + const math = new NDArrayMath('cpu', safeMode); ENV.setMath(math); const a = Array2D.randUniform([size, size], -1, 1); const b = Array2D.randUniform([size, size], -1, 1); @@ -43,7 +44,8 @@ export class MatmulCPUBenchmark implements BenchmarkTest { export class MatmulGPUBenchmark implements BenchmarkTest { async run(size: number): Promise { - const math = new NDArrayMath('webgl', false); + const safeMode = false; + const math = new NDArrayMath('webgl', safeMode); ENV.setMath(math); const a = Array2D.randNormal([size, size]); const b = Array2D.randNormal([size, size]); diff --git a/demos/benchmarks/pool_benchmarks.ts b/demos/benchmarks/pool_benchmarks.ts index e7bfe6afe9..d5808edf4e 100644 --- a/demos/benchmarks/pool_benchmarks.ts +++ b/demos/benchmarks/pool_benchmarks.ts @@ -58,7 +58,8 @@ function getPoolingOp(option: string, math: NDArrayMath): ( export class PoolCPUBenchmark implements BenchmarkTest { run(size: number, option: string, params: PoolBenchmarkParams): Promise { - const math = new NDArrayMath('cpu', false); + const safeMode = false; + const math = new NDArrayMath('cpu', safeMode); ENV.setMath(math); const outputDepth = params.depth; const xShape: [number, number, number] = [size, size, outputDepth]; @@ -84,7 +85,8 @@ export class PoolCPUBenchmark implements BenchmarkTest { export class PoolGPUBenchmark implements BenchmarkTest { async run(size: number, option: string, params: PoolBenchmarkParams): Promise { - const math = new NDArrayMath('webgl', false); + const safeMode = false; + const math = new NDArrayMath('webgl', safeMode); ENV.setMath(math); const outputDepth = params.depth; const xShape: [number, number, number] = [size, size, outputDepth]; diff --git a/demos/benchmarks/reduction_ops_benchmark.ts b/demos/benchmarks/reduction_ops_benchmark.ts index d98d937788..17d815eda0 100644 --- a/demos/benchmarks/reduction_ops_benchmark.ts +++ b/demos/benchmarks/reduction_ops_benchmark.ts @@ -42,7 +42,8 @@ function getReductionOp(option: string, math: NDArrayMath): (input: NDArray) => export class ReductionOpsCPUBenchmark implements BenchmarkTest { async run(size: number, option: string): Promise { - const math = new NDArrayMath('cpu', false); + const safeMode = false; + const math = new NDArrayMath('cpu', safeMode); ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getReductionOp(option, math); @@ -59,7 +60,8 @@ export class ReductionOpsCPUBenchmark implements BenchmarkTest { export class ReductionOpsGPUBenchmark implements BenchmarkTest { async run(size: number, option: string) { - const math = new NDArrayMath('webgl', false); + const safeMode = false; + const math = new NDArrayMath('webgl', safeMode); ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getReductionOp(option, math); diff --git a/demos/benchmarks/unary_ops_benchmark.ts b/demos/benchmarks/unary_ops_benchmark.ts index d0a89c72d3..fb9c677c17 100644 --- a/demos/benchmarks/unary_ops_benchmark.ts +++ b/demos/benchmarks/unary_ops_benchmark.ts @@ -62,7 +62,8 @@ function getUnaryOp(option: string, math: NDArrayMath) { export class UnaryOpsCPUBenchmark implements BenchmarkTest { async run(size: number, option: string): Promise { - const math = new NDArrayMath('cpu', false); + const safeMode = false; + const math = new NDArrayMath('cpu', safeMode); ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getUnaryOp(option, math); @@ -79,7 +80,8 @@ export class UnaryOpsCPUBenchmark implements BenchmarkTest { export class UnaryOpsGPUBenchmark implements BenchmarkTest { async run(size: number, option: string) { - const math = new NDArrayMath('webgl', false); + const safeMode = false; + const math = new NDArrayMath('webgl', safeMode); ENV.setMath(math); const input = Array2D.randUniform([size, size], -1, 1); const op = getUnaryOp(option, math); diff --git a/demos/complementary-color-prediction/complementary-color-prediction.ts b/demos/complementary-color-prediction/complementary-color-prediction.ts index dd6d40cb4d..6fec18621e 100644 --- a/demos/complementary-color-prediction/complementary-color-prediction.ts +++ b/demos/complementary-color-prediction/complementary-color-prediction.ts @@ -157,7 +157,8 @@ class ComplementaryColorModel { private generateTrainingData(exampleCount: number) { const rawInputs = new Array(exampleCount); const oldMath = ENV.math; - const math = new NDArrayMath('cpu', false); + const safeMode = false; + const math = new NDArrayMath('cpu', safeMode); ENV.setMath(math); for (let i = 0; i < exampleCount; i++) { diff --git a/demos/imagenet/imagenet.ts b/demos/imagenet/imagenet.ts index 0e9a831c0a..e1b5431234 100644 --- a/demos/imagenet/imagenet.ts +++ b/demos/imagenet/imagenet.ts @@ -104,7 +104,8 @@ export class ImagenetDemo extends ImagenetDemoPolymer { const gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); this.gpgpu = new GPGPUContext(gl); this.backend = new MathBackendWebGL(this.gpgpu); - this.math = new NDArrayMath(this.backend, false); + const safeMode = false; + this.math = new NDArrayMath(this.backend, safeMode); ENV.setMath(this.math); this.renderGrayscaleChannelsCollageShader = diff --git a/demos/latent-space-explorer/App.vue b/demos/latent-space-explorer/App.vue index 7b6c61374c..4b6b8bbf0b 100644 --- a/demos/latent-space-explorer/App.vue +++ b/demos/latent-space-explorer/App.vue @@ -145,9 +145,9 @@ export default { updateHash: function() { if (this.selectedSample) { this.selectedSample.data().then(vals => { - const hashStr = '#' + Array.from(vals).map( - val => parseFloat(val).toFixed(3)) - .join(','); + const hashStr = '#' + Array.from(vals) + .map(val => parseFloat(val).toFixed(3)) + .join(','); history.replaceState(undefined, undefined, hashStr); }); } diff --git a/demos/ml_beginners/ml_beginners.ts b/demos/ml_beginners/ml_beginners.ts index f81ac812eb..4171534f7f 100644 --- a/demos/ml_beginners/ml_beginners.ts +++ b/demos/ml_beginners/ml_beginners.ts @@ -65,8 +65,7 @@ async function mlBeginners() { // NOTE: "a", "b", and "c" are randomly initialized, so this will give us // something random. let result: NDArray = session.eval(y, [{tensor: x, data: Scalar.new(4)}]); - console.log(result.shape); - console.log(result.getValues()); + console.log(result.dataSync()); /** * Training diff --git a/demos/nn-art/cppn.ts b/demos/nn-art/cppn.ts index 0bc754c448..661f958bbc 100644 --- a/demos/nn-art/cppn.ts +++ b/demos/nn-art/cppn.ts @@ -74,7 +74,8 @@ export class CPPN { const gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); this.gpgpu = new GPGPUContext(gl); this.backend = new MathBackendWebGL(this.gpgpu); - this.math = new NDArrayMath(this.backend, false); + const safeMode = false; + this.math = new NDArrayMath(this.backend, safeMode); ENV.setMath(this.math); const maxTextureSize = webgl_util.queryMaxTextureSize(gl); diff --git a/demos/teachable_gaming/teachable_gaming.ts b/demos/teachable_gaming/teachable_gaming.ts index 15d54dd917..4ec3d71f27 100644 --- a/demos/teachable_gaming/teachable_gaming.ts +++ b/demos/teachable_gaming/teachable_gaming.ts @@ -207,7 +207,8 @@ export class TeachableGamingDemo extends TeachableGamingDemoPolymer { const gl = gpgpu_util.createWebGLContext(this.inferenceCanvas); const gpgpu = new GPGPUContext(gl); const backend = new MathBackendWebGL(gpgpu); - this.math = new NDArrayMath(backend, false); + const safeMode = false; + this.math = new NDArrayMath(backend, safeMode); this.classifier = new KNNImageClassifier( TeachableGamingDemo.maxControls, TeachableGamingDemo.knnKValue, this.math); diff --git a/demos/util.ts b/demos/util.ts index 58b5c5a52f..7c5c6a7c3b 100644 --- a/demos/util.ts +++ b/demos/util.ts @@ -18,7 +18,7 @@ import {ENV} from 'deeplearn'; export function isWebGLSupported(): boolean { - return ENV.getBackend('webgl') != null; + return ENV.get('WEBGL_VERSION') >= 1; } export function isSafari(): boolean { diff --git a/models/knn_image_classifier/knn_image_classifier.ts b/models/knn_image_classifier/knn_image_classifier.ts index 2f63872385..5f37fbccc8 100644 --- a/models/knn_image_classifier/knn_image_classifier.ts +++ b/models/knn_image_classifier/knn_image_classifier.ts @@ -17,6 +17,7 @@ // tslint:disable-next-line:max-line-length import {Array1D, Array2D, Array3D, Model, NDArrayMath, Scalar} from 'deeplearn'; import {SqueezeNet} from 'deeplearn-squeezenet'; +import * as model_util from '../util'; export class KNNImageClassifier implements Model { private squeezeNet: SqueezeNet; @@ -178,7 +179,7 @@ export class KNNImageClassifier implements Model { const knn = this.predict(image).asType('float32'); const numExamples = this.getNumExamples(); const kVal = Math.min(this.k, numExamples); - const topK = this.topK(await knn.data(), kVal); + const topK = model_util.topK(await knn.data(), kVal); knn.dispose(); const topKIndices = topK.indices; @@ -272,24 +273,6 @@ export class KNNImageClassifier implements Model { return total; } - private topK(values: Float32Array, k: number): - {values: Float32Array, indices: Int32Array} { - const valuesAndIndices: Array<{value: number, index: number}> = []; - for (let i = 0; i < values.length; i++) { - valuesAndIndices.push({value: values[i], index: i}); - } - valuesAndIndices.sort((a, b) => { - return b.value - a.value; - }); - const topkValues = new Float32Array(k); - const topkIndices = new Int32Array(k); - for (let i = 0; i < k; i++) { - topkValues[i] = valuesAndIndices[i].value; - topkIndices[i] = valuesAndIndices[i].index; - } - return {values: topkValues, indices: topkIndices}; - } - dispose() { this.squeezeNet.dispose(); this.clearTrainLogitsMatrix(); diff --git a/models/knn_image_classifier/tsconfig.json b/models/knn_image_classifier/tsconfig.json index ca81ff5c4d..ac3fc54cf1 100644 --- a/models/knn_image_classifier/tsconfig.json +++ b/models/knn_image_classifier/tsconfig.json @@ -5,7 +5,8 @@ }, "include": [ "index.ts", - "knn_image_classifier.ts" + "knn_image_classifier.ts", + "../util.ts" ], "exclude": [ "node_modules/", diff --git a/models/mobilenet/mobilenet.ts b/models/mobilenet/mobilenet.ts index 52104fe945..e9cf49f56b 100644 --- a/models/mobilenet/mobilenet.ts +++ b/models/mobilenet/mobilenet.ts @@ -16,6 +16,7 @@ */ // tslint:disable-next-line:max-line-length import {Array1D, Array3D, Array4D, CheckpointLoader, Model, NDArray, NDArrayMath, Scalar} from 'deeplearn'; +import * as model_util from '../util'; import {IMAGENET_CLASSES} from './imagenet_classes'; const GOOGLE_CLOUD_STORAGE_DIR = @@ -147,7 +148,7 @@ export class MobileNet implements Model { async getTopKClasses(logits: Array1D, topK: number): Promise<{[className: string]: number}> { const predictions = this.math.softmax(logits).asType('float32'); - const topk = this.topK(await predictions.data(), topK); + const topk = model_util.topK(await predictions.data(), topK); const topkIndices = topk.indices; const topkValues = topk.values; @@ -158,25 +159,6 @@ export class MobileNet implements Model { return topClassesToProbability; } - private topK(values: Float32Array, k: number): - {values: Float32Array, indices: Int32Array} { - const valuesAndIndices: Array<{value: number, index: number}> = []; - for (let i = 0; i < values.length; i++) { - valuesAndIndices.push({value: values[i], index: i}); - } - valuesAndIndices.sort((a, b) => { - return b.value - a.value; - }); - - const topkValues = new Float32Array(k); - const topkIndices = new Int32Array(k); - for (let i = 0; i < k; i++) { - topkValues[i] = valuesAndIndices[i].value; - topkIndices[i] = valuesAndIndices[i].index; - } - return {values: topkValues, indices: topkIndices}; - } - dispose() { for (const varName in this.variables) { this.variables[varName].dispose(); diff --git a/models/mobilenet/tsconfig.json b/models/mobilenet/tsconfig.json index ad8576b059..6ccd57ef0c 100644 --- a/models/mobilenet/tsconfig.json +++ b/models/mobilenet/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "include": [ - "index.ts", "mobiletnet.ts" + "index.ts", + "mobiletnet.ts", + "../util.ts" ], "exclude": [ "node_modules/", diff --git a/models/package.json b/models/package.json new file mode 100644 index 0000000000..ffac19ec2e --- /dev/null +++ b/models/package.json @@ -0,0 +1,6 @@ +{ + "browserify-shim": { + "deeplearn": "global:dl" + }, + "license": "Apache-2.0" +} diff --git a/models/squeezenet/squeezenet.ts b/models/squeezenet/squeezenet.ts index d0580f44a4..4f3fdf5a12 100644 --- a/models/squeezenet/squeezenet.ts +++ b/models/squeezenet/squeezenet.ts @@ -16,6 +16,7 @@ */ // tslint:disable-next-line:max-line-length import {Array1D, Array3D, Array4D, CheckpointLoader, Model, NDArray, NDArrayMath} from 'deeplearn'; +import * as model_util from '../util'; import {IMAGENET_CLASSES} from './imagenet_classes'; const GOOGLE_CLOUD_STORAGE_DIR = @@ -176,7 +177,7 @@ export class SqueezeNet implements Model { async getTopKClasses(logits: Array1D, topK: number): Promise<{[className: string]: number}> { const predictions = this.math.softmax(logits).asType('float32'); - const topk = this.topK(await predictions.data(), topK); + const topk = model_util.topK(await predictions.data(), topK); const topkIndices = topk.indices; const topkValues = topk.values; @@ -187,25 +188,6 @@ export class SqueezeNet implements Model { return topClassesToProbability; } - private topK(values: Float32Array, k: number): - {values: Float32Array, indices: Int32Array} { - const valuesAndIndices: Array<{value: number, index: number}> = []; - for (let i = 0; i < values.length; i++) { - valuesAndIndices.push({value: values[i], index: i}); - } - valuesAndIndices.sort((a, b) => { - return b.value - a.value; - }); - - const topkValues = new Float32Array(k); - const topkIndices = new Int32Array(k); - for (let i = 0; i < k; i++) { - topkValues[i] = valuesAndIndices[i].value; - topkIndices[i] = valuesAndIndices[i].index; - } - return {values: topkValues, indices: topkIndices}; - } - dispose() { this.preprocessOffset.dispose(); for (const varName in this.variables) { diff --git a/models/squeezenet/tsconfig.json b/models/squeezenet/tsconfig.json index fe7dab1c9c..29a71963a9 100644 --- a/models/squeezenet/tsconfig.json +++ b/models/squeezenet/tsconfig.json @@ -5,7 +5,8 @@ }, "include": [ "index.ts", - "squeezenet.ts" + "squeezenet.ts", + "../util.ts" ], "exclude": [ "node_modules/", diff --git a/models/util.ts b/models/util.ts new file mode 100644 index 0000000000..1e2927c734 --- /dev/null +++ b/models/util.ts @@ -0,0 +1,34 @@ +/** + * @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 topK(values: Float32Array, k: number): + {values: Float32Array, indices: Int32Array} { + const valuesAndIndices: Array<{value: number, index: number}> = []; + for (let i = 0; i < values.length; i++) { + valuesAndIndices.push({value: values[i], index: i}); + } + valuesAndIndices.sort((a, b) => { + return b.value - a.value; + }); + const topkValues = new Float32Array(k); + const topkIndices = new Int32Array(k); + for (let i = 0; i < k; i++) { + topkValues[i] = valuesAndIndices[i].value; + topkIndices[i] = valuesAndIndices[i].index; + } + return {values: topkValues, indices: topkIndices}; +} diff --git a/models/yolo_mobilenet/tsconfig.json b/models/yolo_mobilenet/tsconfig.json index bd8dee0ff4..131cbb176b 100644 --- a/models/yolo_mobilenet/tsconfig.json +++ b/models/yolo_mobilenet/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.json", "include": [ - "index.ts", "yolo_mobilenet.ts" + "index.ts", + "yolo_mobilenet.ts" ], "exclude": [ "node_modules/", From 46aac80d771272fd623e6f9d13a48ef0d65ecf83 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Sat, 23 Dec 2017 12:02:43 -0500 Subject: [PATCH 9/9] fix build script --- scripts/build_and_lint_all | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/build_and_lint_all b/scripts/build_and_lint_all index 3fd7a4c281..3cae8ab379 100755 --- a/scripts/build_and_lint_all +++ b/scripts/build_and_lint_all @@ -56,5 +56,7 @@ function runYarn(filePath) { shell.cd(cwd); } -const dirs = getPackageDirs(process.cwd()); +let dirs = getPackageDirs(process.cwd()); +// Keep only packages that have the 'name' property. +dirs = dirs.filter(dir => require(path.join(dir, 'package.json')).name); dirs.forEach(dir => runYarn(dir));