Reputation: 1016
I build a simple tensorflowjs app with plain Jquery and it was working fine, although prediction wasn't that great but it worked.
Now, I started building a GUI for the app using Vue3 which I have create using @vue/cli. I have installed couple of other plugin such as tailwindcss, clmtrackr via npm and they are working fine.
Now I have installed the tensorflowjs using npm -
npm install @tensorflow/tfjs
Everything installed without any error but when I ran the app after setting up code for model creation and training, I started getting error -
Uncaught (in promise) TypeError: Cannot read property 'backend' of undefined
at Engine.moveData (engine.js?6ae2:288)
at DataStorage.get (backend.js?8b87:29)
at eval (backend_webgl.js?5edb:497)
at Array.every (<anonymous>)
at MathBackendWebGL.shouldExecuteOnCPU (backend_webgl.js?5edb:497)
at concatImpl (Concat_impl.js?2cbf:39)
at Object.concat [as kernelFunc] (Concat.js?b4c2:35)
at kernelFunc (engine.js?6ae2:463)
at eval (engine.js?6ae2:524)
at Engine.scopedRun (engine.js?6ae2:337)
First I thought I probably need to install - @tensorflow/tfjs-node which is made for NodeJs but I still went ahead and installed it. Ofcourse it didn't work because I had node v.14 so I started getting node-gyp error. I read that I need to install it with older version of node v12 so I install nvm and installed another version of nodejs and then run @tensorflow/tfjs-node and it worked. After that I started getting bunch of error which I expected already because this package is made for NodeJS.
Next, I deleted my node_modules folder and modified package.json to remove node version of tensorflow and ran
npm install
to install all fresh packages with their latest version. Everything installed without any error but the Cannot read property 'backend' didn't get resolved.
Surprisingly, when I ran the code in firefox I got info of undefined error and in chrome backed of undefined error which I don't understand.
The code which is causing the error was this -
async trainModel(imageArray, labelArray) {
// tf.getBackend()
let imageSet = tf.tidy(() => {
return tf.concat(imageArray); <--------------- Error
});
let labelSet = tf.tidy(() => {
return tf.oneHot(tf.tensor1d(labelArray, 'int32'), 3);
})
this.model.fit(.............
}
How do I know that? Well I returned null in tf.tidy() and I did get pass through to next code block. I went through so many github issues and they all had different issues with same error.
So there might be doubt about my process for creating dataset which is described here in my other post.
Please someone help me. It has been almost entire week since I had this problem.
Edit 1 :
So any operation on imageArray causes backend error which might actually b related to how I am creating dataset and passing it to the class method.
How I figured this out? I tried
console.log(imageArray.toString()) <--- this causes backend error
console.log(imageArray) < -- this doesn't
|
---> console output <--------------------------------
Tensor {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 135000, …} (4) [1, 150, 300, 3]
Models.vue?2820:139 Tensor {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 135000, …} (4) [1, 150, 300, 3]
Models.vue?2820:139 Tensor {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 135000, …} (4) [1, 150, 300, 3]
Models.vue?2820:139 Tensor {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 135000, …} (4) [1, 150, 300, 3]
Models.vue?2820:139 Tensor {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 135000, …} (4) [1, 150, 300, 3]
TFModel.js?4fc1:71 Proxy {0: Tensor, 1: Tensor, 2: Tensor, 3: Tensor, 4: Tensor}
I am adding my dataset creation method in vue3 app -
initCanvas() {
this.mycan.canvas = this.$refs.mycan;
this.mycan.context = this.mycan.canvas.getContext('2d')
this.mycan.w = this.mycan.canvas.width
this.mycan.h = this.mycan.canvas.height
},
collectData() {
const img = tf.tidy(() => {
const captureImg = this.getImage();
console.log(captureImg, captureImg.shape)
return captureImg;
})
this.imageArray.push(img)
this.label = parseInt(Math.random() * 3)
this.labelArray.push(this.label) //--- labels are 0,1,2
},
getImage() {
return tf.tidy(() => {
const image = tf.browser.fromPixels(this.mycan.canvas);
const batchedImage = image.expandDims(0);
const norm = batchedImage.toFloat().div(tf.scalar(255)).sub(tf.scalar(1));
return norm;
});
}
Edit 2 :
So I ran another test on getImage() method and logged the returned value. It return all the values mentioned below correctly but throws same backend of undefined error at the same time
let imgData = this.getImage()
console.log(imgData)
console.log(imgData.shape)
console.log(imgData.toString())
<--- console output-->
Tensor {kept: false, isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 135000, …}
Models.vue?2820:119 (4) [1, 150, 300, 3]
Models.vue?2820:120 Tensor
[[[[-0.6117647, -0.5411765, -0.3450981],
[-0.6117647, -0.5411765, -0.3450981],
[-0.6117647, -0.5411765, -0.3450981],
...,
[-0.5333334, -0.5019608, -0.3176471],
[-0.5333334, -0.5019608, -0.3176471],
[-0.5333334, -0.5019608, -0.3176471]],
[[-0.6039216, -0.5333334, -0.3372549],
[-0.6078432, -0.5372549, -0.3411765],
[-0.6078432, -0.5372549, -0.3411765],
...,
[-0.5372549, -0.5019608, -0.3176471],
[-0.5372549, -0.5019608, -0.3176471],
[-0.5372549, -0.5019608, -0.3176471]],
[[-0.6 , -0.5294118, -0.3333334],
[-0.6 , -0.5294118, -0.3333334],
[-0.6 , -0.5294118, -0.3333334],
...,
[-0.5372549, -0.4980392, -0.3176471],
[-0.5372549, -0.4980392, -0.3176471],
[-0.5333334, -0.4941177, -0.3137255]],
...
[[-0.4039216, -0.454902 , -0.3529412],
[-0.4078432, -0.4588236, -0.3568628],
[-0.4078432, -0.4588236, -0.3568628],
...,
[-0.309804 , -0.3254902, -0.2352942],
[-0.309804 , -0.3254902, -0.2352942],
[-0.309804 , -0.3254902, -0.2352942]],
[[-0.4039216, -0.454902 , -0.3529412],
[-0.4039216, -0.454902 , -0.3529412],
[-0.4039216, -0.454902 , -0.3529412],
...,
[-0.3058824, -0.3215687, -0.2313726],
[-0.309804 , -0.3254902, -0.2352942],
[-0.309804 , -0.3254902, -0.2352942]],
[[-0.4039216, -0.454902 , -0.3529412],
[-0.4039216, -0.454902 , -0.3529412],
[-0.4039216, -0.454902 , -0.3529412],
...,
[-0.3058824, -0.3215687, -0.2313726],
[-0.309804 , -0.3254902, -0.2352942],
[-0.309804 , -0.3254902, -0.2352942]]]]
Uncaught TypeError: Cannot read property 'backend' of undefined
at Engine.moveData (engine.js?6ae2:288)
at DataStorage.get (backend.js?8b87:29)
at reshape (Reshape.js?ad24:31)
at conv2dWithIm2Row (Conv2D_impl.js?7600:157)
at Object.fusedConv2d [as kernelFunc] (FusedConv2D.js?2d19:46)
at kernelFunc (engine.js?6ae2:463)
at eval (engine.js?6ae2:524)
at Engine.scopedRun (engine.js?6ae2:337)
at Engine.runKernelFunc (engine.js?6ae2:520)
at Engine.runKernel (engine.js?6ae2:393)
Upvotes: 2
Views: 3211
Reputation: 632
I have faced the same issue in Angular. By reading @Csabi, it occurred to me to try to remove the training from tidy. It worked.💕👌 Even though tidy may work well in pure JavaScript, it seems to be problematic in Angular.
Upvotes: 0
Reputation: 31
I've been in the same situation when I tried to use my model in Vue3. I managed to run predict on model by doing:
import { toRaw } from 'vue'
...
let raw_model = toRaw(this.model)
let result = raw_model.predict(img)
...
Upvotes: 3
Reputation: 1
I've hit the same error in CLI without anything to do with Vue.
In my case I've tried to use a tensor outside tf.tidy(() => {})
scope.
Upvotes: 0
Reputation: 31
In my case, the error seems to be caused by the fact that Vue3 wrapped my model attribute in a Proxy object. You can use Object.freeze() to prevent vue framework to modify your object.
Before:
export default {
data: ()=>({
prediction: null,
model: null
}),
methods:{
async initModel(){
this.model = await tmImage.load(modelURL, metadataURL)
// model is wrapped in a Proxy object
},
async predict(){
this.prediction = await this.model.predict(canvas) // this line throwed error
}
}
}
After:
export default {
data: ()=>({
prediction: null,
model: null
}),
methods:{
async initModel(){
this.model = Object.freeze(await tmImage.load(modelURL, metadataURL))
},
async predict(){
this.prediction = await this.model.predict(canvas)
}
}
}
Upvotes: 3
Reputation: 11
Success:
let model;
model = await tf.loadGraphModel(MODEL_URL)
Error:
let model = ref();
model.value = await tf.loadGraphModel(MODEL_URL);
Anyway, I solved this problem, and it can run normally now.
Upvotes: -1