TF.js 在浏览器中以 model.json 格式加载对象检测模型

TF.js load object detection model in model.json format in browser

我使用 Colab 在 python 中训练了一个 .pb 对象检测模型,并使用 TensorFlow converter 将其转换为 model.json 格式。我需要在浏览器中加载此模型(没有 Node.js!)并在那里进行 运行 推理。 这是 TensorFlow converter 生成的我的模型文件夹的结构:

model
| - model.json
| - labels.json
| - group1-shard1of2.bin
| - group1-shard2of2.bin

Tensorflow documentation建议如下加载这样的模型:

const model = await tf.loadGraphModel('model/model.json');

const model = await tf.loadLayersModel('model/model.json');

我正在使用 tf.loadGraphModel 函数。加载模型完美无缺,但是当我尝试 运行 使用此代码对其进行推理时:

// detect objects in the image.
const img = document.getElementById('img'); 
model.predict(img).then(predictions => {
    console.log('Predictions: ');
    console.log(predictions);
});

它抛出以下错误:

Uncaught (in promise) Error: The dict provided in model.execute(dict) has keys [...] that are not part of graph
at e.t.checkInputs (graph_executor.js:607)
at e.t.execute (graph_executor.js:193)
at e.t.execute (graph_model.js:338)
at e.t.predict (graph_model.js:291)
at predictImages (detector.php:39)

我是否使用了错误的加载函数,模型加载过程是否失败(即使它没有抛出任何错误?)还是推理函数错误? 在此先感谢您的支持!

编辑: 在使用@edkeveked 的建议首先使用此代码将图像转换为张量之后:

const tensor = tf.browser.fromPixels(img);

和运行宁推理使用这个:

model.predict(tensor.expandDims(0));

我收到此错误消息:

Uncaught (in promise) Error: This execution contains the node 'Preprocessor/map/while/Exit_2', which has the dynamic op 'Exit'. Please use model.executeAsync() instead. Alternatively, to avoid the dynamic ops, specify the inputs [Preprocessor/map/TensorArrayStack/TensorArrayGatherV3]
    at e.t.compile (graph_executor.js:162)
    at e.t.execute (graph_executor.js:212)
    at e.t.execute (graph_model.js:338)
    at e.t.predict (graph_model.js:291)
    at predictImages (detector.php:38)

model.predict() 替换为 model.executeAsync() 后,它返回的结果不是我期望从对象检测模型中得到的结果:

detector.php:40 (2) [e, e]0: e {kept: false, isDisposedInternal: false, shape: Array(3), dtype: "float32", size: 3834, …}1: e {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 7668, …}length: 2__proto__: Array(0)

这是我到目前为止的完整代码(使用 PHP 在 HTML 中添加的图像):

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.8.3/dist/tf.min.js"></script>
    <!-- Load the coco-ssd model. -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@1.1.0"></script>

    <script>
    async function predictImages() { // async
        console.log("loading model");
        // Load the model.
        const model = await tf.loadGraphModel('model/model.json');
        console.log("model loaded.");
        
        // predict for all images
        for (let i = 0; i <= 4; i++) {
            const img = document.getElementById('img' + i); // check if image exists if (img
            if (img != null) {
                console.log("doc exists: " + 'img' + i);
                const tensor = tf.browser.fromPixels(img);
                model.executeAsync(tensor.expandDims(0)).then(predictions => {
                    console.log('Predictions: ');
                    console.log(predictions);
                });
             
            } else {
                break;
            }
        }
    }
    predictImages();
    </script>

model.predict 需要一个张量,但它被赋予了一个 HTMLImageElement。首先需要从 HTMLImageElement 构造一个张量。

const tensor = tf.browser.fromPixels(img)

然后张量可以作为参数model.predict

model.predict(tensor) // returns a 3d

最后但并非最不重要的一点是确保张量形状是模型预期的形状(3d 或 4d)。如果模型需要 4d,那么它应该是

model.predict(tensor.expandDims(0))