Search code examples
node.jstensorflowrequiregoogle-cloud-automlscript-tag

Is there a way to replace script tag src with require and run the same script on node?


I am running the following in a browser:

INDEX.HTML (BODY)

<script src="https://unpkg.com/@tensorflow/tfjs"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-automl"></script>
<img
  id="daisy"
  crossorigin="anonymous"
  src="https://storage.googleapis.com/tfjs-testing/tfjs-automl/img_classification/daisy.jpg"
/>
<script>
  async function run() {
    const model = await tf.automl.loadImageClassification("model.json");
    const image = document.getElementById("daisy");
    const predictions = await model.classify(image);

    const pre = document.createElement("pre");
    pre.textContent = JSON.stringify(predictions, null, 2);
    document.body.append(pre);
  }

  run();
</script>

What I am trying to do is convert the script to something I can run in node js, like this:

INDEX.JS (IMPORT/ESM)

import * as tf from "@tensorflow/tfjs";
import * as automl from "@tensorflow/tfjs-automl";

async function run() {
  const model = await tf.automl.loadImageClassification("model.json");
  const image = document.createElement("img");
  image.src =
    "https://storage.googleapis.com/tfjs-testing/tfjs-automl/img_classification/daisy.jpg";
  const predictions = await model.classify(image);

  console.log(predictions);
}

run();

I then run the script with node --experimental-modules index.js and it fails with:

(node:24163) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'loadImageClassification' of undefined

I also tried require:

INDEX.JS (REQUIRE/COMMON WITH CONST)

const tf = require("@tensorflow/tfjs");
const automl = require("@tensorflow/tfjs-automl");

async function run() {
  const model = await tf.automl.loadImageClassification("model.json");
  const image = document.createElement("img");
  image.src =
    "https://storage.googleapis.com/tfjs-testing/tfjs-automl/img_classification/daisy.jpg";
  const predictions = await model.classify(image);

  console.log(predictions);
}

run();

I had to remove "type": "module" from package.json and run with node index index.js. It gave the same error.

I also tried not capturing the require:

INDEX.JS (REQUIRE/COMMON)

require("@tensorflow/tfjs");
require("@tensorflow/tfjs-automl");

async function run() {
  const model = await tf.automl.loadImageClassification("model.json");
  const image = document.createElement("img");
  image.src =
    "https://storage.googleapis.com/tfjs-testing/tfjs-automl/img_classification/daisy.jpg";
  const predictions = await model.classify(image);

  console.log(predictions);
}

run();

When I run this, I get the error: (node:24211) UnhandledPromiseRejectionWarning: ReferenceError: tf is not defined.

This seems like it might be obvious, but is there a way to do what <script src= does, but in node, i.e. bring in the external script so my script can see and use the variables/methods in the external script?


Solution

  • For anyone else who wants to run tensorflow predictions on node:

    const tf = require("@tensorflow/tfjs-node");
    const automl = require("@tensorflow/tfjs-automl");
    const fs = require("fs");
    
    const model_url = "<your-model-url>";
    const image_path = process.argv.slice(2)[0];
    
    if (!image_path) {
      throw new Error("missing argument: path to image");
    }
    
    const image = fs.readFileSync(image_path);
    const decoded_image = tf.node.decodeJpeg(image);
    
    async function run() {
      const model = await automl.loadImageClassification(model_url);
      const predictions = await model.classify(decoded_image);
    
      console.log(predictions);
    }
    
    run().catch(console.error);