add benchmark info

pull/193/head
Vladimir Mandic 2021-09-05 16:42:11 -04:00
parent e54304e61a
commit bb8785b3d4
17 changed files with 147603 additions and 3225 deletions

View File

@ -6,6 +6,7 @@ WebGL shader optimizations for faster load and initial detection
- Implement WebGL uniforms for shaders: <https://github.com/tensorflow/tfjs/issues/5205> - Implement WebGL uniforms for shaders: <https://github.com/tensorflow/tfjs/issues/5205>
- Fix shader packing: <https://github.com/tensorflow/tfjs/issues/5343> - Fix shader packing: <https://github.com/tensorflow/tfjs/issues/5343>
- Event emitters
<br> <br>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Human</title>
<meta name="viewport" content="width=device-width" id="viewport">
<meta name="keywords" content="Human">
<meta name="application-name" content="Human">
<meta name="description" content="Human: 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction, Emotion Prediction & Gesture Recognition; Author: Vladimir Mandic <https://github.com/vladmandic>">
<meta name="msapplication-tooltip" content="Human: 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction, Emotion Prediction & Gesture Recognition; Author: Vladimir Mandic <https://github.com/vladmandic>">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="../manifest.webmanifest">
<link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="../../assets/icon.png">
<script type="module" src="browser.js"></script>
<style>
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 100; src: local('Lato'), url('../../assets/lato-light.woff2') }
html { font-family: 'Lato', 'Segoe UI'; font-size: 16px; font-variant: small-caps; }
body { margin: 0; background: black; color: white; overflow-x: hidden; width: 100vw; height: 100vh; }
body::-webkit-scrollbar { display: none; }
.status { position: absolute; width: 100vw; bottom: 10%; text-align: center; font-size: 3rem; font-weight: 100; text-shadow: 2px 2px #303030; }
.log { position: absolute; bottom: 0; margin: 0.4rem 0.4rem 0 0.4rem; font-size: 0.9rem; }
</style>
</head>
<body>
<div id="status" class="status"></div>
<img id="image" src="../../samples/groups/group1.jpg" style="display: none"></img>
<div id="log" class="log"></div>
</body>
</html>

51
demo/benchmark/browser.js Normal file
View File

@ -0,0 +1,51 @@
// import * as tf from '../../assets/tf.es2017.js';
// import '../../assets/tf-backend-webgpu.es2017.js';
import Human from '../../dist/human.esm.js';
const loop = 20;
// eslint-disable-next-line no-console
const log = (...msg) => console.log(...msg);
const myConfig = {
backend: 'humangl',
modelBasePath: 'https://vladmandic.github.io/human/models',
wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.9.0/dist/',
debug: true,
async: true,
cacheSensitivity: 0,
filter: { enabled: false },
face: {
enabled: true,
detector: { enabled: true, rotation: false },
mesh: { enabled: true },
iris: { enabled: true },
description: { enabled: true },
emotion: { enabled: false },
},
hand: { enabled: true, rotation: false },
body: { enabled: true },
object: { enabled: false },
};
async function main() {
const human = new Human(myConfig);
await human.tf.ready();
log('Human:', human.version);
await human.load();
const loaded = Object.keys(human.models).filter((a) => human.models[a]);
log('Loaded:', loaded);
log('Memory state:', human.tf.engine().memory());
const element = document.getElementById('image');
const processed = await human.image(element);
const t0 = performance.now();
await human.detect(processed.tensor, myConfig);
const t1 = performance.now();
log('Backend:', human.tf.getBackend());
log('Warmup:', Math.round(t1 - t0));
for (let i = 0; i < loop; i++) await human.detect(processed.tensor, myConfig);
const t2 = performance.now();
log('Average:', Math.round((t2 - t1) / loop));
}
main();

71
demo/benchmark/node.js Normal file
View File

@ -0,0 +1,71 @@
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node-gpu');
const log = require('@vladmandic/pilogger');
const canvasJS = require('canvas');
const Human = require('../../dist/human.node-gpu.js').default;
const input = 'samples/groups/group1.jpg';
const loop = 20;
const myConfig = {
backend: 'tensorflow',
modelBasePath: 'https://vladmandic.github.io/human/models',
wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.9.0/dist/',
debug: true,
async: true,
cacheSensitivity: 0,
filter: { enabled: false },
face: {
enabled: true,
detector: { enabled: true, rotation: false },
mesh: { enabled: true },
iris: { enabled: true },
description: { enabled: true },
emotion: { enabled: true },
},
hand: {
enabled: true,
},
body: { enabled: true },
object: { enabled: false },
};
async function getImage(human) {
const img = await canvasJS.loadImage(input);
const canvas = canvasJS.createCanvas(img.width, img.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const res = human.tf.tidy(() => {
const tensor = human.tf.tensor(Array.from(imageData.data), [canvas.height, canvas.width, 4], 'int32'); // create rgba image tensor from flat array
const channels = human.tf.split(tensor, 4, 2); // split rgba to channels
const rgb = human.tf.stack([channels[0], channels[1], channels[2]], 2); // stack channels back to rgb
const reshape = human.tf.reshape(rgb, [1, canvas.height, canvas.width, 3]); // move extra dim from the end of tensor and use it as batch number instead
return reshape;
});
log.info('Image:', input, res.shape);
return res;
}
async function main() {
log.header();
const human = new Human(myConfig);
await human.tf.ready();
log.info('Human:', human.version);
await human.load();
const loaded = Object.keys(human.models).filter((a) => human.models[a]);
log.info('Loaded:', loaded);
log.info('Memory state:', human.tf.engine().memory());
const tensor = await getImage(human);
log.state('Processing:', tensor['shape']);
const t0 = performance.now();
await human.detect(tensor, myConfig);
const t1 = performance.now();
log.state('Backend:', human.tf.getBackend());
log.data('Warmup:', Math.round(t1 - t0));
for (let i = 0; i < loop; i++) await human.detect(tensor, myConfig);
const t2 = performance.now();
log.data('Average:', Math.round((t2 - t1) / loop));
}
main();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

69555
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

69583
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -11771,7 +11771,7 @@ var version = "2.1.5";
// src/human.ts // src/human.ts
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
var _Human = class { var Human = class {
constructor(userConfig) { constructor(userConfig) {
__privateAdd(this, _numTensors, void 0); __privateAdd(this, _numTensors, void 0);
__privateAdd(this, _analyzeMemoryLeaks, void 0); __privateAdd(this, _analyzeMemoryLeaks, void 0);
@ -11973,7 +11973,7 @@ var _Human = class {
} }
return res; return res;
}); });
_Human.version = version; this.version = version;
Object.defineProperty(this, "version", { value: version }); Object.defineProperty(this, "version", { value: version });
config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`; config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`;
this.config = mergeDeep(config, userConfig || {}); this.config = mergeDeep(config, userConfig || {});
@ -12028,7 +12028,7 @@ var _Human = class {
this.config = mergeDeep(this.config, userConfig); this.config = mergeDeep(this.config, userConfig);
if (__privateGet(this, _firstRun)) { if (__privateGet(this, _firstRun)) {
if (this.config.debug) if (this.config.debug)
log(`version: ${_Human.version}`); log(`version: ${this.version}`);
if (this.config.debug) if (this.config.debug)
log(`tfjs version: ${this.tf.version_core}`); log(`tfjs version: ${this.tf.version_core}`);
if (this.config.debug) if (this.config.debug)
@ -12230,7 +12230,6 @@ var _Human = class {
return res; return res;
} }
}; };
var Human = _Human;
_numTensors = new WeakMap(); _numTensors = new WeakMap();
_analyzeMemoryLeaks = new WeakMap(); _analyzeMemoryLeaks = new WeakMap();
_checkSanity = new WeakMap(); _checkSanity = new WeakMap();

View File

@ -11772,7 +11772,7 @@ var version = "2.1.5";
// src/human.ts // src/human.ts
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
var _Human = class { var Human = class {
constructor(userConfig) { constructor(userConfig) {
__privateAdd(this, _numTensors, void 0); __privateAdd(this, _numTensors, void 0);
__privateAdd(this, _analyzeMemoryLeaks, void 0); __privateAdd(this, _analyzeMemoryLeaks, void 0);
@ -11974,7 +11974,7 @@ var _Human = class {
} }
return res; return res;
}); });
_Human.version = version; this.version = version;
Object.defineProperty(this, "version", { value: version }); Object.defineProperty(this, "version", { value: version });
config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`; config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`;
this.config = mergeDeep(config, userConfig || {}); this.config = mergeDeep(config, userConfig || {});
@ -12029,7 +12029,7 @@ var _Human = class {
this.config = mergeDeep(this.config, userConfig); this.config = mergeDeep(this.config, userConfig);
if (__privateGet(this, _firstRun)) { if (__privateGet(this, _firstRun)) {
if (this.config.debug) if (this.config.debug)
log(`version: ${_Human.version}`); log(`version: ${this.version}`);
if (this.config.debug) if (this.config.debug)
log(`tfjs version: ${this.tf.version_core}`); log(`tfjs version: ${this.tf.version_core}`);
if (this.config.debug) if (this.config.debug)
@ -12231,7 +12231,6 @@ var _Human = class {
return res; return res;
} }
}; };
var Human = _Human;
_numTensors = new WeakMap(); _numTensors = new WeakMap();
_analyzeMemoryLeaks = new WeakMap(); _analyzeMemoryLeaks = new WeakMap();
_checkSanity = new WeakMap(); _checkSanity = new WeakMap();

