Javascript tensorflowjs抛出的WASM后端;未处理的拒绝(RuntimeError):索引超出范围;Reactjs中的错误
我正在尝试在react应用程序中为blazeface人脸检测模型设置WASM后端。尽管带vanillajs的演示可以在数小时内无任何错误地运行,但在react中,它会在打开cam超过3-5分钟后抛出“未处理拒绝(RuntimeError):索引越界错误” 整个应用程序因此错误而崩溃。从下面的错误日志来看,可能与Javascript tensorflowjs抛出的WASM后端;未处理的拒绝(RuntimeError):索引超出范围;Reactjs中的错误,javascript,reactjs,webassembly,tensorflow.js,Javascript,Reactjs,Webassembly,Tensorflow.js,我正在尝试在react应用程序中为blazeface人脸检测模型设置WASM后端。尽管带vanillajs的演示可以在数小时内无任何错误地运行,但在react中,它会在打开cam超过3-5分钟后抛出“未处理拒绝(RuntimeError):索引越界错误” 整个应用程序因此错误而崩溃。从下面的错误日志来看,可能与disposeData()或disposedensor()函数有关,我猜它们与垃圾收集有关。但我不知道它是否是来自WASM库本身的bug。你知道为什么会这样吗 下面我还提供了渲染预测功能
disposeData()
或disposedensor()
函数有关,我猜它们与垃圾收集有关。但我不知道它是否是来自WASM库本身的bug。你知道为什么会这样吗
下面我还提供了渲染预测功能
renderPrediction=async()=>{
const model=await blazeface.load({maxFaces:1,scoreThreshold:0.95});
如果(这个游戏){
const canvas=this.refCanvas.current;
const ctx=canvas.getContext(“2d”);
常量返回张量=假;
常量flipHorizontal=true;
const=true;
常数预测=等待模型.estimateFaces(
this.refVideo.current,
返回张量,
水平翻转,
注释框
);
如果(长度>0){
clearRect(0,0,canvas.width,canvas.height);
for(设i=0;i<0.length;i++){
if(返回张量){
预测[i].topLeft=预测[i].topLeft.arraySync();
预测[i].bottomRight=预测[i].bottomRight.arraySync();
如果(注释框){
预测[i]。landmarks=预测[i]。landmarks.arraySync();
}
}
试一试{
}捕捉(错误){
控制台日志(错误消息);
}
常数开始=预测[i]。左上角;
const end=预测[i]。右下角;
常量大小=[end[0]-start[0],end[1]-start[1]];
如果(注释框){
常数地标=预测[i]。地标;
ctx.fillStyle=“蓝色”;
for(设j=0;j
错误的完整日志:
Unhandled Rejection (RuntimeError): index out of bounds
(anonymous function)
unknown
./node_modules/@tensorflow/tfjs-backend-wasm/dist/tf-backend-wasm.esm.js/</tt</r</r._dispose_data
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/wasm-out/tfjs-backend-wasm.js:9
disposeData
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/backend_wasm.ts:115
112 |
113 | disposeData(dataId: DataId) {
114 | const data = this.dataIdMap.get(dataId);
> 115 | this.wasm._free(data.memoryOffset);
| ^ 116 | this.wasm.tfjs.disposeData(data.id);
117 | this.dataIdMap.delete(dataId);
118 | }
disposeTensor
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:838
835 | 'tensors');
836 | let res;
837 | const inputMap = {};
> 838 | inputs.forEach((input, i) => {
| ^ 839 | inputMap[i] = input;
840 | });
841 | return this.runKernelFunc((_, save) => {
dispose
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/tensor.ts:388
endScope
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:983
tidy/<
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:431
428 | if (kernel != null) {
429 | kernelFunc = () => {
430 | const numDataIdsBefore = this.backend.numDataIds();
> 431 | out = kernel.kernelFunc({ inputs, attrs, backend: this.backend });
| ^ 432 | const outInfos = Array.isArray(out) ? out : [out];
433 | if (this.shouldCheckForMemLeaks()) {
434 | this.checkKernelForMemLeak(kernelName, numDataIdsBefore, outInfos);
scopedRun
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:448
445 | // inputsToSave and outputsToSave. Currently this is the set of ops
446 | // with kernel support in the WASM backend. Once those ops and
447 | // respective gradients are modularised we can remove this path.
> 448 | if (outputsToSave == null) {
| ^ 449 | outputsToSave = [];
450 | }
451 | const outsToSave = outTensors.filter((_, i) => outputsToSave[i]);
tidy
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:431
428 | if (kernel != null) {
429 | kernelFunc = () => {
430 | const numDataIdsBefore = this.backend.numDataIds();
> 431 | out = kernel.kernelFunc({ inputs, attrs, backend: this.backend });
| ^ 432 | const outInfos = Array.isArray(out) ? out : [out];
433 | if (this.shouldCheckForMemLeaks()) {
434 | this.checkKernelForMemLeak(kernelName, numDataIdsBefore, outInfos);
tidy
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/globals.ts:190
187 | const tensors = getTensorsInContainer(container);
188 | tensors.forEach(tensor => tensor.dispose());
189 | }
> 190 | /**
191 | * Keeps a `tf.Tensor` generated inside a `tf.tidy` from being disposed
192 | * automatically.
193 | */
estimateFaces
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/blazeface_reactjs/node_modules/@tensorflow-models/blazeface/dist/blazeface.esm.js:17
Camera/this.renderPrediction
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/blazeface_reactjs/src/Camera.js:148
145 | const returnTensors = false;
146 | const flipHorizontal = true;
147 | const annotateBoxes = true;
> 148 | const predictions = await model.estimateFaces(
| ^ 149 | this.refVideo.current,
150 | returnTensors,
151 | flipHorizontal,
async*Camera/this.renderPrediction
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/blazeface_reactjs/src/Camera.js:399
396 | // }
397 | }
398 | }
> 399 | requestAnimationFrame(this.renderPrediction);
| ^ 400 | }
401 | };
402 |
未处理的拒绝(RuntimeError):索引超出范围
(匿名函数)
未知的
./node_modules/@tensorflow/tfjs backend-wasm/dist/tf-backend-wasm.esm.js/{
|^839 | inputMap[i]=输入;
840 | });
841 |返回此。runKernelFunc((|,save)=>{
处置
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/tensor.ts:388
内窥镜
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:983
整洁的/<
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:431
428 |如果(内核!=null){
429 | kernelFunc=()=>{
430 | const numDataIdsBefore=this.backend.numDataIds();
>431 | out=kernel.kernelFunc({inputs,attrs,backend:this.backend});
|^432 | const outingfos=Array.isArray(out)?out:[out];
433 |如果(此.shouldCheckForMemLeaks()){
434 |此项。检查kernelformleak(kernelName、numdataidsbree、outInfos);
scopedRun
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:448
445 |//inputsToSave和outputsToSave。目前这是操作集
446 |//在WASM后端支持内核。一旦这些操作和
447 |//各个梯度模块化,我们可以删除此路径。
>448 |如果(outputsToSave==null){
|^449 | outputsToSave=[];
450 | }
451 | const outsToSave=outTensors.filter(|,i)=>outputsToSave[i]);
整齐的
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/engine.ts:431
428 |如果(内核!=null){
429 | kernelFunc=()=>{
430 | const numDataIdsBefore=this.backend.numDataIds();
>431 | out=kernel.kernelFunc({inputs,attrs,backend:this.backend});
|^432 | const outingfos=Array.isArray(out)?out:[out];
433 |如果(此.shouldCheckForMemLeaks()){
434 |此项。检查kernelformleak(kernelName、numdataidsbree、outInfos);
整齐的
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/src/globals.ts:190
187 |常数张量=getTensorsInContainer(container);
188 | tensors.forEach(tensor=>tensor.dispose());
189 | }
> 190 | /**
191 |*防止在“tf.tidy”中生成的“tf.Tensor”被丢弃
192 |*自动。
193 | */
估计面
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/blazeface_reactjs/node_modules/@tensorflow models/blazeface/dist/blazeface.esm.js:17
摄影机/此.renderPrediction
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/blazeface_reactjs/src/Camera.js:148
145 |常数返回张量=假;
146 | const flipHorizontal=真;
147 | const=true;
>148 |常数预测=等待模型。估计面(
|^149 | this.refVideo.current,
150 |返回张量,
151 |水平翻转,
异步*摄像机/this.renderPrediction
C:/Users/osman.cakir/Documents/osmancakirio/deepLearning/blazeface_reactjs/src/Camera.js:399
396 | // }
397 | }
398 | }
>399 | requestAnimationFrame(此.renderPrediction);
| ^ 400 | }
401 | };
402 |
使用张量进行预测后,您需要将张量从设备内存中释放出来,否则它会累积,并导致潜在的错误。这只需使用tf.dispose()即可完成
手动指定要处理张量的位置。在对十位数进行预测后立即执行此操作
const predictions = await model.estimateFaces(
this.refVideo.current,
returnTensors,
flipHorizontal,
annotateBoxes
);
tf.dispose(this.refVideo.current);
tf.engine().startScope()
// handling image tensors function
tf.engine().endScope()