@tensorflow/tfjs-converter
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -1,4 +0,7 @@ | ||
import { Tensor } from 'deeplearn'; | ||
import { Tensor } from '@tensorflow/tfjs-core'; | ||
export declare type NamedTensorMap = { | ||
[key: string]: Tensor; | ||
}; | ||
export declare type NamedTensorsMap = { | ||
[key: string]: Tensor[]; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { NamedTensorMap } from '../data/index'; | ||
import { NamedTensorMap, NamedTensorsMap } from '../data/index'; | ||
import * as operations from '../operations/index'; | ||
@@ -7,7 +7,7 @@ export declare class GraphExecutor { | ||
private _weightMap; | ||
weightMap: NamedTensorMap; | ||
weightMap: NamedTensorsMap; | ||
constructor(graph: operations.Graph); | ||
private compile(); | ||
execute(inputs: NamedTensorMap): NamedTensorMap; | ||
execute(inputs: NamedTensorsMap, outputs?: string | string[]): NamedTensorMap; | ||
dispose(): void; | ||
} |
@@ -31,3 +31,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var deeplearn_1 = require("deeplearn"); | ||
var tfjs_core_1 = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("../operations/executors/utils"); | ||
var operations = require("../operations/index"); | ||
@@ -65,5 +66,5 @@ var GraphExecutor = (function () { | ||
}; | ||
GraphExecutor.prototype.execute = function (inputs) { | ||
GraphExecutor.prototype.execute = function (inputs, outputs) { | ||
var _this = this; | ||
var outputs = deeplearn_1.tidy(function () { | ||
var result = tfjs_core_1.tidy(function () { | ||
var tensors = _this.compiledOrder.reduce(function (map, node) { | ||
@@ -73,12 +74,17 @@ map[node.name] = operations.executeOp(node, map); | ||
}, __assign({}, _this.weightMap, inputs)); | ||
return _this.graph.outputs.reduce(function (map, node) { | ||
map[node.name] = tensors[node.name]; | ||
if (outputs && !(outputs instanceof Array)) { | ||
outputs = [outputs]; | ||
} | ||
var requestedOutputs = (outputs || _this.graph.outputs.map(function (node) { return node.name; })); | ||
return requestedOutputs.reduce(function (map, name) { | ||
map[name] = utils_1.getTensor(name, tensors); | ||
return map; | ||
}, {}); | ||
}); | ||
return outputs; | ||
return result; | ||
}; | ||
GraphExecutor.prototype.dispose = function () { | ||
var _this = this; | ||
Object.keys(this.weightMap).forEach(function (key) { return _this.weightMap[key].dispose(); }); | ||
Object.keys(this.weightMap) | ||
.forEach(function (key) { return _this.weightMap[key].forEach(function (tensor) { return tensor.dispose(); }); }); | ||
}; | ||
@@ -85,0 +91,0 @@ return GraphExecutor; |
@@ -0,1 +1,2 @@ | ||
import * as tf from '@tensorflow/tfjs-core'; | ||
import { NamedTensorMap } from '../data/index'; | ||
@@ -15,4 +16,5 @@ export declare class TFModel { | ||
load(): Promise<boolean>; | ||
eval(inputs: NamedTensorMap): NamedTensorMap; | ||
eval(inputs: NamedTensorMap, outputs?: string | string[]): tf.Tensor | NamedTensorMap; | ||
private convertTensorMapToTensorsMap(map); | ||
dispose(): void; | ||
} |
@@ -54,3 +54,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var index_1 = require("../data/index"); | ||
@@ -74,7 +74,15 @@ var index_2 = require("../operations/index"); | ||
TFModel.prototype.getPathPrefix = function () { | ||
var url = new URL(this.weightManifestUrl); | ||
var segments = url.pathname.split('/'); | ||
segments.splice(-1); | ||
url.pathname = segments.join('/'); | ||
this.pathPrefix = url.toString(); | ||
var isAbsolute = /^[a-z][a-z0-9+.-]*:/.test(this.weightManifestUrl); | ||
if (isAbsolute) { | ||
var url = new URL(this.weightManifestUrl); | ||
var segments = url.pathname.split('/'); | ||
segments.splice(-1); | ||
url.pathname = segments.join('/'); | ||
this.pathPrefix = url.toString(); | ||
} | ||
else { | ||
var segments = this.weightManifestUrl.split('/'); | ||
segments.splice(-1); | ||
this.pathPrefix = segments.join('/'); | ||
} | ||
}; | ||
@@ -138,3 +146,3 @@ TFModel.prototype.loadRemoteProtoFile = function () { | ||
this.version = graph.versions.producer + "." + graph.versions.minConsumer; | ||
return [4, dl.loadWeights(this.weightManifest, this.pathPrefix)]; | ||
return [4, tf.loadWeights(this.weightManifest, this.pathPrefix)]; | ||
case 2: | ||
@@ -144,3 +152,3 @@ weightMap = _b.sent(); | ||
new graph_executor_1.GraphExecutor(index_2.OperationMapper.Instance.transformGraph(graph)); | ||
this.executor.weightMap = weightMap; | ||
this.executor.weightMap = this.convertTensorMapToTensorsMap(weightMap); | ||
return [2, true]; | ||
@@ -151,5 +159,13 @@ } | ||
}; | ||
TFModel.prototype.eval = function (inputs) { | ||
return this.executor.execute(inputs); | ||
TFModel.prototype.eval = function (inputs, outputs) { | ||
var result = this.executor.execute(this.convertTensorMapToTensorsMap(inputs), outputs); | ||
var keys = Object.keys(result); | ||
return (keys.length === 1) ? result[keys[0]] : result; | ||
}; | ||
TFModel.prototype.convertTensorMapToTensorsMap = function (map) { | ||
return Object.keys(map).reduce(function (newMap, key) { | ||
newMap[key] = [map[key]]; | ||
return newMap; | ||
}, {}); | ||
}; | ||
TFModel.prototype.dispose = function () { | ||
@@ -156,0 +172,0 @@ this.executor.dispose(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -8,20 +8,20 @@ exports.executeOp = function (node, tensorMap) { | ||
case 'add': { | ||
return dl.add(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.add(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'mul': | ||
return dl.mul(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.mul(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
case 'div': { | ||
return dl.div(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.div(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'sub': { | ||
return dl.sub(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.sub(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'minimum': { | ||
return dl.minimum(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.minimum(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'maximum': { | ||
return dl.maximum(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.maximum(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'pow': { | ||
return dl.pow(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.pow(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
@@ -28,0 +28,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -8,49 +8,49 @@ exports.executeOp = function (node, tensorMap) { | ||
case 'abs': | ||
return dl.abs(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.abs(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'acos': | ||
return dl.acos(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.acos(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'asin': | ||
return dl.asin(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.asin(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'atan': | ||
return dl.atan(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.atan(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'ceil': | ||
return dl.ceil(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.ceil(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'cos': | ||
return dl.cos(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.cos(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'cosh': | ||
return dl.cosh(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.cosh(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'elu': | ||
return dl.elu(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.elu(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'exp': | ||
return dl.exp(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.exp(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'floor': | ||
return dl.floor(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.floor(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'log': | ||
return dl.log(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.log(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'relu': | ||
return dl.relu(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.relu(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'selu': | ||
return dl.selu(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.selu(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'sigmoid': | ||
return dl.sigmoid(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.sigmoid(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'sin': | ||
return dl.sin(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.sin(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'sinh': { | ||
return dl.sinh(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.sinh(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
case 'sqrt': { | ||
return dl.sqrt(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.sqrt(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
case 'square': { | ||
return dl.square(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.square(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
case 'tanh': { | ||
return dl.tanh(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.tanh(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
case 'tan': | ||
return dl.tan(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.tan(utils_1.getParamValue('x', node, tensorMap))]; | ||
case 'clipByValue': | ||
return dl.clipByValue(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('clipValueMin', node, tensorMap), utils_1.getParamValue('clipValueMax', node, tensorMap)); | ||
return [tf.clipByValue(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('clipValueMin', node, tensorMap), utils_1.getParamValue('clipValueMax', node, tensorMap))]; | ||
case 'rsqrt': | ||
return dl.div(dl.scalar(1.0, 'float32'), dl.sqrt(tensorMap[node.inputNames[0]])); | ||
return [tf.div(tf.scalar(1.0, 'float32'), tf.sqrt(utils_1.getTensor(node.inputNames[0], tensorMap)))]; | ||
default: | ||
@@ -57,0 +57,0 @@ throw TypeError("Node type " + node.op + " is not implemented"); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -10,3 +10,3 @@ exports.executeOp = function (node, tensorMap) { | ||
var pad = utils_1.getParamValue('pad', node, tensorMap); | ||
return dl.conv1d(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), stride, pad); | ||
return [tf.conv1d(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), stride, pad)]; | ||
} | ||
@@ -16,3 +16,3 @@ case 'conv2d': { | ||
var pad = utils_1.getParamValue('pad', node, tensorMap); | ||
return dl.conv2d(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), [stride[1], stride[2]], pad); | ||
return [tf.conv2d(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), [stride[1], stride[2]], pad)]; | ||
} | ||
@@ -23,3 +23,3 @@ case 'conv2dTranspose': { | ||
var pad = utils_1.getParamValue('pad', node, tensorMap); | ||
return dl.conv2dTranspose(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), shape, [stride[1], stride[2]], pad); | ||
return [tf.conv2dTranspose(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), shape, [stride[1], stride[2]], pad)]; | ||
} | ||
@@ -30,3 +30,3 @@ case 'depthwiseConv2d': { | ||
var rates = utils_1.getParamValue('rates', node, tensorMap); | ||
return dl.depthwiseConv2d(utils_1.getParamValue('input', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), [stride[1], stride[2]], pad, [rates[0], rates[1]]); | ||
return [tf.depthwiseConv2d(utils_1.getParamValue('input', node, tensorMap), utils_1.getParamValue('filter', node, tensorMap), [stride[1], stride[2]], pad, [rates[0], rates[1]])]; | ||
} | ||
@@ -37,3 +37,3 @@ case 'avgPool': { | ||
var kernelSize = utils_1.getParamValue('kernelSize', node, tensorMap); | ||
return dl.avgPool(utils_1.getParamValue('x', node, tensorMap), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad); | ||
return [tf.avgPool(utils_1.getParamValue('x', node, tensorMap), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad)]; | ||
} | ||
@@ -44,3 +44,3 @@ case 'maxPool': { | ||
var kernelSize = utils_1.getParamValue('kernelSize', node, tensorMap); | ||
return dl.maxPool(utils_1.getParamValue('x', node, tensorMap), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad); | ||
return [tf.maxPool(utils_1.getParamValue('x', node, tensorMap), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad)]; | ||
} | ||
@@ -47,0 +47,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -10,3 +10,3 @@ exports.executeOp = function (node, tensorMap) { | ||
var value = utils_1.getParamValue('value', node, tensorMap); | ||
return dl.fill(shape, value); | ||
return [tf.fill(shape, value)]; | ||
} | ||
@@ -17,3 +17,3 @@ case 'linspace': { | ||
var num = utils_1.getParamValue('num', node, tensorMap); | ||
return dl.linspace(start, stop_1, num); | ||
return [tf.linspace(start, stop_1, num)]; | ||
} | ||
@@ -25,12 +25,12 @@ case 'oneHot': { | ||
var offValue = utils_1.getParamValue('offValue', node, tensorMap); | ||
return dl.oneHot(indices, depth, onValue, offValue); | ||
return [tf.oneHot(indices, depth, onValue, offValue)]; | ||
} | ||
case 'ones': { | ||
return dl.ones(utils_1.getParamValue('shape', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap)); | ||
return [tf.ones(utils_1.getParamValue('shape', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap))]; | ||
} | ||
case 'onesLike': { | ||
return dl.onesLike(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.onesLike(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
case 'randomUniform': { | ||
return dl.randomUniform(utils_1.getParamValue('shape', node, tensorMap), utils_1.getParamValue('minval', node, tensorMap), utils_1.getParamValue('maxval', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap)); | ||
return [tf.randomUniform(utils_1.getParamValue('shape', node, tensorMap), utils_1.getParamValue('minval', node, tensorMap), utils_1.getParamValue('maxval', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap))]; | ||
} | ||
@@ -41,3 +41,3 @@ case 'range': { | ||
var step = utils_1.getParamValue('step', node, tensorMap); | ||
return dl.range(start, stop_2, step, utils_1.getParamValue('dtype', node, tensorMap)); | ||
return [tf.range(start, stop_2, step, utils_1.getParamValue('dtype', node, tensorMap))]; | ||
} | ||
@@ -49,9 +49,9 @@ case 'truncatedNormal': { | ||
var seed = utils_1.getParamValue('seed', node, tensorMap); | ||
return dl.truncatedNormal(shape, mean, stdDev, utils_1.getParamValue('dtype', node, tensorMap), seed); | ||
return [tf.truncatedNormal(shape, mean, stdDev, utils_1.getParamValue('dtype', node, tensorMap), seed)]; | ||
} | ||
case 'zeros': { | ||
return dl.zeros(utils_1.getParamValue('shape', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap)); | ||
return [tf.zeros(utils_1.getParamValue('shape', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap))]; | ||
} | ||
case 'zerosLike': { | ||
return dl.zerosLike(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.zerosLike(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
@@ -58,0 +58,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -12,7 +12,7 @@ exports.executeOp = function (node, tensorMap) { | ||
var def = utils_1.getParamValue('default', node, tensorMap); | ||
return tensorMap[node.name] ? tensorMap[node.name] : def; | ||
return [utils_1.getTensor(node.name, tensorMap) || def]; | ||
case 'identity': | ||
return utils_1.getParamValue('x', node, tensorMap); | ||
return [utils_1.getParamValue('x', node, tensorMap)]; | ||
case 'shape': | ||
return dl.tensor1d(utils_1.getParamValue('x', node, tensorMap).shape, 'int32'); | ||
return [tf.tensor1d(utils_1.getParamValue('x', node, tensorMap).shape, 'int32')]; | ||
default: | ||
@@ -19,0 +19,0 @@ throw TypeError("Node type " + node.op + " is not implemented"); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -8,27 +8,27 @@ exports.executeOp = function (node, tensorMap) { | ||
case 'equal': { | ||
return dl.equal(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.equal(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'greater': { | ||
return dl.greater(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.greater(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'greaterEqual': { | ||
return dl.greaterEqual(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.greaterEqual(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'less': { | ||
return dl.less(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.less(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'lessEqual': { | ||
return dl.lessEqual(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.lessEqual(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'logicalAnd': { | ||
return dl.logicalAnd(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.logicalAnd(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'logicalNot': { | ||
return dl.logicalNot(utils_1.getParamValue('a', node, tensorMap)); | ||
return [tf.logicalNot(utils_1.getParamValue('a', node, tensorMap))]; | ||
} | ||
case 'logicalOr': { | ||
return dl.logicalOr(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.logicalOr(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
case 'where': { | ||
return dl.where(utils_1.getParamValue('condition', node, tensorMap), utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap)); | ||
return [tf.where(utils_1.getParamValue('condition', node, tensorMap), utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap))]; | ||
} | ||
@@ -35,0 +35,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -8,5 +8,5 @@ exports.executeOp = function (node, tensorMap) { | ||
case 'matMul': | ||
return dl.matMul(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap), utils_1.getParamValue('transposeA', node, tensorMap), utils_1.getParamValue('transposeB', node, tensorMap)); | ||
return [tf.matMul(utils_1.getParamValue('a', node, tensorMap), utils_1.getParamValue('b', node, tensorMap), utils_1.getParamValue('transposeA', node, tensorMap), utils_1.getParamValue('transposeB', node, tensorMap))]; | ||
case 'transpose': | ||
return dl.transpose(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('perm', node, tensorMap)); | ||
return [tf.transpose(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('perm', node, tensorMap))]; | ||
default: | ||
@@ -13,0 +13,0 @@ throw TypeError("Node type " + node.op + " is not implemented"); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -8,9 +8,9 @@ exports.executeOp = function (node, tensorMap) { | ||
case 'batchNormalization': { | ||
return dl.batchNormalization(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('mean', node, tensorMap), utils_1.getParamValue('variance', node, tensorMap), utils_1.getParamValue('epislon', node, tensorMap), utils_1.getParamValue('scale', node, tensorMap), utils_1.getParamValue('offset', node, tensorMap)); | ||
return [tf.batchNormalization(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('mean', node, tensorMap), utils_1.getParamValue('variance', node, tensorMap), utils_1.getParamValue('epislon', node, tensorMap), utils_1.getParamValue('scale', node, tensorMap), utils_1.getParamValue('offset', node, tensorMap))]; | ||
} | ||
case 'localResponseNormalization': { | ||
return dl.localResponseNormalization(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('radius', node, tensorMap), utils_1.getParamValue('bias', node, tensorMap), utils_1.getParamValue('alpha', node, tensorMap), utils_1.getParamValue('beta', node, tensorMap)); | ||
return [tf.localResponseNormalization(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('radius', node, tensorMap), utils_1.getParamValue('bias', node, tensorMap), utils_1.getParamValue('alpha', node, tensorMap), utils_1.getParamValue('beta', node, tensorMap))]; | ||
} | ||
case 'softmax': { | ||
return dl.softmax(utils_1.getParamValue('x', node, tensorMap)); | ||
return [tf.softmax(utils_1.getParamValue('x', node, tensorMap))]; | ||
} | ||
@@ -17,0 +17,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -10,3 +10,3 @@ exports.executeOp = function (node, tensorMap) { | ||
var keepDims = utils_1.getParamValue('keepDims', node, tensorMap); | ||
return dl.max(utils_1.getParamValue('x', node, tensorMap), axis, keepDims); | ||
return [tf.max(utils_1.getParamValue('x', node, tensorMap), axis, keepDims)]; | ||
} | ||
@@ -16,3 +16,3 @@ case 'mean': { | ||
var keepDims = utils_1.getParamValue('keepDims', node, tensorMap); | ||
return dl.mean(utils_1.getParamValue('x', node, tensorMap), axis, keepDims); | ||
return [tf.mean(utils_1.getParamValue('x', node, tensorMap), axis, keepDims)]; | ||
} | ||
@@ -22,3 +22,3 @@ case 'min': { | ||
var keepDims = utils_1.getParamValue('keepDims', node, tensorMap); | ||
return dl.min(utils_1.getParamValue('x', node, tensorMap), axis, keepDims); | ||
return [tf.min(utils_1.getParamValue('x', node, tensorMap), axis, keepDims)]; | ||
} | ||
@@ -28,11 +28,11 @@ case 'sum': { | ||
var keepDims = utils_1.getParamValue('keepDims', node, tensorMap); | ||
return dl.sum(utils_1.getParamValue('x', node, tensorMap), axis, keepDims); | ||
return [tf.sum(utils_1.getParamValue('x', node, tensorMap), axis, keepDims)]; | ||
} | ||
case 'argMax': { | ||
var axis = utils_1.getParamValue('axis', node, tensorMap); | ||
return dl.argMax(utils_1.getParamValue('x', node, tensorMap), axis); | ||
return [tf.argMax(utils_1.getParamValue('x', node, tensorMap), axis)]; | ||
} | ||
case 'argMin': { | ||
var axis = utils_1.getParamValue('axis', node, tensorMap); | ||
return dl.argMin(utils_1.getParamValue('x', node, tensorMap), axis); | ||
return [tf.argMin(utils_1.getParamValue('x', node, tensorMap), axis)]; | ||
} | ||
@@ -39,0 +39,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -10,3 +10,3 @@ exports.executeOp = function (node, tensorMap) { | ||
var inputs = utils_1.getParamValue('tensors', node, tensorMap); | ||
return dl.concat(inputs, axis); | ||
return [tf.concat(inputs, axis)]; | ||
} | ||
@@ -17,3 +17,3 @@ case 'gather': { | ||
var indices = utils_1.getParamValue('indices', node, tensorMap); | ||
return dl.gather(input, indices, axis); | ||
return [tf.gather(input, indices, axis)]; | ||
} | ||
@@ -23,3 +23,3 @@ case 'reverse': { | ||
var input = utils_1.getParamValue('x', node, tensorMap); | ||
return dl.reverse(input, axis); | ||
return [tf.reverse(input, axis)]; | ||
} | ||
@@ -29,11 +29,11 @@ case 'slice': { | ||
var size = utils_1.getParamValue('size', node, tensorMap); | ||
return dl.slice(utils_1.getParamValue('x', node, tensorMap), begin, size); | ||
return [tf.slice(utils_1.getParamValue('x', node, tensorMap), begin, size)]; | ||
} | ||
case 'stack': { | ||
var axis = utils_1.getParamValue('axis', node, tensorMap); | ||
return dl.stack(utils_1.getParamValue('tensors', node, tensorMap), axis); | ||
return [tf.stack(utils_1.getParamValue('tensors', node, tensorMap), axis)]; | ||
} | ||
case 'tile': { | ||
var reps = utils_1.getParamValue('reps', node, tensorMap); | ||
return dl.tile(utils_1.getParamValue('x', node, tensorMap), reps); | ||
return [tf.tile(utils_1.getParamValue('x', node, tensorMap), reps)]; | ||
} | ||
@@ -40,0 +40,0 @@ default: |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var dl = require("deeplearn"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var utils_1 = require("./utils"); | ||
@@ -8,17 +8,17 @@ exports.executeOp = function (node, tensorMap) { | ||
case 'cast': { | ||
return dl.cast(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap)); | ||
return [tf.cast(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('dtype', node, tensorMap))]; | ||
} | ||
case 'expandDims': { | ||
var axis = node.params['axis'].value; | ||
return dl.expandDims(utils_1.getParamValue('x', node, tensorMap), axis); | ||
return [tf.expandDims(utils_1.getParamValue('x', node, tensorMap), axis)]; | ||
} | ||
case 'squeeze': { | ||
var axis = node.params['axis'].value; | ||
return dl.squeeze(utils_1.getParamValue('x', node, tensorMap), axis); | ||
return [tf.squeeze(utils_1.getParamValue('x', node, tensorMap), axis)]; | ||
} | ||
case 'reshape': { | ||
return dl.reshape(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('shape', node, tensorMap)); | ||
return [tf.reshape(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('shape', node, tensorMap))]; | ||
} | ||
case 'pad': { | ||
return dl.pad(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('padding', node, tensorMap), utils_1.getParamValue('constantValue', node, tensorMap)); | ||
return [tf.pad(utils_1.getParamValue('x', node, tensorMap), utils_1.getParamValue('padding', node, tensorMap), utils_1.getParamValue('constantValue', node, tensorMap))]; | ||
} | ||
@@ -25,0 +25,0 @@ default: |
@@ -1,6 +0,6 @@ | ||
import * as dl from 'deeplearn'; | ||
import { NamedTensorMap } from '../../data/index'; | ||
import * as tf from '@tensorflow/tfjs-core'; | ||
import { NamedTensorsMap } from '../../data/index'; | ||
import { Node } from '../index'; | ||
export interface OpExecutor { | ||
(node: Node, tensorMap: NamedTensorMap): dl.Tensor; | ||
(node: Node, tensorMap: NamedTensorsMap): tf.Tensor[]; | ||
} |
@@ -1,3 +0,5 @@ | ||
import { NamedTensorMap } from '../../data/index'; | ||
import * as tf from '@tensorflow/tfjs-core'; | ||
import { NamedTensorsMap } from '../../data/index'; | ||
import { Node, ValueType } from '../index'; | ||
export declare function getParamValue(paramName: string, node: Node, tensorMap: NamedTensorMap): ValueType; | ||
export declare function getParamValue(paramName: string, node: Node, tensorMap: NamedTensorsMap): ValueType; | ||
export declare function getTensor(name: string, tensorMap: NamedTensorsMap): tf.Tensor; |
@@ -7,3 +7,3 @@ "use strict"; | ||
if (param.type === 'tensor') { | ||
return tensorMap[node.inputNames[param.inputIndex]]; | ||
return getTensor(node.inputNames[param.inputIndex], tensorMap); | ||
} | ||
@@ -14,5 +14,6 @@ if (param.type === 'tensors') { | ||
node.inputNames.splice(param.inputIndex); | ||
return inputs.map(function (name) { return tensorMap[name]; }); | ||
return inputs.map(function (name) { return getTensor(name, tensorMap); }); | ||
} | ||
var data = Array.prototype.slice.call(tensorMap[node.inputNames.slice(param.inputIndex)[0]].dataSync()); | ||
var data = Array.prototype.slice.call(getTensor(node.inputNames.slice(param.inputIndex)[0], tensorMap) | ||
.dataSync()); | ||
return param.type === 'number' ? data[0] : data; | ||
@@ -23,2 +24,15 @@ } | ||
exports.getParamValue = getParamValue; | ||
function getTensor(name, tensorMap) { | ||
var index = name.lastIndexOf(':'); | ||
if (index === -1) { | ||
return tensorMap[name] ? tensorMap[name][0] : undefined; | ||
} | ||
else { | ||
var nodeName = name.substring(0, index); | ||
return tensorMap[nodeName] ? | ||
tensorMap[nodeName][Number(name.substring(index + 1))] : | ||
undefined; | ||
} | ||
} | ||
exports.getTensor = getTensor; | ||
//# sourceMappingURL=utils.js.map |
@@ -1,4 +0,4 @@ | ||
import * as dl from 'deeplearn'; | ||
import { NamedTensorMap } from '../data/index'; | ||
import * as tf from '@tensorflow/tfjs-core'; | ||
import { NamedTensorsMap } from '../data/index'; | ||
import { Node } from './index'; | ||
export declare function executeOp(node: Node, tensorMap: NamedTensorMap): dl.Tensor; | ||
export declare function executeOp(node: Node, tensorMap: NamedTensorsMap): tf.Tensor[]; |
@@ -8,2 +8,3 @@ import { tensorflow } from '../data/index'; | ||
private constructor(); | ||
private isControlFlow(node); | ||
transformGraph(graph: tensorflow.IGraphDef): Graph; | ||
@@ -10,0 +11,0 @@ private mapNode(node); |
@@ -35,2 +35,3 @@ "use strict"; | ||
var transformation = require("./op_list/transformation.json"); | ||
var CONTROL_FLOW_OPS = ['Switch', 'Merge', 'Enter', 'Exit', 'Next']; | ||
var OperationMapper = (function () { | ||
@@ -51,7 +52,13 @@ function OperationMapper() { | ||
}); | ||
OperationMapper.prototype.isControlFlow = function (node) { | ||
return CONTROL_FLOW_OPS.some(function (op) { return op === node.op; }); | ||
}; | ||
OperationMapper.prototype.transformGraph = function (graph) { | ||
var _this = this; | ||
var tfNodes = graph.node; | ||
var withControlFlow = false; | ||
var nodes = tfNodes.reduce(function (map, node) { | ||
map[node.name] = _this.mapNode(node); | ||
if (_this.isControlFlow(node)) | ||
withControlFlow = true; | ||
return map; | ||
@@ -75,3 +82,3 @@ }, {}); | ||
}); | ||
return { nodes: nodes, inputs: inputs, outputs: outputs }; | ||
return { nodes: nodes, inputs: inputs, outputs: outputs, withControlFlow: withControlFlow }; | ||
}; | ||
@@ -78,0 +85,0 @@ OperationMapper.prototype.mapNode = function (node) { |
@@ -1,2 +0,2 @@ | ||
import { Tensor } from 'deeplearn'; | ||
import { Tensor } from '@tensorflow/tfjs-core'; | ||
export declare type ParamTypes = 'number' | 'string' | 'number[]' | 'bool' | 'shape' | 'tensor' | 'tensors' | 'dtype'; | ||
@@ -39,2 +39,3 @@ export declare type Category = 'arithmetic' | 'basic_math' | 'convolution' | 'creation' | 'graph' | 'logical' | 'matrices' | 'normalization' | 'reduction' | 'slice_join' | 'transformation'; | ||
outputs: Node[]; | ||
withControlFlow: boolean; | ||
} | ||
@@ -41,0 +42,0 @@ export declare type ValueType = string | string[] | number | number[] | boolean | boolean[] | Tensor | Tensor[]; |
@@ -1,2 +0,2 @@ | ||
declare const version = "0.1.0"; | ||
declare const version = "0.0.2"; | ||
export { version }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var version = '0.1.0'; | ||
var version = '0.0.2'; | ||
exports.version = version; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "@tensorflow/tfjs-converter", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Tensorflow model converter for javascript", | ||
@@ -11,9 +11,10 @@ "main": "dist/index.js", | ||
"type": "git", | ||
"url": "https://github.com/tensorflow/web.git" | ||
"url": "https://github.com/tensorflow/tfjs-converter.git" | ||
}, | ||
"license": "Apache-2.0", | ||
"peerDependencies": { | ||
"deeplearn": "next" | ||
"@tensorflow/tfjs-core": "0.0.1" | ||
}, | ||
"devDependencies": { | ||
"@tensorflow/tfjs-core": "0.0.1", | ||
"@types/jasmine": "~2.8.6", | ||
@@ -26,3 +27,2 @@ "@types/seedrandom": "~2.4.27", | ||
"cross-spawn": "~6.0.4", | ||
"deeplearn": "next", | ||
"deeplearn-src": "git+https://github.com/PAIR-code/deeplearnjs.git#c24c1e6959faffac5b676bb5cee64f9745577bb0", | ||
@@ -51,2 +51,3 @@ "handlebars": "~4.0.11", | ||
"scripts": { | ||
"prep": "yarn && mkdirp dist", | ||
"build": "tsc && copyfiles -f src/data/compiled_api.* dist/data && copyfiles -f src/operations/op_list/*.json dist/operations/op_list && copyfiles -f src/operations/typings.d.ts dist/operations", | ||
@@ -53,0 +54,0 @@ "build-npm": "./scripts/build-npm.sh", |
101
README.md
@@ -5,20 +5,67 @@ # Getting started | ||
It has two main pieces: | ||
1. [Coversion Python script](./scripts/convert.py), converts your Tensorflow SavedModel to web friendly format. | ||
2. [Javascript API](./src/executor/tf_model.ts), simple one line API for inference. | ||
## Dependencies | ||
The python conversion script requires following packages: | ||
## Inference with converted models | ||
There are three types of files: | ||
* web_model.pb (model) | ||
* weights_manifest.json (weight manifest file) | ||
* group1-shard\*of\* (collection of weight files) | ||
Remember to serve the manifest and weight files with the same url path. | ||
For example, we have the mobilenet models converted and served for you in following location: | ||
```html | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/optimized_model.pb | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/weights_manifest.json | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard1of5 | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard2of5 | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard3of5 | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard4of5 | ||
https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard5of5 | ||
``` | ||
1. Install the tfjs-converter npm package | ||
`yarn add @tensorflow/tfjs-converter` or `npm install @tensorflow/tfjs-converter` | ||
2. Instantiate the [TFModel class](./src/executor/tf_model.ts) and run inference. [Example](./demo/mobilenet.ts) | ||
```typescript | ||
import {TFModel} from 'tfjs-converter'; | ||
const MODEL_FILE_URL = 'http://example.org/models/mobilenet/web_model.pb'; | ||
const WEIGHT_MANIFEST_FILE_URL = 'http://example.org/models/mobilenet/weights_manifest.json'; | ||
const model = new TFModel(MODEL_FILE_URL, WEIGHT_MANIFEST_FILE_URL); | ||
const cat = document.getElementById('cat'); | ||
model.predict({input: tf.fromPixels(cat)}); // run the inference on your model. | ||
``` | ||
## Convert your own Tensorflow pre-trained model in [SavedModel](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md) format | ||
### Dependencies | ||
1. Clone the github repo: | ||
```bash | ||
$ pip install tensorflow numpy absl-py protobuf | ||
$ git clone git@github.com:tensorflow/tfjs-converter.git | ||
``` | ||
## Usage | ||
2. Install following pip packages: | ||
1. `yarn add @tensorflow/tfjs-converter` or `npm install @tensorflow/tfjs-converter` | ||
```bash | ||
$ pip install tensorflow numpy absl-py protobuf | ||
``` | ||
2. Use the scripts/convert.py to convert your Tensorflow [SavedModel](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md). | ||
### Conversion | ||
```bash | ||
$ python node_modules/@tensorflow/tfjs-converter/scripts/convert.py --saved_model_dir=/tmp/mobilenet/ --output_node_names='MobilenetV1/Predictions/Reshape_1' --output_graph=/tmp/mobilenet/web_model.pb --saved_model_tags=serve | ||
$ cd tfjs-converter/ | ||
$ python scripts/convert.py --saved_model_dir=/tmp/mobilenet/ --output_node_names='MobilenetV1/Predictions/Reshape_1' --output_graph=/tmp/mobilenet/web_model.pb --saved_model_tags=serve | ||
``` | ||
@@ -33,3 +80,2 @@ | ||
### Outputs | ||
@@ -39,2 +85,3 @@ | ||
In the above example, generated files are: | ||
* web_model.pb (model) | ||
@@ -44,24 +91,30 @@ * weights_manifest.json (weight manifest file) | ||
You need to have the model, weight manifest and weight files accessible through url. | ||
And the manifest and weight files should share the the same url path. For example: | ||
You can serve these files similarly as shown in the inference [example] (./demo). | ||
``` | ||
http://example.org/models/mobilenet/weights_manifest.json | ||
http://example.org/models/mobilenet/group1-shard1of2 | ||
http://example.org/models/mobilenet/group1-shard2of2 | ||
``` | ||
### Limitations | ||
3. Instantiate the [TFModel class](./src/executor/tf_model.ts) and run inference. [Example](./demo/mobilenet.ts) | ||
Currently Tensorflow.js only supports a limit set of Tensorflow Ops, here is the [full list](./docs/supported_ops.md). | ||
When you converting model with any unsupported Ops, the convert.py script will prompt the unsupported Ops list at the end of the execution. Please fill bugs to let us know what Ops you need support with. | ||
```typescript | ||
import {TFModel} from 'tfjs-converter'; | ||
const MODEL_FILE_URL = 'http://example.org/models/mobilenet/web_model.pb'; | ||
const WEIGHT_MANIFEST_FILE_URL = 'http://example.org/models/mobilenet/weights_manifest.json'; | ||
## FAQ | ||
const model = new TFModel(MODEL_FILE_URL, WEIGHT_MANIFEST_FILE_URL); | ||
const cat = document.getElementById('cat'); | ||
model.predict({input: dl.fromPixels(cat)}) // run the inference on your model. | ||
``` | ||
1. What Tensorflow models does the converter currently support? | ||
Image-based models (MobileNet, SqueezeNet, add more if you tested) are the most supported. Models with control flow ops (e.g. RNNs) are not yet supported. The convert.py script will validate the model you have and show a list of unsupported ops in your model. See [this list](./docs/supported_ops.md) for which ops are currently supported. | ||
2. Will model with large weights work? | ||
While the browser supports loading 100-500MB models, the page load time, the inference time and the user experience would not be great. We recommend using models that are designed for edge devices (e.g. phones). These models are usually smaller than 30MB. | ||
3. Will the model and weight files be cached in the browser? | ||
Yes, we are splitting the weights into files of 4MB chunks, which enable the browser to cache them automatically. If the model architecture is less than 4MB (most models are), it will also be cached. | ||
4. Will it support model with quantization? | ||
Not yet. We are planning to add quantization support soon. | ||
5. | ||
## Development | ||
@@ -68,0 +121,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2575004
74
44291
156