Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果在节点而不是浏览器中运行,则会有不同的预测(使用相同的模型\u web-python转换模型)_Javascript_Node.js_Tensorflow_Tensorflow.js_Tfjs Node - Fatal编程技术网

Javascript 如果在节点而不是浏览器中运行,则会有不同的预测(使用相同的模型\u web-python转换模型)

Javascript 如果在节点而不是浏览器中运行,则会有不同的预测(使用相同的模型\u web-python转换模型),javascript,node.js,tensorflow,tensorflow.js,tfjs-node,Javascript,Node.js,Tensorflow,Tensorflow.js,Tfjs Node,对于ML和tensorflow来说,这是一个全新的概念 我制作了一个对象检测模型,它允许训练和转换不同格式的模型,还有tfjs(model_web)。 该网站还提供了在浏览器中运行模型的样板(react应用程序)。。。就像你所做的一样——可能是相同的代码,没有花足够的时间 因此,我在浏览器中运行了这个模型,考虑到我给出的示例数量和预测分数(0.89),对照片中的对象进行预测,结果非常好。给定的边界框也很好 但是,不幸的是,我没有“一个视频”在浏览器中逐帧分析,我有很多视频。所以我决定切换到nod

对于ML和tensorflow来说,这是一个全新的概念

我制作了一个对象检测模型,它允许训练和转换不同格式的模型,还有tfjs(model_web)。 该网站还提供了在浏览器中运行模型的样板(react应用程序)。。。就像你所做的一样——可能是相同的代码,没有花足够的时间

因此,我在浏览器中运行了这个模型,考虑到我给出的示例数量和预测分数(0.89),对照片中的对象进行预测,结果非常好。给定的边界框也很好

但是,不幸的是,我没有“一个视频”在浏览器中逐帧分析,我有很多视频。所以我决定切换到node.js,按原样移植代码。 你猜怎么着?js依赖于DOM和浏览器组件,几乎不存在与Node一起工作的示例。所以没什么大不了的,只是花了一个上午找出了所有缺失的部分。 最后,我能够以相当快的速度在分割成帧的视频上运行我的模型——尽管在我已经使用tfjs节点的时候有“Hello here,use tfjs node to gain speed”(你好,使用tfjs节点提高速度)的横幅——但结果似乎很奇怪。 将同一张图片与同一个model_web文件夹进行比较,得出了相同的预测,但分数较低(0.80而不是0.89),边界框不同,对象根本不居中

(TL;DR)

tfjs是否有不同的库实现(tfjs和tfjs节点),它们对同一模型有不同的使用?我不认为这是一个输入问题,因为在经过长时间的搜索和斗争后,我找到了两种方法将图像提供给节点中的tf.browser.getPixel(我仍然想知道为什么我必须在tfjs节点中使用“browser”方法)。有人做过比较吗?

所以。。。这就是我使用的代码,供您参考:

模型web正在加载
tf.loadGraphModel(“file://path/to/model_web/model.json");

转换JPG并使其与tf.browser.getPixel()配合使用的两种不同方法

这就是使用加载的模型进行预测的代码-节点和浏览器的相同代码,在中找到-在节点上无法正常工作,我更改了
require(@tensorflow/tfjs”)require(@tensorflow/tfjs节点)的code>并用
fs.read替换
fetch

const runObjectDetectionPrediction = async (graph, labels, input) => {
    const batched = tf.tidy(() => {
        const img = tf.browser.fromPixels(input);
        // Reshape to a single-element batch so we can pass it to executeAsync.
        return img.expandDims(0);
    });

    const height = batched.shape[1];
    const width = batched.shape[2];

    const result = await graph.executeAsync(batched);

    const scores = result[0].dataSync();
    const boxes = result[1].dataSync();

    // clean the webgl tensors
    batched.dispose();
    tf.dispose(result);

    const [maxScores, classes] = calculateMaxScores(
        scores,
        result[0].shape[1],
        result[0].shape[2]
    );

    const prevBackend = tf.getBackend();
    // run post process in cpu
    tf.setBackend("cpu");
    const indexTensor = tf.tidy(() => {
        const boxes2 = tf.tensor2d(boxes, [result[1].shape[1], result[1].shape[3]]);
        return tf.image.nonMaxSuppression(
            boxes2,
            maxScores,
            20, // maxNumBoxes
            0.5, // iou_threshold
            0.5 // score_threshold
        );
    });
    const indexes = indexTensor.dataSync();
    indexTensor.dispose();
    // restore previous backend
    tf.setBackend(prevBackend);

    return buildDetectedObjects(
        width,
        height,
        boxes,
        maxScores,
        indexes,
        classes,
        labels
    );
};
对库(tfjs和tfjs节点)执行不同的实现,以对同一模型进行不同的使用

如果在浏览器和nodejs中部署相同的模型,则预测结果将是相同的

如果预测值不同,则可能与用于预测的张量有关。从图像到张量的处理可能不同,导致用于预测的张量不同,从而导致输出不同

我想出了两种方法将图像提供给节点中的tf.browser.getPixel(我仍然想知道为什么我必须在tfjs节点中使用“browser”方法)


canvas包使用系统图形创建可由nodejs使用的类似浏览器的canvas环境。这使得使用tf.browser名称空间成为可能,特别是在处理图像转换时。但是,仍然可以直接使用nodejs缓冲区创建张量。

您是否检查了浏览器和nodejs中用于预测的张量是否相同?我在两个预测(服务器和浏览器)中使用了相同的照片。也许我应该把所有的代码(包括服务器端和浏览器端)打包并发布到github上。因此,了解这一领域的人可以有更多的背景。这个问题可能与你在预测之前的处理有关。您可以尝试打印您的张量,并查看它在浏览器和节点中的外观。你可以在这里为这个问题添加更多的上下文,因为即使你在github上问这个问题,只要我有空闲时间,你就会被重定向到这里,我会在某个地方部署一个带有来自两个环境的预测的repo。也许你可以告诉我这些环境产生的张量是否不同。谢谢你的信息。
const runObjectDetectionPrediction = async (graph, labels, input) => {
    const batched = tf.tidy(() => {
        const img = tf.browser.fromPixels(input);
        // Reshape to a single-element batch so we can pass it to executeAsync.
        return img.expandDims(0);
    });

    const height = batched.shape[1];
    const width = batched.shape[2];

    const result = await graph.executeAsync(batched);

    const scores = result[0].dataSync();
    const boxes = result[1].dataSync();

    // clean the webgl tensors
    batched.dispose();
    tf.dispose(result);

    const [maxScores, classes] = calculateMaxScores(
        scores,
        result[0].shape[1],
        result[0].shape[2]
    );

    const prevBackend = tf.getBackend();
    // run post process in cpu
    tf.setBackend("cpu");
    const indexTensor = tf.tidy(() => {
        const boxes2 = tf.tensor2d(boxes, [result[1].shape[1], result[1].shape[3]]);
        return tf.image.nonMaxSuppression(
            boxes2,
            maxScores,
            20, // maxNumBoxes
            0.5, // iou_threshold
            0.5 // score_threshold
        );
    });
    const indexes = indexTensor.dataSync();
    indexTensor.dispose();
    // restore previous backend
    tf.setBackend(prevBackend);

    return buildDetectedObjects(
        width,
        height,
        boxes,
        maxScores,
        indexes,
        classes,
        labels
    );
};