使用Web Worker执行tensorflowjs-Angular 11的model.predict

使用Web Worker执行tensorflowjs-Angular 11的model.predict,angular,web-worker,tensorflow.js,Angular,Web Worker,Tensorflow.js,我试图在web worker中执行model.predict函数,但我找不到在web worker中如何导入Tensorflowjs 我可以使用importScripts('cdn'),但是如何引用tensorflow来使用它的函数呢 这是迄今为止的代码: worker.js /// <reference lib="webworker" /> importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@

我试图在web worker中执行
model.predict
函数,但我找不到在web worker中如何导入Tensorflowjs

我可以使用importScripts('cdn'),但是如何引用tensorflow来使用它的函数呢

这是迄今为止的代码:

worker.js

/// <reference lib="webworker" />
importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js');

addEventListener('message', async ({ data }) => {
  const model = data.model;
  const pred = await model.predict(data.tensor);
  postMessage(pred);
});
predict() {
   if (typeof Worker !== 'undefined') {
  // Create a new
  const worker = new Worker('../workers/model.worker', { type: 'module' });
  worker.onmessage = ({ data }) => {
    console.log(Array.from(data.dataSync()));
  };
  worker.postMessage({tensor, model: this._model});
  } else {
    // Web Workers are not supported in this environment.
    // You should add a fallback so that your program still executes correctly.
  }
}

您不能对自定义对象的方法进行后期消息传递,因此需要从Worker本身初始化这个
模型
张量,以便它拥有所有的方法

为此,如果确实从DOM元素生成张量,则首先需要从主线程通过
tf.browser.fromPixels()
生成张量,然后将张量数据提取为发送给工作线程的TypedArray。然后在Worker中,您将能够从该TypedArray创建一个新的tensor实例

下面是使用辅助程序的重写(预测结果可能需要一些时间才能显示)

onload=async(evt)=>{
const-worker=新工作者(getWorkerURL());
const imgElement=document.querySelector('img');
//像往常一样得到张量
常量img=tf.browser.fromPixels(imgElement);
//提取为TypedArray,以便我们可以转移到Worker
常量数据=等待img.data();
img.dispose();
//等待工人准备好
//(Chrome中的奇怪错误,消息事件会丢失,否则…)
worker.onmessage=(evt)=>{
//对结果做点什么
worker.onmessage=({data})=>
展示结果(信息、数据);
//将我们提取的数据传输给工人
worker.postMessage(数据,[data.buffer]);
};
}
函数显示结果(元素、类){
const predictionContainer=document.createElement('div');
predictionContainer.className='pred container';
常量imgContainer=document.createElement('div');
imgContainer.appendChild(imgElement);
predictionContainer.appendChild(imgContainer);
const probsContainer=document.createElement('div');
for(设i=0;i
.pred容器{
边缘底部:20px;
}
.pred容器>div{
显示:内联块;
右边距:20px;
垂直对齐:顶部;
}
.行{
显示:表格行;
}
.细胞{
显示:表格单元格;
右边填充:20px;
}

//我们需要在这里加载tensorflow
进口文件(“https://cdn.jsdelivr.net/npm/@张量流/tfjs@2.0.0/地区/交通运输署(民建联);;
(异步()=>{
常数MOBILENET_模型_路径=
'https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json';
const IMAGE_SIZE=224;
常数TOPK_预测=10;
//加载模型
//请注意,“tf”由于“importScripts”而在全球范围内可用
const mobilenet=wait tf.loadLayersModel(mobilenet_MODEL_PATH);
//让主线程知道我们已经准备好了
//(Chrome中的奇怪错误,消息事件会丢失,否则…)
邮递信息(“就绪”);
self.onmessage=async({data})=>{
常数img=tf.张量(数据);
const logits=tf.tidy(()=>{
常数偏移=tf.标量(127.5);
//将图像从[0,255]规格化为[-1,1]。
常量归一化=img.sub(偏移量).div(偏移量);
//重塑为单个元素批次,以便我们可以将其传递给预测。
const batched=规格化。重塑([1,图像大小,图像大小,3]);
返回mobilenet.predict(分批);
});
//将登录项转换为概率和类名。
常量类=等待gettopkclass(logits、TOPK_预测);
邮资(类别);
}
异步函数gettopkclass(logits,topK){
常量值=等待logits.data();
常量值和索引=[];
for(设i=0;i{
返回b.value-a.value;
});
const topkValues=新的Float32Array(topK);
const topkIndices=新的Int32Array(topK);
for(设i=0;i
主要工作人员和可序列化的子工作人员之间交换的数据。因此,您不能传递模型本身,也不能传递tf.tensor。另一方面,您可以传递数据并在workers中构造张量

为了让编译器知道您导入了一个全局变量,您需要声明
tf

declare let tf: any // or find better type

你所说的
是什么意思?我如何引用tensorflow来使用它的函数
?例如,编译器无法识别tf并抛出错误。即使我将tensorflow包含在importScripts中,问题是我不能使用对使用importScripts导入的tf的引用。编译器无法识别它并抛出错误。这将是另一个问题。。。也许吧,但我