Skip to content

Chrome browser plugin deployment example (mobilenet) #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jul 2, 2019

Conversation

bileschi
Copy link
Contributor

@bileschi bileschi commented Jun 28, 2019

This PR creates a subdirectory within examples for examples meant to exhibit how to deploy tfjs. It creates two examples. One for deploying to browser (indicating to the reader just to use the mobilenet example in the parent dir above), and one for deploying to a browser plugin.

The browser plugin allows the user to right-click on images in a webpage, and apply mobilenet to the image. The resulting prediction is written on top of the image.


This change is Reviewable

@bileschi bileschi requested review from caisq and tafsiri June 28, 2019 21:58
Copy link
Contributor Author

@bileschi bileschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 1 approvals obtained (waiting on @caisq and @tafsiri)


deployment-examples/README.md, line 12 at r1 (raw file):

TODO(bileschi) :

Improve readme.


deployment-examples/browser-plugin/README.md, line 5 at r1 (raw file):

    "copy": "cp src/content.js dist/src/ && cp src/imagenet_classes.js dist/src/",

Improve readme. Add build & installation instructions.


deployment-examples/browser-plugin/src/background.js, line 1 at r1 (raw file):

import 'babel-polyfill';

Needs license


deployment-examples/browser-plugin/src/background.js, line 7 at r1 (raw file):

// Where to load the model from.
const MOBILENET_MODEL_PATH = 'https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json';
const IMAGE_SIZE = 224;

Add comments describing the purpose of these constants.


