【问题标题】:how to convert Lenet model h5 to .tflite如何将 Lenet 模型 h5 转换为 .tflite
【发布时间】:2020-10-10 21:07:05
【问题描述】:

如何正确地将 Lenet 模型(输入 32x32、5 层、10 个类)转换为 Tensorflow Lite?我使用了这行代码,但它让我对 android like this image 的信心非常糟糕。置信度都在 0.1 或 10% 左右。

这是我使用的代码

model = tf.keras.models.load_model('model.h5')
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.post_training_quantize = True
tflite_model = converter.convert()
open("converted_model.tflite", "wb").write(tflite_model)

上面的 .h5 文件可以以良好的置信度和准确度预测图像,like this image。或者我应该问,Tensorflow Lite 不支持自定义模型(Lenet)吗?为什么 tflite 文件比 .h5 差这么多?

【问题讨论】:

  • 你为什么使用 post_training_quantize?您是说您使用 32x32 图像。你的手机处理这么小的图片有那么难吗?在您的手机中处理一张图像需要多长时间?
  • @Farmaker 实际上,如果我删除量化并正常转换它,它没有区别,这就是为什么我想知道 tensorflow lite 是否不支持自定义 lenet 模型。而且,处理一张图像只需不到 1 秒。
  • 为什么要除以 3 (/ 3 / 255f) ?这通常用于灰度图像。我看到你的图片是彩色的。
  • 所以根据您的主要问题,我认为我们已经完成了。转换模型(无论是否量化)都没有问题。接下来我们必须查看要调试的代码。有github链接吗?
  • 感谢您的链接。是否可以上传 .h5 文件和一些图片进行检查?

标签: python tensorflow keras tensorflow-lite


【解决方案1】:

如果生成的 .tflite 文件没有错误,则模型是否称为 Lenet 或其他任何名称都没有关系。此外,量化的准确性会略有下降,但没有像您所说的那样有重大差异。我会看看你是如何制作字节缓冲区以将其插入解释器的。如果您使用的是灰度图像,则必须除以 3/255 ......对于彩色图像只有 /255。如果在您的训练期间您没有使用像素归一化,那么在位图到字节缓冲区期间不要使用 /255。所以你的代码会是这样的:

private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(ModelConfig.MODEL_INPUT_SIZE);
    byteBuffer.order(ByteOrder.nativeOrder());
    int[] pixels = new int[ModelConfig.INPUT_WIDTH * ModelConfig.INPUT_HEIGHT];
    bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
    for (int pixel : pixels) {
        float rChannel = (pixel >> 16) & 0xFF;
        float gChannel = (pixel >> 8) & 0xFF;
        float bChannel = (pixel) & 0xFF;
        float pixelValue = (rChannel + gChannel + bChannel);
        byteBuffer.putFloat(pixelValue);
    }
    return byteBuffer;
}

而不是:

private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(ModelConfig.MODEL_INPUT_SIZE);
    byteBuffer.order(ByteOrder.nativeOrder());
    int[] pixels = new int[ModelConfig.INPUT_WIDTH * ModelConfig.INPUT_HEIGHT];
    bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
    for (int pixel : pixels) {
        float rChannel = (pixel >> 16) & 0xFF;
        float gChannel = (pixel >> 8) & 0xFF;
        float bChannel = (pixel) & 0xFF;
        float pixelValue = (rChannel + gChannel + bChannel) / 255.f;
        byteBuffer.putFloat(pixelValue);
    }
    return byteBuffer;
}

【讨论】:

    【解决方案2】:

    这是因为量化。
    它减小了模型的大小,从而降低了准确性。尽量不要量化模型。
    试试这个。

    import tensorflow as tf
    
    model = tf.keras.models.load_model('model.h5')
    converter = tf.lite.TFLiteConverter.from_keras_model(model)
    tflite_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_model)
    

    它可能会增加 tflite 模型的大小,但不会降低准确度。

    【讨论】:

    • 我实际上有 2 个可以量化和不量化的 python 代码,并且两个代码都将 .h5 文件缩小到 .tflite(从 729kb .h5 到 244kb .tflite),并且具有完全相同的置信度。有没有其他办法?
    • 目前,没有。如果找到另一种方式并且同样明智,会通知您。
    猜你喜欢
    • 2020-09-10
    • 1970-01-01
    • 2022-12-22
    • 2021-12-09
    • 2019-06-10
    • 2021-06-11
    • 1970-01-01
    • 2019-04-14
    • 2020-12-15
    相关资源
    最近更新 更多