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

Why does the tensorflow lite example use image_mean and image_std when adding pixel values to the array?

正在查看 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);
  }

您会注意到,对于量化示例(请参阅 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));
  }

目前粗略的想法....

127.5 = 255 / 2. Pixels are frequently represented as colors using a range from 0-255. This is exactly the middle of that range. So every pixel color is being adjusted to be between -1 and 1...

完全正确。

but why?

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

凭直觉,如果输入未标准化为 -1 到 1,会出现什么问题:

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

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