Javascript 如果在节点而不是浏览器中运行,则会有不同的预测(使用相同的模型\u web-python转换模型)
对于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正在加载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
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
);
};