7
dist/human.node.js vendored
View File

@ -11771,7 +11771,7 @@ var version = "2.1.5";
// src/human.ts // src/human.ts
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
var _Human = class { var Human = class {
constructor(userConfig) { constructor(userConfig) {
__privateAdd(this, _numTensors, void 0); __privateAdd(this, _numTensors, void 0);
__privateAdd(this, _analyzeMemoryLeaks, void 0); __privateAdd(this, _analyzeMemoryLeaks, void 0);
@ -11973,7 +11973,7 @@ var _Human = class {
} }
return res; return res;
}); });
_Human.version = version; this.version = version;
Object.defineProperty(this, "version", { value: version }); Object.defineProperty(this, "version", { value: version });
config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`; config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`;
this.config = mergeDeep(config, userConfig || {}); this.config = mergeDeep(config, userConfig || {});
@ -12028,7 +12028,7 @@ var _Human = class {
this.config = mergeDeep(this.config, userConfig); this.config = mergeDeep(this.config, userConfig);
if (__privateGet(this, _firstRun)) { if (__privateGet(this, _firstRun)) {
if (this.config.debug) if (this.config.debug)
log(`version: ${_Human.version}`); log(`version: ${this.version}`);
if (this.config.debug) if (this.config.debug)
log(`tfjs version: ${this.tf.version_core}`); log(`tfjs version: ${this.tf.version_core}`);
if (this.config.debug) if (this.config.debug)
@ -12230,7 +12230,6 @@ var _Human = class {
return res; return res;
} }
}; };
var Human = _Human;
_numTensors = new WeakMap(); _numTensors = new WeakMap();
_analyzeMemoryLeaks = new WeakMap(); _analyzeMemoryLeaks = new WeakMap();
_checkSanity = new WeakMap(); _checkSanity = new WeakMap();

