first shape parameter should be null,but it's not allowed

495 Views Asked by At

I have this model:

model I trained

Which is a conv layer that's suppose to detect facial emotions, I try to implement it on my TensorFlowJS, so I converted it and when I try to enter an input, it requires a 4d tensor with null as the first input, but the tensor4d will not allow it: enter image description here

The shape should be a number only, but when I try to add it to my model it asks for null, what do I do? This is the function I convert jpg to tensors:

const imageToTensor = (rawData: ArrayBuffer) => {
    const { width, height, data } = jpeg.decode(rawData, true);
    const buffer = new Uint8Array(width * height * 3);
    let offset = 0;
    for (let i = 0; i < buffer.length; i += 3) {
      buffer[i] = data[offset]; //red
      buffer[i + 1] = data[offset + 1]; //green
      buffer[i + 2] = data[offset + 2]; //blue
      offset += 4; //skips Alpha value
    }
      //instead of 1 I need null, but wont let me -----
    return tf.tensor4d(buffer, [1, height, width, 3]);
  };

EDIT: this is my prediction function :

const trypredict = async () => {
    try {
      let image = require("../assets/smile.jpg");
      image = tf.browser
        .fromPixels(image)
        .mean(2)
        .toFloat()
        .expandDims(0)
        .expandDims(-1);
      const imageAssetPath = Image.resolveAssetSource(image);
      const response = await fetch(imageAssetPath.uri, {}, { isBinary: true });
      const imageData = await response.arrayBuffer();

      let imageTensor = imageToTensor(imageData);
      imageTensor = imageTensor.resizeBilinear([48, 48]);
      if (model) {
        const prediction = await model.predict(imageTensor);
      }
    } catch (error) {
      console.log(error);
    }
  };
1

There are 1 best solutions below

2
On BEST ANSWER

You need to resize the tensor from [1,560, 617,3] to [null,48,48,1]

But your model takes in greyscale images so you need to convert it from RGB to greyscale first:

Method 1

tf.browser.fromPixels(image)
    .mean(2)
    .toFloat()
    .expandDims(0)
    .expandDims(-1)

Then you can resize it.

The array for the second parameter represents the [newHeight,newWidth].

The tensor is the tensor you want to resize to a new shape which would be the greyscale image.

 const alignCorners = true;
 const imageResize = tf.image.resizeBilinear(
          tensor,
          [48, 48],
          alignCorners
        );

Method 2

Or an easier way would be to use cameraWithTensor and resize the tensor immediately. You can do so using the following then after that you would just have to reshape it to a 4D tensor:

return <View>
      <TensorCamera
       // Standard Camera props
       style={styles.camera}
       type={Camera.Constants.Type.front}
       // Tensor related props
       cameraTextureHeight={textureDims.height}
       cameraTextureWidth={textureDims.width}
       resizeHeight={48}
       resizeWidth={48}
       resizeDepth={1}
       onReady={this.handleCameraStream}
       autorender={true}
      />
    </View>

Then you can reshape it into a 4D tensor:

image = image.reshape(1,48,48,1)

Here is a code example using cameraWithTensor with detailed code for it