Skip to content

Commit a3f59d5

Browse files
committed
[v1.1.0] - add BigInt polyfill and loading model retries
1 parent 120d0c9 commit a3f59d5

File tree

4 files changed

+162
-129
lines changed

4 files changed

+162
-129
lines changed

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
# Teachable Machine Node v1.0.0
1+
# Teachable Machine Node
22

33
![teachable-machine-cover](https://media-blog.sashido.io/content/images/2020/09/teachable-machine-cover.png)
44

55
# About
66

7-
**Teachable Machine Node v.1.0.0** empowers you to load any image classification model trained with Google's Teachable Machine tool in a Node.Js project.
7+
**Teachable Machine Node** empowers you to load any image classification model trained with Google's Teachable Machine tool in a Node.Js project.
88

9-
[Teachable Machine](https://teachablemachine.withgoogle.com/) makes AI easy for everyone, by offering a fast and fun way to train a real TensorFlow.js Machine Learning Models without any coding required. You can train the computer to recognize images, sounds, & poses, using your camera or your own dataset.
9+
[Teachable Machine](https://teachablemachine.withgoogle.com/) makes AI easy for everyone, by offering a fast and fun way to train a real TensorFlow.js Machine Learning Models without any coding required. You can train the computer to recognize images, sounds, & poses, using your camera or your own dataset.
1010

11-
For now, Teachable Machine Node v.1.0.0 holds suport only for image models, but we won't stop here. Check out the [Roadmap](#Roadmap) of what comes next!
11+
For now, Teachable Machine Node holds suport only for image models, but we won't stop here. Check out the [Roadmap](#Roadmap) of what comes next!
1212

1313
# Install
1414

@@ -31,7 +31,7 @@ yarn add @sashido/teachablemachine-node
3131

3232
1. [Gathering samples](https://youtu.be/DFBbSTvtpy4) is the fundamental first step to your Teachable Machine Model. Use your camera to collect data or upload some preselected images.
3333

34-
2. [Train your Teachable Machine Image Model](https://teachablemachine.withgoogle.com/train?action=onboardOpen&id=CO67EQ0ZWgA).
34+
2. [Train your Teachable Machine Image Model](https://teachablemachine.withgoogle.com/train?action=onboardOpen&id=CO67EQ0ZWgA).
3535

3636
![](https://media-blog.sashido.io/content/images/2020/09/tm_export_model.png)
3737

@@ -117,15 +117,15 @@ app.listen(port, () => {
117117

118118
In the long run, we will add more options, so you can train and load all kinds of Teachable Machine Models.
119119

120-
1. Add support for Pose Models.
121-
122-
2. Add support for Audio Models.
123-
124-
3. Add support for Gifs.
125-
120+
1. Add support for Pose Models.
121+
122+
2. Add support for Audio Models.
123+
124+
3. Add support for Gifs.
125+
126126
4. Add support for Videos.
127-
128-
We would love to have your opinion which's the one you would like to see supported first. Don't be shy and drop us a line at [email protected].
127+
128+
We would love to have your opinion which's the one you would like to see supported first. Don't be shy and drop us a line at [email protected].
129129

130130
# Contribute
131131

index.js

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,27 @@
1+
global.BigInt = require("bigint-polyfill");
2+
global.fetch = require("node-fetch");
3+
14
const tmImage = require("@teachablemachine/image");
25
const isImageUrl = require('is-image-url');
36
const canvas = require("canvas");
7+
48
const { JSDOM } = require("jsdom");
59
const dom = new JSDOM("");
6-
7-
8-
global.fetch = require("node-fetch");
910
global.document = dom.window.document;
1011
global.HTMLVideoElement = dom.window.HTMLVideoElement;
1112

1213

1314
const wait = ms => new Promise(r => setTimeout(r, ms));
1415

15-
16-
const retryOperation = (operation, delay, times, retriesCounter = 0) => new Promise((resolve, reject) => {
16+
const retryOperation = (operation, delay, times) => new Promise((resolve, reject) => {
1717
return operation()
1818
.then(({ cb }) => {
1919
return resolve(cb());
2020
})
2121
.catch(({ message }) => {
22-
if (retriesCounter === 0) {
23-
console.info("[@sashido/teachablemachine-node] -", message);
24-
}
25-
2622
if (times - 1 > 0) {
27-
retriesCounter++;
2823
return wait(delay)
29-
.then(retryOperation.bind(null, operation, delay, times - 1, retriesCounter))
24+
.then(retryOperation.bind(null, operation, delay, times - 1))
3025
.then(resolve)
3126
.catch(reject);
3227
}
@@ -41,15 +36,17 @@ const byProbabilty = (predictionA, predictionB) => {
4136
return 0;
4237
}
4338

44-
class SashiDoTeachable {
39+
40+
class SashiDoTeachableMachine {
4541
constructor(params) {
4642
this.loadModel(params);
4743
}
4844

49-
5045
async loadModel({ modelUrl }) {
5146
if (!modelUrl || modelUrl === "") {
5247
console.error("[@sashido/teachablemachine-node] -", "Missing model URL!");
48+
this.error = "Missing model URL!";
49+
return null;
5350
}
5451

5552
try {
@@ -59,32 +56,42 @@ class SashiDoTeachable {
5956
}
6057
}
6158

59+
async checkModel(cb) {
60+
const { model } = this;
61+
62+
if (model) {
63+
return Promise.resolve({ cb });
64+
}
65+
66+
return Promise.reject({ message: "Loading model" });
67+
}
68+
6269

6370
async classify(params) {
64-
const { model } = this;
6571
const { imageUrl } = params;
6672

6773
if (!isImageUrl(imageUrl)) {
68-
console.error("[@sashido/teachablemachine-node] -", "Image URL is not valid!");
6974
return Promise.reject({ error: "Image URL is not valid!" });
7075
}
7176

72-
if (!model) {
73-
console.error("[@sashido/teachablemachine-node] -", "Model is not ready!");
74-
return Promise.reject({ error: "Model is not ready!" });
77+
if (this.error) {
78+
return Promise.reject({ error: this.error });
7579
}
7680

81+
return retryOperation(() => this.checkModel(() => this.inference(params)), 1000, 20); // method, delay, retries
82+
}
83+
84+
async inference({ imageUrl }) {
7785
try {
7886
const image = new canvas.Image();
7987
image.src = imageUrl;
8088

8189
const predictions = await this.model.predict(image);
8290
return predictions.sort(byProbabilty);
8391
} catch (error) {
84-
console.error("[@sashido/teachablemachine-node] -", error);
8592
return Promise.reject({ error });
8693
}
8794
}
8895
}
8996

90-
module.exports = SashiDoTeachable;
97+
module.exports = SashiDoTeachableMachine;

0 commit comments

Comments
 (0)