无法使用 Tensorflow.js predict() 函数

Can't use Tensorflow.js predict() function

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

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()这样不好

编辑

好的,我现在按照 @Jason Mayes 所说的那样使用 executeAsync。但它返回了一些这样的值:

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

如何获取这个的边界框?

尝试 model.executeAsync() 而不是预测。

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

常量输出=等待model.executeAsync(数据);

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

console.log(tensor)

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

tensor.print() 

从后端获取张量后,console.log可以用来将输出显示为普通的js数组

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

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
}]