4
dist/tfjs.esm.js vendored
View File

@ -2173,9 +2173,9 @@ var require_seedrandom4 = __commonJS({
} }
}); });
// (disabled):node_modules/.pnpm/string_decoder@1.3.0/node_modules/string_decoder/lib/string_decoder.js // (disabled):node_modules/.pnpm/string_decoder@1.1.1/node_modules/string_decoder/lib/string_decoder.js
var require_string_decoder = __commonJS({ var require_string_decoder = __commonJS({
"(disabled):node_modules/.pnpm/string_decoder@1.3.0/node_modules/string_decoder/lib/string_decoder.js"() { "(disabled):node_modules/.pnpm/string_decoder@1.1.1/node_modules/string_decoder/lib/string_decoder.js"() {
} }
}); });

File diff suppressed because one or more lines are too long

View File

@ -73,7 +73,7 @@
"canvas": "^2.8.0", "canvas": "^2.8.0",
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
"dayjs": "^1.10.6", "dayjs": "^1.10.6",
"esbuild": "^0.12.24", "esbuild": "^0.12.25",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1", "eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.24.2", "eslint-plugin-import": "^2.24.2",
@ -83,7 +83,7 @@
"node-fetch": "^3.0.0", "node-fetch": "^3.0.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"seedrandom": "^3.0.5", "seedrandom": "^3.0.5",
"simple-git": "^2.45.0", "simple-git": "^2.45.1",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typedoc": "0.21.9", "typedoc": "0.21.9",
"typescript": "4.4.2" "typescript": "4.4.2"

View File

@ -62,7 +62,7 @@ export type TensorFlow = typeof tf;
*/ */
export class Human { export class Human {
/** Current version of Human library in *semver* format */ /** Current version of Human library in *semver* format */
static version: string; version: string;
/** Current configuration /** Current configuration
* - Details: {@link Config} * - Details: {@link Config}
*/ */
@ -148,7 +148,7 @@ export class Human {
* @param userConfig: {@link Config} * @param userConfig: {@link Config}
*/ */
constructor(userConfig?: Config | Record<string, unknown>) { constructor(userConfig?: Config | Record<string, unknown>) {
Human.version = app.version; // expose version property on instance of class this.version = app.version; // expose version property on instance of class
Object.defineProperty(this, 'version', { value: app.version }); // expose version property directly on class itself Object.defineProperty(this, 'version', { value: app.version }); // expose version property directly on class itself
defaults.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`; defaults.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`;
this.config = mergeDeep(defaults, userConfig || {}); this.config = mergeDeep(defaults, userConfig || {});
@ -270,7 +270,7 @@ export class Human {
if (userConfig) this.config = mergeDeep(this.config, userConfig) as Config; if (userConfig) this.config = mergeDeep(this.config, userConfig) as Config;
if (this.#firstRun) { // print version info on first run and check for correct backend setup if (this.#firstRun) { // print version info on first run and check for correct backend setup
if (this.config.debug) log(`version: ${Human.version}`); if (this.config.debug) log(`version: ${this.version}`);
if (this.config.debug) log(`tfjs version: ${this.tf.version_core}`); if (this.config.debug) log(`tfjs version: ${this.tf.version_core}`);
if (this.config.debug) log('platform:', this.sysinfo.platform); if (this.config.debug) log('platform:', this.sysinfo.platform);
if (this.config.debug) log('agent:', this.sysinfo.agent); if (this.config.debug) log('agent:', this.sysinfo.agent);

2
wiki

@ -1 +1 @@
Subproject commit 7f55fd1c8aea22f33a767da840147b15aeeed034 Subproject commit 82ce7a69656a11fa4cd5c5bea447cd1a2797b903