有没有办法用节点上的 require 和 运行 相同的脚本替换脚本标签 src?

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

我正在 运行浏览器中设置以下内容:

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>

我想做的是将脚本转换为我可以在节点 js 中 运行 的东西,像这样:

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();

然后我 运行 带有 node --experimental-modules index.js 的脚本,它失败了:

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

我也试过了require:

INDEX.JS(REQUIRE/COMMON 带常量)

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();

我不得不用 node index index.jspackage.json 和 运行 中删除 "type": "module"。它给出了同样的错误。

我也试过不捕获 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();

当我运行这个时,我得到错误:(node:24211) UnhandledPromiseRejectionWarning: ReferenceError: tf is not defined

这似乎很明显,但是有没有办法做 <script src= 所做的事情,但是在节点中,即引入外部脚本,以便我的脚本可以看到和使用 variables/methods 在外部脚本中?

我最初误解了你的问题。根据我现在所知道的,您需要使用的不是 tfjs,而是 tfjs-node,如 github issue

中所述

https://us04web.zoom.us/j/74533735324?pwd=d2NkcENZS3Q2MUtEeGFjc2V6TUowdz09

原因是默认情况下 tfjs 被设计为 运行 在浏览器上。我仍然认为以下信息可能对将来的某些人有所帮助。

这是来自 NodeJS 的官方资源 https://nodejs.dev/differences-between-nodejs-and-the-browser

您的脚本失败的原因可能与多种原因有关。以下是我的想法:

  1. 您正在尝试在您的应用中导入 Node 不知道如何加载的模块。这可能是因为您没有使用以下方式安装模块:
npm install --save @tensorflow/tfjs-automl @tensorflow/tfjs
  1. tfjs 在浏览器中使用之前可能需要捆绑。这意味着仅使用一个简单的 nodejs 应用程序是不够的,您需要进行简单的设置以将您的模块和脚本捆绑到一个脚本中,然后您可以在浏览器中使用它。

  2. 您确实正确使用了您的模块,但您的浏览器不知道如何加载它们,可能是因为您的浏览器不理解 "import" 语法。虽然不太可能,但这只是我的一个想法。

  3. 您的设置没问题,但您没有正确使用 tensorflow 库。从你在评论中告诉我的。我感觉 loadImageClassification 方法或 classify 方法可能没有收到他们期望的参数。请记住,loadImageClassification 需要 url 作为 tensorflow 将在分类期间使用的 json 文件。我还发现,如果你不设置它的宽度和高度,tfjs 在动态创建图像时会遇到一些麻烦,如下所述:

Requested texture size [0x0] is invalid. error when i am loading image in browser

我查看了 tfjs 示例并找到了一个与您在此处发布的示例非常相似的示例: https://github.com/tensorflow/tfjs/tree/master/tfjs-automl/demo/img_classification

我自己也在我的 github 个人资料中进行了类似的设置,没有遇到太多麻烦

https://github.com/taro-0/tsfjs-sample

对于任何其他想要在节点上进行 运行 tensorflow 预测的人:

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);