【问题标题】:first shape parameter should be null,but it's not allowed第一个形状参数应该为空,但不允许
【发布时间】:2020-10-05 09:25:19
【问题描述】:

我有这个模型:

这是一个假设检测面部情绪的卷积层, 我尝试在我的 TensorFlowJS 上实现它,所以我转换了它,当我尝试输入输入时,它需要一个 4d 张量,第一个输入为 null, 但 tensor4d 不允许:

形状应该只是一个数字,但是当我尝试将它添加到我的模型时它要求为空,我该怎么办? 这是我将 jpg 转换为张量的函数:

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]);
  };

编辑:这是我的预测功能:

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);
    }
  };

【问题讨论】:

  • 从上面的函数中,你能打印出张量的形状吗?您还在 React Native 应用程序中使用它吗?
  • 我认为你完全误解了我对你其他问题的回答,这里没有这意味着它可以是任何值,而不是它必须为空。在您的情况下,使用 1 完全没问题,它是预期的正确值!
  • @Dr.Snoopy 这就是我这样做时发生的情况:检查时出错:预期 conv2d_8_input 的形状为 [null,48,48,1] 但得到的数组的形状为 [1,560,617,3]。
  • @yuRa 错误有点显示形状,它在本机反应:检查时出错:预期 conv2d_8_input 的形状为 [null,48,48,1] 但得到的数组形状为 [1,560,617,3] .你怎么看?
  • 图片必须是48x48,一个通道,而你的图像是560x617,三个通道,你需要调整图像大小并转换为灰度。该错误与第一个维度无关。

标签: tensorflow keras tensorflow.js


【解决方案1】:

您需要将张量的大小从[1,560, 617,3] 调整为[null,48,48,1]

但是您的模型采用灰度图像,因此您需要先将其从 RGB 转换为灰度:

方法一

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

然后你可以调整它的大小。

第二个参数的数组代表[newHeight,newWidth]

张量是您想要调整为新形状的张量,这将是灰度图像。

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

方法二

或者更简单的方法是使用cameraWithTensor 并立即调整张量的大小。您可以使用以下方法执行此操作,然后您只需将其重塑为 4D 张量:

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>

然后你可以把它重塑成一个 4D 张量:

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

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

【讨论】:

  • 感谢您的帮助,但是关于第一种方法,我什么时候需要将其转换为灰度,就在我获取照片之后?因为我收到此错误:传递给 tf.browser.fromPixels() 的像素必须是浏览器中的 HTMLVideoElement、HTMLImageElement、HTMLCanvasElement、ImageData 或 Webworker 中的 OffscreenCanvas、ImageData 或 {data: Uint32Array, width: number, height: number} ,但是是 Number ,我将所需的图像传递给它
  • 我将代码添加到我的原始帖子中,这样会更清晰
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
相关资源
最近更新 更多