为什么在将像素值添加到数组时,tensorflow lite 示例使用 image_mean 和 image_std ?

Cam*_*art 4 android machine-learning computer-vision tensorflow-lite

查看https://github.com/tensorflow/examples/blob/master/lite/examples/image_classification/android/app/src/main/java/org/tensorflow/lite/examples/classification/tflite/ClassifierFloatMobileNet.java

你能帮我理解为什么他们- IMAGE_MEAN/ IMAGE_STD吗?

  private static final float IMAGE_MEAN = 127.5f;
  private static final float IMAGE_STD = 127.5f;

  //...

@Override
  protected void addPixelValue(int pixelValue) {
    imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
    imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
    imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
  }
Run Code Online (Sandbox Code Playgroud)

您会注意到量化示例不需要它(请参阅https://github.com/tensorflow/examples/blob/master/lite/examples/image_classification/android/app/src/main/java/org/tensorflow/lite /examples/classification/tflite/ClassifierQuantizedMobileNet.java)。

@Override
  protected void addPixelValue(int pixelValue) {
    imgData.put((byte) ((pixelValue >> 16) & 0xFF));
    imgData.put((byte) ((pixelValue >> 8) & 0xFF));
    imgData.put((byte) (pixelValue & 0xFF));
  }
Run Code Online (Sandbox Code Playgroud)

到目前为止的粗略想法......

  • 127.5 = 255 / 2。像素通常使用 0-255 的范围表示为颜色。这正是该范围的中间。所以每个像素颜色都被调整到 -1 和 1 之间......但是为什么呢?

mia*_*t17 10

127.5 = 255 / 2。像素通常使用 0-255 的范围表示为颜色。这正是该范围的中间。所以每个像素颜色都被调整到 -1 和 1 之间......

这是完全正确的。

但为什么?

输入标准化是机器学习中的常用技术。这个特定模型是用输入值范围 -1 到 1 进行训练的,因此我们应该将推理输入标准化到相同的范围以获得最佳结果。

直观地说,如果输入没有标准化为 -1 到 1,会出现什么问题:

  • 例如,如果我们不小心设置了 IMAGE_MEAN=0.0f & IMAGE_STD = 255.0f,它会将输入标准化为 0 到 1。模型仍然会“看到”图像,但一切都会变得更亮。准确率可能会下降一点
  • 如果我们不进行归一化,只是将uint8转换为float,则当期望为-1~1时,值范围为0~255。模型可能会“看到”超亮/白色图像。准确性可能会显着下降或根本不起作用。

范围可以是任意的。经常使用-1~1和0~1。要点是相同的归一化应该应用于训练和推理。