blob: 61619ddfe07409cbb122e6681adda0944d8f28cb [file] [log] [blame]
"use strict";
var tf = _interopRequireWildcard(tfjsRequire("@tensorflow/tfjs"));
var use = _interopRequireWildcard(tfjsRequire("@tensorflow-models/universal-sentence-encoder"));
var cocoSsd = _interopRequireWildcard(tfjsRequire("@tensorflow-models/coco-ssd"));
var _tfjsBackendWasm = tfjsRequire("@tensorflow/tfjs-backend-wasm");
var _mobilenetInput = tfjsRequire("./mobilenet-input");
// FIXME: This is speculative fix for jetsams on iOS devices.
// It seems that loading model in each iteration increases
// memory usage on both Safari and Chrome.
globalThis.models = {
use: null,
cocoSsd: null,
knn: null,
mobilenet_v1: null,
mobilenet_v3: null
};
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function")
return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function (nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
}
)(nodeInterop);
}
function _interopRequireWildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for (var key in obj) {
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const WASM_TFJS_DIR = './wasm/';
const loadAndPredict_mobilenet = async () => {
// -------------- Load pre-trained mobilenet model --------------
if (!models.mobilenet_v3) {
// https://tfhub.dev/google/tfjs-model/imagenet/mobilenet_v2_100_224/classification/3/default/1
models.mobilenet_v3 = await tf.loadGraphModel('wasm-tfjs-mobilenet', { fromTFHub: true });
globalThis.MOBILENET_ARTIFACTS_V3 = null;
}
const model = models.mobilenet_v3;
// -------------- Load image data --------------
const imageSize = 224;
const imageObject = {
data: _mobilenetInput.mobilenetInputData,
width: imageSize,
height: imageSize
};
// -------------- Prediction --------------
const startTime = performance.now();
model.predict(tf.zeros([1, imageSize, imageSize, 3])).dispose();
tf.tidy(() => {
const img = tf.cast(tf.browser.fromPixels(imageObject), 'float32');
const offset = tf.scalar(127.5);
const normalized = img.sub(offset).div(offset);
const batched = normalized.reshape([1, imageSize, imageSize, 3]);
return model.predict(batched);
}
);
const totalTime = Math.max(1, performance.now() - startTime);
return totalTime;
};
const loadAndPredict_knn = async () => {
// -------------- Load pre-trained KNN classifier model --------------
if (!models.knn) {
// https://www.npmjs.com/package/@tensorflow-models/mobilenet
models.mobilenet_v1 = await tfjsRequire('@tensorflow-models/mobilenet').load();
// https://www.npmjs.com/package/@tensorflow-models/knn-classifier
models.knn = tfjsRequire('@tensorflow-models/knn-classifier').create();
globalThis.MOBILENET_ARTIFACTS_V1 = null;
}
const classifier = models.knn;
const mobilenet = models.mobilenet_v1;
// -------------- Load image data --------------
const imageSize = 224;
const imageObject = {
data: _mobilenetInput.mobilenetInputData,
width: imageSize,
height: imageSize
};
// -------------- Prediction --------------
const startTime = performance.now();
tf.cast(tf.browser.fromPixels(imageObject), 'float32');
const logits0 = mobilenet.infer(tf.browser.fromPixels(imageObject), true);
classifier.addExample(logits0, 0);
const logits1 = mobilenet.infer(tf.browser.fromPixels(imageObject), true);
classifier.addExample(logits1, 1);
mobilenet.infer(tf.browser.fromPixels(imageObject), true);
const totalTime = Math.max(1, performance.now() - startTime);
return totalTime;
};
const loadAndPredict_cocoSsd = async () => {
// -------------- Load pre-trained cocoSsd model --------------
// https://www.npmjs.com/package/@tensorflow-models/coco-ssd
if (!models.cocoSsd) {
models.cocoSsd = await cocoSsd.load();
globalThis.COCO_SSD_ARTIFACTS == null;
}
const model = models.cocoSsd;
// -------------- Load image data --------------
const imageSize = 224;
const imageObject = {
data: _mobilenetInput.mobilenetInputData,
width: imageSize,
height: imageSize
};
// -------------- Prediction --------------
const startTime = performance.now();
await model.detect(imageObject);
const totalTime = Math.max(1, performance.now() - startTime);
return totalTime;
};
const loadAndPredict_use = async () => {
// -------------- Load pre-trained universal-sentence-encoder model --------------
// https://www.npmjs.com/package/@tensorflow-models/universal-sentence-encoder
if (!models.use) {
models.use = await use.loadQnA();
globalThis.USE_ARTIFACTS = null;
globalThis.USE_VOCAB_JSON = null;
}
const model = models.use;
// -------------- Load text data --------------
const input = {
queries: ['How are you feeling today?'],
responses: ['I\'m not feeling very well.', 'Beijing is the capital of China.', 'You have five fingers on your hand.']
};
// -------------- Prediction --------------
const startTime = performance.now();
let result = model.embed(input);
tf.matMul(result['queryEmbedding'], result['responseEmbedding'], false, true).dataSync();
const totalTime = Math.max(1, performance.now() - startTime);
return totalTime;
};
globalThis.setWasmBackend = async () => {
// https://github.com/tensorflow/tfjs/tree/master/tfjs-backend-wasm
// https://github.com/tensorflow/tfjs-models
_tfjsBackendWasm.setWasmPaths(WASM_TFJS_DIR, (path) => {
console.log("Fetching " + path)
});
let value = await tf.setBackend('wasm')
if (!value)
throw new Error("Should use wasm backend.");
await loadAndPredict();
};
globalThis.loadAndPredict = async () => {
let result = 0.0;
result += await loadAndPredict_mobilenet();
result += await loadAndPredict_knn();
result += await loadAndPredict_cocoSsd();
result += await loadAndPredict_use();
return result;
};