首页 > 解决方案 > SetInterval() 和异步函数?CPU 与 TF.js 一起工作太辛苦了

问题描述

我在 Tensorflow.js 中编写了用于网络摄像头分类的代码。通过结合许多教程的建议,它现在可以工作了。然而,在当前阶段,Tensorflow.js 对系统来说非常昂贵。预测循环while (true)。Google Chrome Helper(渲染器)使用 50-60% 的 CPU,此代码在浏览器中运行。

对我来说,每 0.5-1 秒进行一次预测计算就足够了,如果这样可以减轻一些 CPU 压力。但是,作为初学者,我仍然很困惑如何将 setInterval() 添加到我当前的代码中(替换while(true) 循环)。我想知道是否有人能指出我正确的方向?或者,如果有任何其他方法可以避免这段代码对 CPU 造成压力。非常感谢!


async function app() {

  const model = await tf.loadGraphModel(MODEL_URL);
  console.log('Successfully loaded model');

  const labels = ["not_monster", "monster"];

  console.log(labels);


  const webcam = await tf.data.webcam(video);


  while (true) {


    tf.engine().startScope();
    const img = await webcam.capture();
    const smalImg = tf.image.resizeBilinear(img, [224, 224]);
    const resized = tf.cast(smalImg, 'float32');

    const t4d = tf.tensor4d(Array.from(resized.dataSync()),[1,224,224,3]);


    const result = await model.predict(t4d); 

    result.print(); 
    result.as1D().argMax().print(); 
    const labelIndex = result.as1D().argMax(); 
    const predictionLabel = result.as1D().argMax().dataSync()[0];

    
    const predict = await result.data();
    const value = predict[predictionLabel];



    document.getElementById("demo").innerHTML = `
       Numeric prediction is: ${labelIndex}\n
       The predicted label is: ${labels[predictionLabel]}\n
       Confidence is: ${value}\n
    `;

    if (labels[predictionLabel] == "monster"){ 
     var data = {
       speed: 100
     }
     socket.emit("monster", data);
    }

    else {
     socket.emit("not_monster"); 
    }

    img.dispose();
    result.dispose();
    smalImg.dispose();
    resized.dispose();
    t4d.dispose();
    tf.engine().endScope();
    await tf.nextFrame();

    
  } // closes loop

} // closes app

requestAnimationFrame(() => this.app());

标签: javascripttensorflow.js

解决方案


您已经有一个 setinterval 循环:

requestAnimationFrame(() => this.app());

这与以下内容完全相同:

setInterval(() => this.app(), 16.66666666667);

(嗯,几乎完全一样。很难获得 1/60 秒的精确毫秒值)。

所以基本上你的应用程序已经有一个巨大的while循环,如果你愿意requestAnimationFrame(),你也可以像我上面所做的那样替换它。setInterval()

这会导致this.app()每秒调用 60 次。

因此,执行一秒钟后,您将在后台运行 60 个 while 循环(感谢await)。

执行 10 秒后,您将在后台运行 600 个 while 循环(等待 600 个对 Tensorflow 的调用)。

一分钟后,您将等待 3600 个对 Tensorflow 的并行调用。

10 分钟后,这将最终等待 36000 次对 Tensorflow 的并行调用。

难怪它会占用 60% 的 CPU 时间。随着时间的推移,情况会变得更糟。

在尝试替换之前requestAnimationFrame()setInterval()我建议您删除第while()一个. 您不必删除 while 循环内的代码,只需删除最后的while (true) {and即可}

requestAnimationFrame()尝试每秒调用您的函数 60 次(基本上充当 while 循环)。如果您想每 0.5 秒运行一次函数,请将其替换为:

setInterval(() => this.app(), 500);

要每 1 秒运行一次函数,请执行以下操作:

setInterval(() => this.app(), 1000);

推荐阅读