Локальная модель Firebase выдает «Не найден op для встроенного кода операции ‘CONV_2D’ версии ‘2’»

#android #firebase #tensorflow #tensorflow-lite

#Android #firebase #тензорный поток #tensorflow-lite

Вопрос:

Я взял модель, которая выглядит вот так, и обучил ее:

       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

Ответ №1:

Проверьте версию Tensorflow, которую вы используете во время обучения, используйте ту же версию в Android build.gridle (приложение). Я использую tensorflow 2.4.0 (последнюю версию) во время обучения, поэтому я поместил (реализацию ‘org.tensorflow:tensorflow-lite: 2.4.0’) в свой Android build.gridle (приложение)

Ответ №2:

Операторы TFLite имеют разные версии. Похоже, что вы преобразовали модель в более новую версию 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 с помощью command:

 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()
  

Комментарии:

1. это не исправлено :/

2. Sry все еще не исправлено: / Я исправил проблему с этой моделью (понятия не имею, как) и хочу развернуть новую (пользовательскую мобильную сеть)…

3. Вы помогли мне найти решение. Спасибо, брат

Ответ №3:

Я исправил это следующими изменениями:

Я сохранил свою модель следующим образом (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
  

И использовал этот код (благодаря Алексу К.):

 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)
  

Вот и все.