pull/19/head
Vladimir Mandic 2020-12-02 15:56:29 -05:00
parent 006678b6c8
commit d82c04870d
7 changed files with 490 additions and 15 deletions

227
README copy.md Normal file
View File

@ -0,0 +1,227 @@
# FaceAPI
## Note
This is updated **face-api.js** with latest available TensorFlow/JS as the original face-api.js is not compatible with **tfjs 2.0+**.
Forked from **face-api.js** version **0.22.2** released on March 22nd, 2020
- <https://github.com/justadudewhohacks/face-api.js>
- <https://www.npmjs.com/package/face-api.js>
Currently based on **`TensorFlow/JS` 2.7.0**
If you want to access `TFJS` classes and methods directly, they are exported as `faceapi.tf`
### Why?
Because I needed FaceAPI that does not cause version conflict with newer TFJS 2.0 that I use accross my projects
And since original FaceAPI was open-source, I've released this version as well
Unfortunately, changes ended up being too large for a simple pull request on original FaceaPI and it ended up being a full-fledged version on its own
### Differences
- Compatible with `TensorFlow/JS 2.0+`
- Compatible with `WebGL`, `CPU` and `WASM` TFJS backends
- Updated all type castings for TypeScript type checking to `TypeScript 4.1`
- Switched bundling from `UMD` to `ESM` + `CommonJS`
This does require separate process for usage in NodeJS vs Browser, but resulting code is much lighter
Fully tree shakable when imported as an `ESM` module
Browser bundle process uses `ESBuild` instead of `Rollup`
- Typescript build process now targets `ES2018` and instead of dual ES5/ES6
Resulting code is clean ES2018 JavaScript without polyfills
- Removed old tests, docs, examples
- Removed old package dependencies (`karma`, `jasmine`, `babel`, etc.)
- Updated all package dependencies
- Updated TensorFlow/JS dependencies since backends were removed from `@tensorflow/tfjs-core`
- Updated mobileNetv1 model due to `batchNorm()` dependency
- Added `version` class that returns JSON object with version of FaceAPI as well as linked TFJS
- Removed `mtcnn` and `tinyYolov2` models as they were non-functional in latest public version of `Face-API`
*If there is a demand, I can re-implement them back.*
Which means valid models are **tinyFaceDetector** and **mobileNetv1**
## Installation
Face-API ships with several pre-build versions of the library:
- `dist/face-api.js`: IIFE format for client-side Browser execution *with* TFJS pre-bundled
- `dist/face-api.esm.js`: ESM format for client-side Browser execution *with* TFJS pre-bundled
- `dist/face-api.esm.nobundle.js`: ESM format for client-side Browser execution *without* TFJS pre-bundled
- `dist/face-api.node.js`: CommonJS format for server-side NodeJS execution *without* TFJS pre-bundled
Defaults are:
```json
{
"main": "dist/face-api.cjs",
"module": "dist/face-api.esm.js",
"browser": "dist/face-api.esm.js",
}
```
Reason for additional `nobundle` version is if you want to include a specific version of TFJS and not rely on pre-packaged one
`FaceAPI` is compatible with TFJS 2.0+
Bundled versions are ~1.1MB minified and non-bundled versions are ~169KB non-minified
All versions include `sourcemap`
There are several ways to use Face-API:
### 1. IIFE script
*Recommened for quick tests and backward compatibility with older Browsers that do not support ESM such as IE*
This is simplest way for usage within Browser
Simply download `dist/face-api.js`, include it in your `HTML` file & it's ready to use
```html
<script src="dist/face-api.js"><script>
```
IIFE script bundles TFJS and auto-registers global namespace `faceapi` within Window object which can be accessed directly from a `<script>` tag or from your JS file.
### 2. ESM module
*Recommended for usage within Browser*
#### 2.1. Direct Import
To use ESM import directly in a Browser, you must import your script (e.g. `index.js`) with a `type="module"`
```html
<script src="./index.js" type="module">
```
and then in your `index.js`
```js
import * as faceapi from 'dist/face-api.esm.js';
```
or to use non-bundled version:
```js
import * as tf from `https://cdnjs.cloudflare.com/ajax/libs/tensorflow/2.7.0/tf.es2017.min.js`; // load tfjs directly from CDN link
import * as faceapi from 'dist/face-api.nobundle.js';
```
#### 2.2. With Bundler
Same as above, but expectation is that you've installed `@vladmandic/faceapi` package
and that you'll package your script using a bundler such as `webpack`, `rollup` or `esbuild`
in which case, you do not need to import a script as module - that depends on your bundler configuration
```js
import * as faceapi from '@vladmandic/face-api';
```
or if your bundler doesn't recognize `recommended` type, force usage with:
```js
import * as faceapi from '@vladmandic/face-api/dist/face-api.esm.js';
```
or to use non-bundled version
```js
import * as tf from `@tensorflow/tfjs`;
import * as faceapi from '@vladmandic/face-api/dist/face-api.nobundle.js';
```
### 3. NPM module
#### 3.1. Import CommonJS
*Recommended for NodeJS projects*
*Node: Face-API for NodeJS does not bundle TFJS due to binary dependencies that are installed during TFJS installation*
Install with:
```shell
npm install @tensorflow/tfjs-node
npm install @vladmandic/face-api
```
And then use with:
```js
const tf = require('@tensorflow/tfjs-node')
const faceapi = require('@vladmandic/face-api');
```
- if you want to CUDA GPU Accelerated NodeJS, import `tfjs-node-gpu` instead of `tfjs-node`
This requires that system is CUDA enabled and has CUDA libraries already installed.
- If you want to force CommonJS module instead of relying on `recommended` field:
```js
const faceapi = require('@vladmandic/face-api/dist/face-api.node.js');
```
### 4. Import Sources
*Recommended for complex NodeJS projects that use TFJS for other purposes and not just FaceaPI*
This way you're importing FaceAPI sources directly and not a bundle, so you have to import `@tensorflow/tfjs` explicitly
#### 4.1. For Browser with Bundler
##### 4.1.1. For JavaScript projects
```js
import * as tf from '@tensorflow/tfjs';
import * as faceapi from '@vladmandic/face-api/build/index.js';
```
##### 4.1.2. For TypeScript projects
```js
import * as tf from '@tensorflow/tfjs';
import * as faceapi from '@vladmandic/face-api/src/index.ts';
```
#### 4.2. For NodeJS
##### 4.2.1. For JavaScript projects
```js
const tf = require('@tensorflow/tfjs');
const faceapi = require('@vladmandic/face-api/build/index.js');
```
##### 4.1.2. For TypeScript projects
```js
const tf = require('@tensorflow/tfjs');
const faceapi = require('@vladmandic/face-api/src/index.ts');
```
## Weights
Pretrained models and their weights are includes in `./model`.
## Build
If you want to do a full rebuild, either download npm module
```shell
npm install @vladmandic/face-api
cd node_modules/@vladmandic/face-api
```
or clone a git project
```shell
git clone https://github.com/vladmandic/face-api
cd face-api
```
Then install all dependencies and run rebuild:
```shell
npm install
npm run build
```
Which will compile everything in `./src` into `./build` and create both ESM (standard) and IIFE (minified) bundles as well as sourcemaps in `./dist`
## Credits & Documentation
- Original documentation: [Face-API](https://github.com/justadudewhohacks/face-api.js)
- Original model weighs: [Face-API](https://github.com/justadudewhohacks/face-api.js-models)
- ML API Documentation: [Tensorflow/JS](https://js.tensorflow.org/api/latest/)
## Example
### Browser
Example that uses both models as well as all of the extensions is included in `/example/index.html`
Example can be accessed directly using Git pages using URL: <https://vladmandic.github.io/face-api/example/>
### NodeJS
Example is included in `/example/node.js`
Note that it does not require any other other 3rd party libraries
*Note: Photos shown below are taken by me*
![alt text](example/screenshot.png)

177
build.js Normal file
View File

@ -0,0 +1,177 @@
#!/usr/bin/env -S node --trace-warnings
const fs = require('fs');
const esbuild = require('esbuild');
const log = require('@vladmandic/pilogger');
// keeps esbuild service instance cached
let es;
const banner = `
/*
Face-API
homepage: <https://github.com/vladmandic/face-api>
author: <https://github.com/vladmandic>'
*/
`;
// common configuration
const common = {
banner,
minifyWhitespace: true,
minifySyntax: true,
bundle: true,
sourcemap: true,
logLevel: 'error',
target: 'es2018',
tsconfig: './tsconfig.json',
};
const targets = {
node: {
tfjs: {
platform: 'node',
format: 'cjs',
metafile: 'dist/tfjs.esm.json',
entryPoints: ['src/tfjs/tf-node.js'],
outfile: 'dist/tfjs.esm.js',
external: ['@tensorflow'],
},
node: {
platform: 'node',
format: 'cjs',
metafile: 'dist/human.node.json',
entryPoints: ['src/human.js'],
outfile: 'dist/human.node.js',
external: ['@tensorflow'],
},
},
nodeGPU: {
tfjs: {
platform: 'node',
format: 'cjs',
metafile: 'dist/tfjs.esm.json',
entryPoints: ['src/tfjs/tf-node-gpu.js'],
outfile: 'dist/tfjs.esm.js',
external: ['@tensorflow'],
},
node: {
platform: 'node',
format: 'cjs',
metafile: 'dist/human.node.json',
entryPoints: ['src/human.js'],
outfile: 'dist/human.node-gpu.js',
external: ['@tensorflow'],
},
},
browserNoBundle: {
tfjs: {
platform: 'browser',
format: 'esm',
metafile: 'dist/tfjs.esm.json',
entryPoints: ['src/tfjs/tf-browser.js'],
outfile: 'dist/tfjs.esm.js',
external: ['fs', 'buffer', 'util', '@tensorflow'],
},
esm: {
platform: 'browser',
format: 'esm',
metafile: 'dist/human.esm.json',
entryPoints: ['src/human.js'],
outfile: 'dist/human.esm-nobundle.js',
external: ['fs', 'buffer', 'util', '@tensorflow'],
},
},
browserBundle: {
tfjs: {
platform: 'browser',
format: 'esm',
metafile: 'dist/tfjs.esm.json',
entryPoints: ['src/tfjs/tf-browser.js'],
outfile: 'dist/tfjs.esm.js',
external: ['fs', 'buffer', 'util'],
},
iife: {
platform: 'browser',
format: 'iife',
globalName: 'Human',
metafile: 'dist/human.json',
entryPoints: ['src/human.js'],
outfile: 'dist/human.js',
external: ['fs', 'buffer', 'util'],
},
esm: {
platform: 'browser',
format: 'esm',
metafile: 'dist/human.esm.json',
entryPoints: ['src/human.js'],
outfile: 'dist/human.esm.js',
external: ['fs', 'buffer', 'util'],
},
demo: {
platform: 'browser',
format: 'esm',
metafile: 'dist/demo-browser-index.json',
entryPoints: ['demo/browser.js'],
outfile: 'dist/demo-browser-index.js',
external: ['fs', 'buffer', 'util'],
},
},
};
async function getStats(metafile) {
const stats = {};
if (!fs.existsSync(metafile)) return stats;
const data = fs.readFileSync(metafile);
const json = JSON.parse(data);
if (json && json.inputs && json.outputs) {
for (const [key, val] of Object.entries(json.inputs)) {
if (key.startsWith('node_modules')) {
stats.modules = (stats.modules || 0) + 1;
stats.moduleBytes = (stats.moduleBytes || 0) + val.bytes;
} else {
stats.imports = (stats.imports || 0) + 1;
stats.importBytes = (stats.importBytes || 0) + val.bytes;
}
}
const files = [];
for (const [key, val] of Object.entries(json.outputs)) {
if (!key.endsWith('.map')) {
files.push(key);
stats.outputBytes = (stats.outputBytes || 0) + val.bytes;
}
}
stats.outputFiles = files.join(', ');
}
return stats;
}
// rebuild on file change
async function build(f, msg) {
log.info('Build: file', msg, f, 'target:', common.target);
if (!es) es = await esbuild.startService();
// common build options
try {
// rebuild all target groups and types
for (const [targetGroupName, targetGroup] of Object.entries(targets)) {
for (const [targetName, targetOptions] of Object.entries(targetGroup)) {
// if triggered from watch mode, rebuild only browser bundle
if ((require.main !== module) && (targetGroupName !== 'browserBundle')) continue;
await es.build({ ...common, ...targetOptions });
const stats = await getStats(targetOptions.metafile, targetName);
log.state(`Build for: ${targetGroupName} type: ${targetName}:`, stats);
}
}
if (require.main === module) process.exit(0);
} catch (err) {
// catch errors and print where it occured
log.error('Build error', JSON.stringify(err.errors || err, null, 2));
if (require.main === module) process.exit(1);
}
}
if (require.main === module) {
log.header();
build('all', 'startup');
} else {
exports.build = build;
}

52
package-lock.json generated
View File

@ -150,6 +150,12 @@
"integrity": "sha512-oGaKsBbxQOY5+aJFV3KECDhGaXt+yZJt2y/OZsnQGLRkH6Fvr7rv4pCt3SRH1somIHfej/c4u7NSpCyd9x+1Ow==", "integrity": "sha512-oGaKsBbxQOY5+aJFV3KECDhGaXt+yZJt2y/OZsnQGLRkH6Fvr7rv4pCt3SRH1somIHfej/c4u7NSpCyd9x+1Ow==",
"dev": true "dev": true
}, },
"@vladmandic/pilogger": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/@vladmandic/pilogger/-/pilogger-0.2.9.tgz",
"integrity": "sha512-UaDAFoEJwPw8248u9WQjVexP24wMiglHMWWd4X0gwukZuDw+CkoLddVF8335OYa+pXbP+t/rwx+E50f5rd5IhQ==",
"dev": true
},
"abbrev": { "abbrev": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@ -174,12 +180,14 @@
"ansi-regex": { "ansi-regex": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
}, },
"ansi-styles": { "ansi-styles": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": { "requires": {
"color-convert": "^2.0.1" "color-convert": "^2.0.1"
} }
@ -263,6 +271,7 @@
"version": "7.0.4", "version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"requires": { "requires": {
"string-width": "^4.2.0", "string-width": "^4.2.0",
"strip-ansi": "^6.0.0", "strip-ansi": "^6.0.0",
@ -279,6 +288,7 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": { "requires": {
"color-name": "~1.1.4" "color-name": "~1.1.4"
} }
@ -286,7 +296,8 @@
"color-name": { "color-name": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
}, },
"combined-stream": { "combined-stream": {
"version": "1.0.8", "version": "1.0.8",
@ -312,7 +323,8 @@
"core-js": { "core-js": {
"version": "3.7.0", "version": "3.7.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.7.0.tgz", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.7.0.tgz",
"integrity": "sha512-NwS7fI5M5B85EwpWuIwJN4i/fbisQUwLwiSNUWeXlkAZ0sbBjLEvLvFLf1uzAUV66PcEPt4xCGCmOZSxVf3xzA==" "integrity": "sha512-NwS7fI5M5B85EwpWuIwJN4i/fbisQUwLwiSNUWeXlkAZ0sbBjLEvLvFLf1uzAUV66PcEPt4xCGCmOZSxVf3xzA==",
"dev": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -362,7 +374,8 @@
"emoji-regex": { "emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
}, },
"es6-promise": { "es6-promise": {
"version": "4.2.8", "version": "4.2.8",
@ -380,15 +393,16 @@
} }
}, },
"esbuild": { "esbuild": {
"version": "0.8.15", "version": "0.8.17",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.15.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.17.tgz",
"integrity": "sha512-mSaLo9t/oYtQE6FRUEdO47Pr8PisSPzHtgr+LcihIcjBEhbYwjT6WLCQ7noDoTBfIatBCw229rtmIwl9u9UQwg==", "integrity": "sha512-ReHap+Iyn5BQF0B8F3xrLwu+j57ri5uDUw2ej9XTPAuFDebYiWwRzBY4jhF610bklveXLbCGim/8/2wQKQlu1w==",
"dev": true "dev": true
}, },
"escalade": { "escalade": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
}, },
"form-data": { "form-data": {
"version": "3.0.0", "version": "3.0.0",
@ -472,7 +486,8 @@
"get-caller-file": { "get-caller-file": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
}, },
"glob": { "glob": {
"version": "7.1.6", "version": "7.1.6",
@ -491,7 +506,8 @@
"google-protobuf": { "google-protobuf": {
"version": "3.14.0", "version": "3.14.0",
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.14.0.tgz", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.14.0.tgz",
"integrity": "sha512-bwa8dBuMpOxg7COyqkW6muQuvNnWgVN8TX/epDRGW5m0jcrmq2QJyCyiV8ZE2/6LaIIqJtiv9bYokFhfpy/o6w==" "integrity": "sha512-bwa8dBuMpOxg7COyqkW6muQuvNnWgVN8TX/epDRGW5m0jcrmq2QJyCyiV8ZE2/6LaIIqJtiv9bYokFhfpy/o6w==",
"dev": true
}, },
"has-flag": { "has-flag": {
"version": "4.0.0", "version": "4.0.0",
@ -558,7 +574,8 @@
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
}, },
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
@ -827,7 +844,8 @@
"require-directory": { "require-directory": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
"dev": true
}, },
"rimraf": { "rimraf": {
"version": "3.0.2", "version": "3.0.2",
@ -906,6 +924,7 @@
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": { "requires": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@ -925,6 +944,7 @@
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^5.0.0" "ansi-regex": "^5.0.0"
} }
@ -1036,6 +1056,7 @@
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"requires": { "requires": {
"ansi-styles": "^4.0.0", "ansi-styles": "^4.0.0",
"string-width": "^4.1.0", "string-width": "^4.1.0",
@ -1051,7 +1072,8 @@
"y18n": { "y18n": {
"version": "5.0.5", "version": "5.0.5",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
"dev": true
}, },
"yallist": { "yallist": {
"version": "3.1.1", "version": "3.1.1",
@ -1063,6 +1085,7 @@
"version": "16.1.1", "version": "16.1.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz",
"integrity": "sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==", "integrity": "sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==",
"dev": true,
"requires": { "requires": {
"cliui": "^7.0.2", "cliui": "^7.0.2",
"escalade": "^3.1.1", "escalade": "^3.1.1",
@ -1076,7 +1099,8 @@
"yargs-parser": { "yargs-parser": {
"version": "20.2.4", "version": "20.2.4",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
"dev": true
}, },
"yn": { "yn": {
"version": "3.1.1", "version": "3.1.1",

View File

@ -45,7 +45,8 @@
"@tensorflow/tfjs": "^2.7.0", "@tensorflow/tfjs": "^2.7.0",
"@tensorflow/tfjs-node": "^2.7.0", "@tensorflow/tfjs-node": "^2.7.0",
"@types/node": "^14.14.10", "@types/node": "^14.14.10",
"esbuild": "^0.8.15", "@vladmandic/pilogger": "^0.2.9",
"esbuild": "^0.8.17",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"ts-node": "^9.0.0", "ts-node": "^9.0.0",
"tslib": "^2.0.3", "tslib": "^2.0.3",

44
src/tfjs/tf-browser.js Normal file
View File

@ -0,0 +1,44 @@
// wrapper to load tfjs in a single place so version can be changed quickly
// simplified
// { modules: 1061, moduleBytes: 3772720, outputBytes: 1531035 }
export * from '@tensorflow/tfjs/dist/index.js';
export * from '@tensorflow/tfjs-backend-wasm';
// modular
// { modules: 1064, moduleBytes: 3793219, outputBytes: 1535600 }
/*
// get versions of all packages.
import { version as tfjs } from '@tensorflow/tfjs/package.json';
import { version as versionCore } from '@tensorflow/tfjs-core/package.json';
import { version as versionData } from '@tensorflow/tfjs-data/package.json';
import { version as versionLayers } from '@tensorflow/tfjs-layers/package.json';
import { version as versionConverter } from '@tensorflow/tfjs-converter/package.json';
// for backends, get version from source so it can register backend during import
import { version_cpu } from '@tensorflow/tfjs-backend-cpu/dist/index.js';
import { version_webgl } from '@tensorflow/tfjs-backend-webgl/dist/index.js';
import { version_wasm } from '@tensorflow/tfjs-backend-wasm/dist/index.js';
// export all
export * from '@tensorflow/tfjs-core/dist/index.js';
export * from '@tensorflow/tfjs-layers/dist/index.js';
export * from '@tensorflow/tfjs-converter/dist/index.js';
export * as data from '@tensorflow/tfjs-data/dist/index.js';
export * from '@tensorflow/tfjs-backend-cpu/dist/index.js';
export * from '@tensorflow/tfjs-backend-webgl/dist/index.js';
export * from '@tensorflow/tfjs-backend-wasm/dist/index.js';
// export versions
export const version = {
tfjs,
'tfjs-core': versionCore,
'tfjs-data': versionData,
'tfjs-layers': versionLayers,
'tfjs-converter': versionConverter,
'tfjs-backend-cpu': version_cpu,
'tfjs-backend-webgl': version_webgl,
'tfjs-backend-wasm': version_wasm,
};
*/

1
src/tfjs/tf-node-gpu.js Normal file
View File

@ -0,0 +1 @@
export * from '@tensorflow/tfjs-node-gpu';

1
src/tfjs/tf-node.js Normal file
View File

@ -0,0 +1 @@
export * from '@tensorflow/tfjs-node';