push
parent
006678b6c8
commit
d82c04870d
|
@ -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*
|
||||||
|
|
||||||
|

|
|
@ -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;
|
||||||
|
}
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
*/
|
|
@ -0,0 +1 @@
|
||||||
|
export * from '@tensorflow/tfjs-node-gpu';
|
|
@ -0,0 +1 @@
|
||||||
|
export * from '@tensorflow/tfjs-node';
|
Loading…
Reference in New Issue