deployment-examples/browser-plugin/src/background.js, line 48 at r1 (raw file):

  }

  async analyzeImage(url, tabId) {

add documentation.


deployment-examples/browser-plugin/src/background.js, line 76 at r1 (raw file):

  }

  async loadImage(src) {

Is this the right way to do this?


deployment-examples/browser-plugin/src/background.js, line 85 at r1 (raw file):

      img.onload = function(e) {
        if ((img.height && img.height > 128) || (img.width && img.width > 128)) {
          // Set image size for tf!

remove comment.


deployment-examples/browser-plugin/src/background.js, line 97 at r1 (raw file):

  }

  async getTopKClasses(logits, topK) {

describe


deployment-examples/browser-plugin/src/background.js, line 124 at r1 (raw file):

  async predict(imgElement) {

describe.


deployment-examples/browser-plugin/src/background.js, line 153 at r1 (raw file):

}

var imageClassifier = new ImageClassifier();

const.


deployment-examples/browser-plugin/src/imagenet_classes.js, line 17 at r1 (raw file):

 * =============================================================================
 */

Consider reducing the classes to just the first one in each.


deployment-examples/web/README.md, line 3 at r1 (raw file):

# TensorFlow.js Deployment Example : Web

Web deployment is the most common deployment scenario, and is the pattern used for most of the examples in the tfjs-examples repository.  For a good simle example of how to deploy and use a model within a web page, refer to https://github.com/tensorflow/tfjs-examples/tree/master/mobilenet among others.

improve README

Copy link
Contributor Author

@bileschi bileschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be

Reviewable status: 0 of 1 approvals obtained (waiting on @caisq and @tafsiri)

a discussion (no related file):
Appears that the manifest is missing.


Copy link
Collaborator

@caisq caisq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @bileschi, @caisq, and @tafsiri)


deployment-examples/README.md, line 1 at r1 (raw file):

# TensorFlow.js Deployment Examples

directory naming nit: how about let's just call this folder "deployment", instead of "deployment-examples", for the sake of simplicity?


deployment-examples/browser-plugin/package.json, line 1 at r1 (raw file):

{

Take a look at the cloud build status. It's currently failing. The presubmit script, which is run by cloud build, assumes that there is a package.json file under each and every top-level folder in this repository. In this new directory organization, the script has to be modified accordingly.


deployment-examples/browser-plugin/README.md, line 1 at r1 (raw file):

# TensorFlow.js Deployment Example : Browser Plugin
  1. You should include instructions on how to build the Chrome Extension and how to load it in Chrome for testing.

  2. Directory naming discussion. Strictly speaking, what you are building is called an "extension", not a "plugin". I think we should replace "plugin" with "extensions" in the file, directory names and the texts.


deployment-examples/browser-plugin/src/background.js, line 1 at r1 (raw file):

mport 'babel-polyfill';

nit: Need license header just like all other .js files in tfjs-examples.


deployment-examples/browser-plugin/src/background.js, line 3 at r1 (raw file):

 

nit: The style we've been using in tfjs-examples doesn't include these spaces in import statements.


deployment-examples/browser-plugin/src/background.js, line 6 at r1 (raw file):

mobilenet_v1_

Why not MobileNetV2? It's smaller and more accuracy.
If it's not there, it'll be easy to create one, e.g., by doing in python

import tensorflow as tf
mport tensorflowjs as tfjs

model = tf.keras.applications.MobileNetV2()
tfjs.converters.save_keras_model(model, 'mobilenet_v2_1.00_224/model.json'

deployment-examples/browser-plugin/src/background.js, line 10 at r1 (raw file):

Fn(

nit: Google style generally prefers more descriptive and longer names over shorthands like Fn. Maybe call this clickMenuCallback.

See https://google.github.io/styleguide/jsguide.html#naming-rules-common-to-all-identifiers


deployment-examples/browser-plugin/src/background.js, line 18 at r1 (raw file):

[

nit: missing a space before [. Please check your JS style throughout, possibly by imitating the eslint in intent-classifier.


deployment-examples/browser-plugin/src/background.js, line 39 at r1 (raw file):

this.model.predict(tf.zeros([1, IMAGE_SIZE, IMAGE_SIZE, 3])).dispose();
  1. Add a comment to say this is for warming up the model.
  2. Note that even though you use dispose(), this still leaks a tenor (i.e., the one created with tf.zeros()). To prevent leakage, do:
tf.tidy(() => {
  this.model.predict(...);
});

deployment-examples/browser-plugin/src/background.js, line 42 at r1 (raw file):

ms

nit: add a space before ms.


deployment-examples/browser-plugin/src/background.js, line 48 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

add documentation.

+1


deployment-examples/browser-plugin/src/background.js, line 50 at r1 (raw file):

log(

Error conditions like this should use console.error(), instead of console.log(). Same below.


deployment-examples/browser-plugin/src/background.js, line 55 at r1 (raw file):

 

The style looks weird. Break it into a separate line.


deployment-examples/browser-plugin/src/background.js, line 55 at r1 (raw file):

5000)

This magic number looks dangerous.


deployment-examples/browser-plugin/src/background.js, line 56 at r1 (raw file):

return;

See my comment about the magic number 5000 above, why return here? You want to load the model and then do the prediction, even when the it's the first time, right?


deployment-examples/browser-plugin/src/background.js, line 64 at r1 (raw file):

!predictions)

Why might this happen? Would it be more appropriate to use try-catch?


deployment-examples/browser-plugin/src/background.js, line 81 at r1 (raw file):

resolve

This should use reject, instead of resolve, so that an Error can be thrown properly. I.e., new Promise((resolve, reject) => { ....


deployment-examples/browser-plugin/src/background.js, line 93 at r1 (raw file):

 img.src = src;

What is this line for? Is src even defined?


deployment-examples/browser-plugin/src/background.js, line 103 at r1 (raw file):

valuesAndIndices.sort

No need to do this manually. The latest version of TF.js has a tf.topk method, see:
https://js.tensorflow.org/api/latest/#topk


deployment-examples/browser-plugin/src/content.js, line 23 at r1 (raw file):

// Produces a short text string summarizing the prediction
// Input prediction should be a list of {className: string, prediction: float}
// objects.

Style nit: function jsdocs should be in C style. Same elsewhere.

See: https://google.github.io/styleguide/jsguide.html#appendices-documentation-annotations


deployment-examples/browser-plugin/src/content.js, line 29 at r1 (raw file):

0.5

These magic numbers should be pulled out as file-level consts for clarity.


deployment-examples/browser-plugin/src/content.js, line 30 at r1 (raw file):

 "😄 " + predictions[0].className + "!";

All these string concatenations should use template strings, i.e., the ones with backtics. Same throughout.


deployment-examples/browser-plugin/src/content.js, line 125 at r1 (raw file):

}

style nit: need a newline character at the end of the file.


deployment-examples/browser-plugin/src/imagenet_classes.js, line 899 at r1 (raw file):

 

nit: indentation should be two spaces, not one.


deployment-examples/web/README.md, line 1 at r1 (raw file):

# TensorFlow.js Deployment Example : Web

Does this file belong in this PR?

@caisq caisq self-assigned this Jun 29, 2019
Copy link

@nsthorat nsthorat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @bileschi and @tafsiri)


deployment/README.md, line 1 at r2 (raw file):

# TensorFlow.js Deployment Examples

The deploy script assumes a script in each directory called build, can you make sure that works with this nested structure?

Also, is this the structure we want? How about just making a folder called chrome-extension?

https://github.com/tensorflow/tfjs-examples/blob/master/deploy.sh


deployment/browser-plugin/package.json, line 1 at r2 (raw file):

{

this is specific to chrome right? how about just calling this directory chrome-extension instead of browser-plugin?


deployment/browser-plugin/src/background.js, line 24 at r2 (raw file):

// Where to load the model from.
const MOBILENET_MODEL_PATH =
    'https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json';

use tfhub


deployment/browser-plugin/src/imagenet_classes.js, line 1 at r2 (raw file):

/**

why do you need this? can you just depend on the mobilenet package @tensorflow-models/mobilenet?

Copy link
Contributor Author

@bileschi bileschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @bileschi, @caisq, @nsthorat, and @tafsiri)


deployment/README.md, line 1 at r2 (raw file):

Previously, nsthorat (Nikhil Thorat) wrote…

The deploy script assumes a script in each directory called build, can you make sure that works with this nested structure?

Also, is this the structure we want? How about just making a folder called chrome-extension?

https://github.com/tensorflow/tfjs-examples/blob/master/deploy.sh

Updated. I'm happy to move the chrome-extension to top level and get rid of the idea of a group of deployment-centric examples.


deployment-examples/README.md, line 1 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
# TensorFlow.js Deployment Examples

directory naming nit: how about let's just call this folder "deployment", instead of "deployment-examples", for the sake of simplicity?

changed.


deployment-examples/README.md, line 12 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

Improve readme.

done


deployment/browser-plugin/src/background.js, line 24 at r2 (raw file):

Previously, nsthorat (Nikhil Thorat) wrote…

use tfhub

done.


deployment/browser-plugin/src/imagenet_classes.js, line 1 at r2 (raw file):

Previously, nsthorat (Nikhil Thorat) wrote…

why do you need this? can you just depend on the mobilenet package @tensorflow-models/mobilenet?

That does not expose the actual classes. It's more of a managed solution that only offers 'load' and 'classify'


deployment-examples/browser-plugin/package.json, line 1 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
{

Take a look at the cloud build status. It's currently failing. The presubmit script, which is run by cloud build, assumes that there is a package.json file under each and every top-level folder in this repository. In this new directory organization, the script has to be modified accordingly.

Done Thanks for pointing this out.
I think the change I made to the testing script should be sufficient.


deployment-examples/browser-plugin/README.md, line 1 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
# TensorFlow.js Deployment Example : Browser Plugin
  1. You should include instructions on how to build the Chrome Extension and how to load it in Chrome for testing.

  2. Directory naming discussion. Strictly speaking, what you are building is called an "extension", not a "plugin". I think we should replace "plugin" with "extensions" in the file, directory names and the texts.

Done.


deployment-examples/browser-plugin/README.md, line 5 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…
    "copy": "cp src/content.js dist/src/ && cp src/imagenet_classes.js dist/src/",

Improve readme. Add build & installation instructions.

done


deployment-examples/browser-plugin/src/background.js, line 1 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
mport 'babel-polyfill';

nit: Need license header just like all other .js files in tfjs-examples.

Done.


deployment-examples/browser-plugin/src/background.js, line 1 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

Needs license

Done.


deployment-examples/browser-plugin/src/background.js, line 3 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
 

nit: The style we've been using in tfjs-examples doesn't include these spaces in import statements.

Done.


deployment-examples/browser-plugin/src/background.js, line 6 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
mobilenet_v1_

Why not MobileNetV2? It's smaller and more accuracy.
If it's not there, it'll be easy to create one, e.g., by doing in python

import tensorflow as tf
mport tensorflowjs as tfjs

model = tf.keras.applications.MobileNetV2()
tfjs.converters.save_keras_model(model, 'mobilenet_v2_1.00_224/model.json'

Done.


deployment-examples/browser-plugin/src/background.js, line 10 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
Fn(

nit: Google style generally prefers more descriptive and longer names over shorthands like Fn. Maybe call this clickMenuCallback.

See https://google.github.io/styleguide/jsguide.html#naming-rules-common-to-all-identifiers

Done.


deployment-examples/browser-plugin/src/background.js, line 18 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
[

nit: missing a space before [. Please check your JS style throughout, possibly by imitating the eslint in intent-classifier.

Done. (needed to re-install and setup clang-format)


deployment-examples/browser-plugin/src/background.js, line 39 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
this.model.predict(tf.zeros([1, IMAGE_SIZE, IMAGE_SIZE, 3])).dispose();
  1. Add a comment to say this is for warming up the model.
  2. Note that even though you use dispose(), this still leaks a tenor (i.e., the one created with tf.zeros()). To prevent leakage, do:
tf.tidy(() => {
  this.model.predict(...);
});

Done.


deployment-examples/browser-plugin/src/background.js, line 42 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
ms

nit: add a space before ms.

Done.


deployment-examples/browser-plugin/src/background.js, line 50 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
log(

Error conditions like this should use console.error(), instead of console.log(). Same below.

Done.


deployment-examples/browser-plugin/src/background.js, line 55 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
5000)

This magic number looks dangerous.

Done.


deployment-examples/browser-plugin/src/background.js, line 55 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
 

The style looks weird. Break it into a separate line.

Done.


deployment-examples/browser-plugin/src/background.js, line 56 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
return;

See my comment about the magic number 5000 above, why return here? You want to load the model and then do the prediction, even when the it's the first time, right?

The function uses async recursion here to handle the case that the model isn't loaded. While it can't load the model it keeps trying every 5 seconds.


deployment-examples/browser-plugin/src/background.js, line 64 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
!predictions)

Why might this happen? Would it be more appropriate to use try-catch?

I don't think it can happen. Removed.


deployment-examples/browser-plugin/src/background.js, line 81 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
resolve

This should use reject, instead of resolve, so that an Error can be thrown properly. I.e., new Promise((resolve, reject) => { ....

good catch. Updated error handling here.


deployment-examples/browser-plugin/src/background.js, line 93 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
 img.src = src;

What is this line for? Is src even defined?

src is an input argument. This line sets the src parameter of the image element


deployment-examples/browser-plugin/src/content.js, line 23 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
// Produces a short text string summarizing the prediction
// Input prediction should be a list of {className: string, prediction: float}
// objects.

Style nit: function jsdocs should be in C style. Same elsewhere.

See: https://google.github.io/styleguide/jsguide.html#appendices-documentation-annotations

Done.


deployment-examples/browser-plugin/src/content.js, line 29 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
0.5

These magic numbers should be pulled out as file-level consts for clarity.

Great idea. done.


deployment-examples/browser-plugin/src/content.js, line 30 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
 "😄 " + predictions[0].className + "!";

All these string concatenations should use template strings, i.e., the ones with backtics. Same throughout.

done.


deployment-examples/browser-plugin/src/content.js, line 125 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
}

style nit: need a newline character at the end of the file.

Done.


deployment-examples/browser-plugin/src/imagenet_classes.js, line 899 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
 

nit: indentation should be two spaces, not one.

Done.


deployment-examples/web/README.md, line 1 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
# TensorFlow.js Deployment Example : Web

Does this file belong in this PR?

Removed.

Copy link
Contributor Author

@bileschi bileschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @bileschi, @caisq, @nsthorat, and @tafsiri)


deployment/README.md, line 1 at r2 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

Updated. I'm happy to move the chrome-extension to top level and get rid of the idea of a group of deployment-centric examples.

updated 2: Got rid of the subdir structure


deployment/browser-plugin/package.json, line 1 at r2 (raw file):

Previously, nsthorat (Nikhil Thorat) wrote…

this is specific to chrome right? how about just calling this directory chrome-extension instead of browser-plugin?

Removed the nested substructure. If we end up wanting to add organizational structure to the examples we can do it later.


deployment-examples/README.md, line 1 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

changed.

removed.


deployment-examples/browser-plugin/README.md, line 1 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

Done.

Done.

Copy link
Collaborator

@caisq caisq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 1 of 1 approvals obtained (waiting on @bileschi, @caisq, @nsthorat, and @tafsiri)

a discussion (no related file):

Previously, bileschi (Stanley Bileschi) wrote…

Appears that the manifest is missing.

:lgtm_strong:

Great work! Thanks!



chrome-extension/README.md, line 1 at r3 (raw file):

Plugin

-> Extension


chrome-extension/README.md, line 5 at r3 (raw file):

 mobilenet

-> MobileNetV2


chrome-extension/src/background.js, line 25 at r3 (raw file):

/ 'https://tfhub.dev/google/imagenet/mobilenet_v1_100_224/classification/

Remove cruft.


chrome-extension/src/background.js, line 193 at r3 (raw file):

const logits1001 = this.model.predict(batched);

To be more robust against future changes, you can do:

const output = this.model.predict(batched);
if (output.shape[output.shape.length - 1] === 1001) {
return output.slice([0, 1], [-1, 1000]);
} else if (output.shape[output.shape.length - 1] === 100) {
return output;
} else {
throw new Error('Unexpected shape...');
}


chrome-extension/src/background.js, line 203 at r3 (raw file):

Math.floor(totalTime1)}

You can also do something like ${totalTime1.toFixed(1)}.


chrome-extension/src/content.js, line 22 at r3 (raw file):

HIGH_CONFIDENCE =

Naming nit: --> HIGH_CONFIDENCE_THRESHOLD to be more threshold. Same below.


deployment-examples/browser-plugin/package.json, line 1 at r1 (raw file):

Previously, bileschi (Stanley Bileschi) wrote…

Done Thanks for pointing this out.
I think the change I made to the testing script should be sufficient.

OK. The flat structure works, too.

Copy link
Collaborator

@caisq caisq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @bileschi, @caisq, @nsthorat, and @tafsiri)


chrome-extension/src/background.js, line 158 at r3 (raw file):

values.dataSync()

To illustrate best practice, use await value.data() here. Same below.

data() doesn't block the main thread.

Copy link
Contributor Author

@bileschi bileschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @bileschi, @caisq, @nsthorat, and @tafsiri)


chrome-extension/src/background.js, line 25 at r3 (raw file):

Previously, caisq (Shanqing Cai) wrote…
/ 'https://tfhub.dev/google/imagenet/mobilenet_v1_100_224/classification/

Remove cruft.

Done.


chrome-extension/src/background.js, line 158 at r3 (raw file):

Previously, caisq (Shanqing Cai) wrote…
values.dataSync()

To illustrate best practice, use await value.data() here. Same below.

data() doesn't block the main thread.

Done.


chrome-extension/src/background.js, line 193 at r3 (raw file):

if (output.shape[output.shape.length - 1] === 1001) {
return output.slice([0, 1], [-1, 1000]);
} else if (output.shape[output.shape.length - 1] === 100) {
return output;
} else {
throw new Error('Unexpected shape...');
}
Good idea. Done.


chrome-extension/src/background.js, line 203 at r3 (raw file):

Previously, caisq (Shanqing Cai) wrote…
Math.floor(totalTime1)}

You can also do something like ${totalTime1.toFixed(1)}.

Done.

Copy link
Contributor Author

@bileschi bileschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @caisq, @nsthorat, and @tafsiri)

a discussion (no related file):

Previously, caisq (Shanqing Cai) wrote…

:lgtm_strong:

Great work! Thanks!

Thanks for the reviews! @nsthorat too



chrome-extension/README.md, line 1 at r3 (raw file):

Previously, caisq (Shanqing Cai) wrote…
Plugin

-> Extension

Done.


chrome-extension/README.md, line 5 at r3 (raw file):

Previously, caisq (Shanqing Cai) wrote…
 mobilenet

-> MobileNetV2

Done.


chrome-extension/src/content.js, line 22 at r3 (raw file):

Previously, caisq (Shanqing Cai) wrote…
HIGH_CONFIDENCE =

Naming nit: --> HIGH_CONFIDENCE_THRESHOLD to be more threshold. Same below.

Done.


deployment-examples/browser-plugin/src/background.js, line 103 at r1 (raw file):

Previously, caisq (Shanqing Cai) wrote…
valuesAndIndices.sort

No need to do this manually. The latest version of TF.js has a tf.topk method, see:
https://js.tensorflow.org/api/latest/#topk

Done.

@bileschi bileschi merged commit 56e3ffa into master Jul 2, 2019
@bileschi bileschi deleted the plugin-mobilenet branch July 2, 2019 14:55
Copy link

@nsthorat nsthorat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies I had one last comment about dist/ which I think I added right after you merged

Reviewable status: :shipit: complete! 1 of 1 approvals obtained (waiting on @bileschi, @caisq, @nsthorat, and @tafsiri)


chrome-extension/README.md, line 15 at r4 (raw file):

To install the unpacked extension in chrome, follow the instructions here. Briefly, navigate to chrome://extensions, make sure that the Developer mode switch is turned on in the upper right, and click Load Unpacked. Then select the appropriate directory (the dist directory containing manifest.json);

usually we don't check in dist/, this is generated. can you put images outside that dist directory? I think it will also get clobbered

@bileschi
Copy link
Contributor Author

bileschi commented Jul 2, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants