Firebase 本地模型抛出 "Didn't find op for builtin opcode 'CONV_2D' version '2'"
Firebase Local Model throws "Didn't find op for builtin opcode 'CONV_2D' version '2'"
我得到了一个看起来像这样的模型并对其进行了训练:
keras.layers.Conv2D(128, (3,3), activation='relu', input_shape=(150,150,3)),
keras.layers.MaxPooling2D(2,2),
keras.layers.Dropout(0.5),
keras.layers.Conv2D(256, (3,3), activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.Conv2D(512, (3,3), activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.Flatten(),
keras.layers.Dropout(0.3),
keras.layers.Dense(280, activation='relu'),
keras.layers.Dense(4, activation='softmax')
])
我使用以下代码将其转换为 .tflite:
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file("model.h5")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.post_training_quantize=True
converter.allow_custom_ops=True
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
然后我希望它与本地 Firebase 一起使用:
val bitmap = Bitmap.createScaledBitmap(image, 150, 150, true)
val batchNum = 0
val input = Array(1) { Array(150) { Array(150) { FloatArray(3) } } }
for (x in 0..149) {
for (y in 0..149) {
val pixel = bitmap.getPixel(x, y)
input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 255.0f
input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 255.0f
input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 255.0f
}
}
val localModel = FirebaseCustomLocalModel.Builder()
.setAssetFilePath("model.tflite")
.build()
val interpreter = FirebaseModelInterpreter.getInstance(FirebaseModelInterpreterOptions.Builder(localModel).build())
val inputOutputOptions = FirebaseModelInputOutputOptions.Builder()
.setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 150, 150, 3))
.setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 4))
.build()
val inputs = FirebaseModelInputs.Builder()
.add(input)
.build()
interpreter?.run(inputs, inputOutputOptions)
?.addOnSuccessListener { result ->
val output = result.getOutput<Array<FloatArray>>(0)
val probabilities = output[0]
但是它抛出这个错误:
Internal error: Cannot create interpreter: Didn't find op for builtin opcode 'CONV_2D' version '2'
有人知道我做错了什么吗?我正在使用 tensorflow-gpu 和 tensorflow-estimator 2.3.0
TFLite 运算符有不同 versions。看起来您已经使用较新版本的 Conv2D 转换了模型,而您当前的解释器不支持它。
我在 Android 上尝试 converter.optimizations = [tf.lite.Optimize.DEFAULT]
时遇到了这个问题。所以我建议你在开始时放弃优化和自定义操作:
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file("model.h5")
converter.optimizations = []
converter.post_training_quantize=True
converter.allow_custom_ops=False
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
编辑:
还要确保在转换模型时和在应用程序中使用相同版本的 Tensorflow。老版本解释器不支持新op版本导致版本不匹配
编辑 2(可能更有用):
尝试使用旧版本的 Tensorflow 转换您的模型,假设 2.1 使用命令:
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file("model.h5")
converter.optimizations = []
converter.allow_custom_ops=False
converter.experimental_new_converter = True
tflite_model = converter.convert()
我通过以下更改修复了它:
我这样保存我的模型 (tf-gpu 2.2.0) 或通过我的回调 (.pb):
tf.saved_model.save(trainedModel,path)
在build.gradle中我添加了:
implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly'
implementation'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly'
我通过 运行:
将我的 tensorflow 版本(仅用于转换器)更新为 tf-nightly (2.5.0)
pip3 install tf-nightly
并使用了这段代码(感谢 Alex K.):
new_model= tf.keras.models.load_model(filepath=path)
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = []
converter.allow_custom_ops=False
converter.experimental_new_converter = True
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
就是这样。
检查您在训练时使用的 Tensorflow 版本,在 android build.gridle(app) 中使用相同的版本。
我在训练时使用 tensorflow 2.4.0(最新版本),所以我将 (implementation 'org.tensorflow:tensorflow-lite:2.4.0') 放在 android build.gridle(app)
我得到了一个看起来像这样的模型并对其进行了训练:
keras.layers.Conv2D(128, (3,3), activation='relu', input_shape=(150,150,3)),
keras.layers.MaxPooling2D(2,2),
keras.layers.Dropout(0.5),
keras.layers.Conv2D(256, (3,3), activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.Conv2D(512, (3,3), activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.Flatten(),
keras.layers.Dropout(0.3),
keras.layers.Dense(280, activation='relu'),
keras.layers.Dense(4, activation='softmax')
])
我使用以下代码将其转换为 .tflite:
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file("model.h5")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.post_training_quantize=True
converter.allow_custom_ops=True
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
然后我希望它与本地 Firebase 一起使用:
val bitmap = Bitmap.createScaledBitmap(image, 150, 150, true)
val batchNum = 0
val input = Array(1) { Array(150) { Array(150) { FloatArray(3) } } }
for (x in 0..149) {
for (y in 0..149) {
val pixel = bitmap.getPixel(x, y)
input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 255.0f
input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 255.0f
input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 255.0f
}
}
val localModel = FirebaseCustomLocalModel.Builder()
.setAssetFilePath("model.tflite")
.build()
val interpreter = FirebaseModelInterpreter.getInstance(FirebaseModelInterpreterOptions.Builder(localModel).build())
val inputOutputOptions = FirebaseModelInputOutputOptions.Builder()
.setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 150, 150, 3))
.setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 4))
.build()
val inputs = FirebaseModelInputs.Builder()
.add(input)
.build()
interpreter?.run(inputs, inputOutputOptions)
?.addOnSuccessListener { result ->
val output = result.getOutput<Array<FloatArray>>(0)
val probabilities = output[0]
但是它抛出这个错误:
Internal error: Cannot create interpreter: Didn't find op for builtin opcode 'CONV_2D' version '2'
有人知道我做错了什么吗?我正在使用 tensorflow-gpu 和 tensorflow-estimator 2.3.0
TFLite 运算符有不同 versions。看起来您已经使用较新版本的 Conv2D 转换了模型,而您当前的解释器不支持它。
我在 Android 上尝试 converter.optimizations = [tf.lite.Optimize.DEFAULT]
时遇到了这个问题。所以我建议你在开始时放弃优化和自定义操作:
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file("model.h5")
converter.optimizations = []
converter.post_training_quantize=True
converter.allow_custom_ops=False
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
编辑:
还要确保在转换模型时和在应用程序中使用相同版本的 Tensorflow。老版本解释器不支持新op版本导致版本不匹配
编辑 2(可能更有用):
尝试使用旧版本的 Tensorflow 转换您的模型,假设 2.1 使用命令:
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file("model.h5")
converter.optimizations = []
converter.allow_custom_ops=False
converter.experimental_new_converter = True
tflite_model = converter.convert()
我通过以下更改修复了它:
我这样保存我的模型 (tf-gpu 2.2.0) 或通过我的回调 (.pb):
tf.saved_model.save(trainedModel,path)
在build.gradle中我添加了:
implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly'
implementation'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly'
我通过 运行:
将我的 tensorflow 版本(仅用于转换器)更新为 tf-nightly (2.5.0)pip3 install tf-nightly
并使用了这段代码(感谢 Alex K.):
new_model= tf.keras.models.load_model(filepath=path)
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = []
converter.allow_custom_ops=False
converter.experimental_new_converter = True
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
就是这样。
检查您在训练时使用的 Tensorflow 版本,在 android build.gridle(app) 中使用相同的版本。 我在训练时使用 tensorflow 2.4.0(最新版本),所以我将 (implementation 'org.tensorflow:tensorflow-lite:2.4.0') 放在 android build.gridle(app)