如何将 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;
}
如何正确地将 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;
}