如何将 Lenet 模型 h5 转换为 .tflite

how to convert Lenet model h5 to .tflite

如何正确地将 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 差这么多?

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

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 模型的大小,但不会将准确性降低到那种程度。

如果生成的 .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;
}