【问题标题】:Can't use Tensorflow.js predict() function无法使用 Tensorflow.js predict() 函数
【发布时间】:2020-03-03 22:58:10
【问题描述】:

我已经训练了自己的图形模型。我想在浏览器上使用它。这是我的代码:

async function predict() {
        const model = await tf.loadGraphModel('./model/model.json');
        let img = document.getElementById('test');
        var example = tf.browser.fromPixels(img);
        example = example.expandDims(0);
        const output = await model.predict(example).data();
        console.log(output);
    }

当我运行它时,它在控制台上给出了这个错误:

Uncaught (in promise) Error: This execution contains the node 'SecondStagePostprocessor/BatchMultiClassNonMaxSuppression/map/while/Exit_4', which has the dynamic op 'Exit'. Please use model.executeAsync() instead. Alternatively, to avoid the dynamic ops, specify the inputs [SecondStagePostprocessor/BatchMultiClassNonMaxSuppression/map/TensorArrayStack_2/TensorArrayGatherV3]
    at t.compile (tfjs:2)
    at t.execute (tfjs:2)
    at t.execute (tfjs:2)
    at predict ((index):85)
    at /websites/optik2/async http://localhost/websites/optik2/:96

我需要predict() 函数,executeAsync() 不是很好。

编辑

好的,我现在使用 executeAsync,正如 @Jason Mayes 所说。但它会返回一些类似的值:

t {kept: false, isDisposedInternal: false, shape: Array(3), dtype: "float32", size: 1200, …}
rank: 3
isDisposed: false
kept: false
isDisposedInternal: false
shape: (3) [1, 300, 4]
dtype: "float32"
size: 1200
strides: (2) [1200, 4]
dataId: {}
id: 2198
rankType: "3"
scopeId: 3545
__proto__: Object

我怎样才能得到这个的边界框?

【问题讨论】:

  • executeAsync() 有什么问题?
  • 好的,我正在使用它。你知道我怎样才能从 executeAsync 获得边界框吗?这是我自己的模型
  • 目前返回什么?由于它是异步的,因此您需要等待它完成才能填充输出。下面更新了答案。

标签: tensorflow tensorflow.js


【解决方案1】:

const output = await model.executeAsync(data) 的输出长度是多少?

您应该在output 中查找这些形状;

output[X] = detection_boxes   // shape: [1, x, 4]  x: number of bounding boxes
output[Y] = detection_scores  // shape: [1, x]     x: number of scores
output[Z] = detection_classes // shape: [1, x]     x: number of classes

然后你可以通过以下方式获取预测;

const boxes = output[0].dataSync()
const scores = output[1].arraySync()
const classes = output[2].dataSync()

然后,您可以通过这样做来构造一个包含所有预测边界框的预测对象;

buildDetectedObjects(scores, threshold, imageWidth, imageHeight, boxes, classes, classesDir) {
    const detectionObjects = []
    scores.forEach((score, i) => {
      if (score > threshold) {
        const bbox = [];
        const minY = boxes[i * 4] * imageHeight;
        const minX = boxes[i * 4 + 1] * imageWidth;
        const maxY = boxes[i * 4 + 2] * imageHeight;
        const maxX = boxes[i * 4 + 3] * imageWidth;
        bbox[0] = minX;
        bbox[1] = minY;
        bbox[2] = maxX - minX;
        bbox[3] = maxY - minY;

        detectionObjects.push({
          class: classes[i],
          label: classesDir[classes[i]].name,
          score: score.toFixed(4),
          bbox: bbox
        })
      }
    })

    return detectionObjects
  }

classesDir 是包含培训课程的字典;

let classesDir = {
    1: {
        name: 'Class name 1',
        id: 1,
    },
    2: {
        name: 'Class name 2',
        id: 2,
    }
}

预测对象将是一个包含对象的数组;

[{
  bbox:[x,y,width,height],
  class: X,
  label: class name,
  score: 0.XYZ
},
{
  bbox:[x,y,width,height],
  class: X,
  label: class name,
  score: 0.XYZ
}]

【讨论】:

  • 太棒了!谢谢!
【解决方案2】:

您正在使用 console.log 来显示张量。

console.log(tensor)

相反,您需要使用张量的print 方法来查看其输出。

tensor.print() 

从后端获取张量后,可以使用console.log将输出显示为纯js数组

data = await tensor.data()
console.log(data) // plain js array

【讨论】:

  • 感谢您的回复。 tensor.data() 或 tensor.dataSync(),只返回 Float32Array。我怎样才能得到边界框?
  • 如果您使用datadataSync,您将拥有一个包含所有数据的数组。但是如果你想让数组保持与张量相同的形状,你可以使用arrayarraySync
  • 边界框呢?我如何解释结果?
  • 查看形状[1, 300, 4],您在图像中有 300 个边界框或检测。
  • 我怎样才能访问这些?
【解决方案3】:

尝试 model.executeAsync() 而不是 predict。

因为它是异步的,你应该使用:

const output = await model.executeAsync(data);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2016-05-02
    • 2014-01-21
    • 2018-01-14
    相关资源
    最近更新 更多