Tensorflow: [Pregunta y error] ¿Existe un modelo de detección como SSD-Mobile-net en tensorflow-lite?

Creado en 26 dic. 2017  ·  141Comentarios  ·  Fuente: tensorflow/tensorflow

HOLA.

Desarrollo de una aplicación para Android usando tensorflow-lite.

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/g3doc/models.md
Modelo de detección no encontrado.

Además, trato de convertir SSD-Inceptionv2 usando tensorflow-lite-API. Pero parece que hay un problema.

Mando


bazel run --config=opt --copt=-msse4.1 --copt=-msse4.2 \
  //tensorflow/contrib/lite/toco:toco -- \
  --input_file=/home/danshin/tensorflow_lite/lite_model/fire_incpetion_v2.pb \
  --output_file=/home/danshin/tensorflow_lite/lite_model/fire_inception_v2.lite \
  --input_format=TENSORFLOW_GRAPHDEF \
  --output_format=TFLITE \
  --inference_type=FLOAT \
  --input_shape=1,300,300,3 \
  --input_array=image_tensor \
  --output_array={detection_boxes,detection_scores,detection_classes,num_detections}

Código de error


2017-12-26 14:59:25.159220: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before general graph transformations: 2029 operators, 3459 arrays (0 quantized)
2017-12-26 14:59:25.251633: F tensorflow/contrib/lite/toco/graph_transformations/resolve_tensorflow_switch.cc:95] Check failed: other_op->type == OperatorType::kTensorFlowMerge 

Se crea el archivo fire_inception_v2, pero su tamaño es cero bytes.
¿Qué es un problema?

además,
por favor, hágame saber cuál es la mejor manera de implementar un modelo personalizado para la detección de objetos.

¡Alguien que me ayude por favor!.

gracias.

lite feature

Comentario más útil

¡Ya está disponible en tensorflow/contrib/lite/examples/android ! Este es un puerto más completo de la demostración original de Android TF (solo le falta el ejemplo Stylize), y reemplazará a la otra demostración en tensorflow/contrib/lite/java/demo en el futuro.

Puede encontrar un búfer plano de TF Lite convertido en mobilenet_ssd_tflite_v1.zip , y puede encontrar la implementación de inferencia de Java en TFLiteObjectDetectionAPIModel.java . Tenga en cuenta que esto difiere de la implementación original de TF en que las cajas deben decodificarse manualmente en Java, y un archivo txt anterior de la caja debe empaquetarse en los activos de las aplicaciones (creo que el que se incluye en el modelo zip anterior debería ser válido para la mayoría gráficos).

Durante la conversión TOCO, se utiliza un nodo de entrada diferente (Preprocesador/sub), así como diferentes nodos de salida (concat, concat_1). Esto omite algunas partes que son problemáticas para tflite, hasta que se reestructura el gráfico o TF Lite alcanza la paridad de TF.

Estos son los pasos rápidos para convertir un modelo SSD MobileNet al formato tflite y crear la demostración para usarlo:

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

Todos 141 comentarios

@aselle , ¿puede echar un vistazo a este problema? Gracias.

Actualmente estamos trabajando para convertir mobilenet SSD (y luego inception ssd después de eso), pero contiene operaciones que no son completamente compatibles. Actualizaré este problema una vez que lo hayamos hecho.

Genial, hice una pregunta similar aquí: https://github.com/tensorflow/tensorflow/issues/14731

¿Cuánto tiempo calculan hasta que agreguen soporte de ssd-mobilenet?

Gracias,
Martín Peniak

Un miembro de la organización TensorFlow respondió después de que se aplicó la etiqueta stat:awaiting tensorflower.

?

Asignatario molesto: han pasado 14 días sin actividad y este problema tiene un asignado. Actualice la etiqueta y/o el estado en consecuencia.

¿Alguna actualización?
También estoy enfrentando un problema similar. Gracias por adelantado.

@yucheeling

¿Podría sugerir algún conjunto de datos como " ssd_mobilenet_v1_coco_2017_11_17.tar " que se pueda usar en una tienda minorista para identificar diferentes prendas como camisetas, jeans, etc.

@ rana3579 , haga esa pregunta en stackoverflow. Una actualización rápida en mobilenet ssd. Esto está progresando y esperamos tener un ejemplo pronto.

@ rana3579 mira mi video, lo ejecuté en movidius, nvidia gpus y procesadores arm. No puedo compartir el conjunto de datos, pero si eres parte de una empresa, podríamos hablar sobre una posible colaboración: https://www.youtube.com/watch?v=3MinI9cCJrc

@aselle gracias por la actualización! ¿Dónde buscar las notificaciones sobre esto? Me gustaría ser notificado tan pronto como esté disponible si eso es posible. ¡Gracias, aprecio tu arduo trabajo en esto!

@andrewharp , está trabajando en esto y actualizará la aplicación Java TF Mobile para usar tflite. Así que esté atento a esos cambios en el repositorio. Dejaré este tema abierto por ahora.

Esto es funcional internamente; debería tener algo en la próxima semana o dos.

@andrewharp eso es genial!! ¿Eso también se aplica al ejemplo de la cámara iOS?
Además, ¿cuál es el tamaño de los pesos y el rendimiento?
La red móvil de clasificación TFLite es pequeña y el rendimiento en iOS es suave como la mantequilla, así que estoy muy emocionado por TFLite.

Algunos otros ya convirtieron el SSD Mobilenet pb existente en un modelo coreml y escribieron las capas de salida faltantes en Swift:
https://github.com/vonholst/SSDMobileNet_CoreML

Pero eso es solo como 8-12 fps en un iPhone 7.

Hola,
¿Algún avance en esto?

yo tambien tengo curiosidad :)

Tengo un compromiso de transferir la demostración de Android TF a tflite actualmente en revisión, debería aparecer en github esta semana con suerte.

@madhavajay Es solo para Android, pero debería poder adaptarlo para iOS. Lo único es que parte del preprocesamiento (redimensionamiento/normalización de la imagen) y el posprocesamiento (supresión no máxima y ajuste por cajas previas) se realiza en Java, ya que tflite no es totalmente compatible con todos los operadores utilizados por MobileNet SSD. .

@andrewharp Eso es increíble. ¿Puede explicar brevemente por qué esas operaciones no están disponibles actualmente en TF lite? Parece el mismo caso para la herramienta de conversión tfcoreml en SSD normal. No me quejo, solo pregunto por interés técnico, ¿hacen algo que sea particularmente difícil de implementar en la pila móvil o simplemente es de baja prioridad?

¡Espero ver tu esfuerzo épico en el código de Android! Muchas gracias. ¡Sé que no soy el único que espera esto!

@andrewharp y @aselle ¿ Alguna actualización sobre cómo obtener una demostración para usar el ejemplo de localización de objetos basado en SSD para TFLite?

¡Ya está disponible en tensorflow/contrib/lite/examples/android ! Este es un puerto más completo de la demostración original de Android TF (solo le falta el ejemplo Stylize), y reemplazará a la otra demostración en tensorflow/contrib/lite/java/demo en el futuro.

Puede encontrar un búfer plano de TF Lite convertido en mobilenet_ssd_tflite_v1.zip , y puede encontrar la implementación de inferencia de Java en TFLiteObjectDetectionAPIModel.java . Tenga en cuenta que esto difiere de la implementación original de TF en que las cajas deben decodificarse manualmente en Java, y un archivo txt anterior de la caja debe empaquetarse en los activos de las aplicaciones (creo que el que se incluye en el modelo zip anterior debería ser válido para la mayoría gráficos).

Durante la conversión TOCO, se utiliza un nodo de entrada diferente (Preprocesador/sub), así como diferentes nodos de salida (concat, concat_1). Esto omite algunas partes que son problemáticas para tflite, hasta que se reestructura el gráfico o TF Lite alcanza la paridad de TF.

Estos son los pasos rápidos para convertir un modelo SSD MobileNet al formato tflite y crear la demostración para usarlo:

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

@andrewharp Felices Pascuas 🥚🍫 ¡LEYENDA! :) Voy a ver si puedo hacer que esto funcione.

Hola, ¿hay alguna versión cuantizada?

Lo hice funcionar con las instrucciones anteriores, pero necesitaba:

  • Android SDK 15 debido a mi versión bazel
  • Tampoco puedo abrir el proyecto en Android Studio

@andrewharp , ¿es una nueva cosa de Android Studio a la que se dirigen que usa bazel para construir proyectos en lugar de Gradle, o simplemente faltan algunas configuraciones del proyecto por ahora debido al corto período de tiempo para que funcione?

Feliz de proporcionar un PR si entiendo cuál es el problema.

También en cuanto al rendimiento, parece ser lento en mi LG G6 con Android 7.
¿Es porque la API de NN solo está en Android 8?

¿Alguien pudo probarlo en Android 8?

Ya veo, pensé que las instrucciones eran solo para la conversión. Dejé de leer después de la primera parte de la oración diciendo que así es como conviertes el modelo lol.

Sí, tengo pixel xl, supongo que su teléfono no tiene hardware que pueda acelerar la inferencia o ese hardware no es compatible con el software.

Probaré y te aviso. Estaba asumiendo que podría construir eso con android studio doh...

Enviado desde mi iPhone

El 31 de marzo de 2018, a las 20:05, Madhava Jay [email protected] escribió:

Lo hice funcionar con las instrucciones anteriores, pero necesitaba:

Android SDK 15 debido a mi versión bazel
Tampoco puedo abrir el proyecto en Android Studio
@andrewharp , ¿es una nueva cosa de Android Studio a la que se dirigen que usa bazel para construir proyectos en lugar de Gradle, o simplemente faltan algunas configuraciones del proyecto por ahora debido al corto período de tiempo para que funcione?

Feliz de proporcionar un PR si entiendo cuál es el problema.

También en cuanto al rendimiento, parece ser lento en mi LG G6 con Android 7.
¿Es porque la API de NN solo está en Android 8?

¿Alguien pudo probarlo en Android 8?


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.

Sí, hice lo mismo y fui directamente al estudio de código y Android. Luego, después de que hiciera ping esta mañana, estaba a punto de responder que tenía el mismo problema y luego RTFM'ed nuevamente. 🤣

Por lo que puedo decir, el LG G6 debería ser compatible con la API NN, ya que tiene el SoC Qualcomm 821 igual que el Pixel 1. Pero, desafortunadamente, LG no ha lanzado Android 8 u 8.1 y las últimas compilaciones de LineageOS parecen un poco incompletas. así que voy a esperar a menos que SÉ que funciona mejor en Android 8.1. Si puedes encenderlo en el Pixel, ¡sería increíble! 👍

Me las arreglé para probar esto, pero la demostración funciona muy lento... incluso más lento que la versión original.
Estoy usando Pixel XL (primera versión) y compilé previamente la demostración anterior para el arco de 64 bits, lo que hizo que se ejecutara casi el doble de rápido incluso sin tfLite... el tiempo de inferencia en este caso es de alrededor de 450 ms. Cuando pruebo esta demostración, se ejecuta alrededor de 850 ms y, a veces, incluso más de un segundo. ¿Hice algo incorrectamente o simplemente estaba siendo demasiado optimista al esperar una aceleración decente? Gracias.

@mpeniak Obtuve las mismas velocidades en el LG G6, con depuración activada o desactivada (al principio pensé que era depuración). Sospecho que NNAPI no se está utilizando. ¿Quizás necesitamos hacer algo especial con la compilación nnapi_lib?
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/BUILD

La dependencia aparece en la lista, pero ¿es posible que deba construirse para una arquitectura específica?
Quizás algo en ./configure
(por cierto, habilité XLA en mi ./configure en caso de que estuviera relacionado pero no cambió la velocidad)

@andrewharp
Quiero usar NNAPI, pero no sé cómo usarlo.
Según el documento, la API de Neural Networks está disponible en Android 8.1 >
Si es 8.1 o superior, ¿se aplica básicamente? o ¿Necesito trabajo adicional de NDK? Enlace del documento
Que tengas un buen día XD

@andrewharp , traté de habilitar NNAPI para tflite_demo y ejecutar el apk, sin embargo, encontré que el apk se estrelló
cuando llama a AddOpsAndParams, la operación tflite::BuiltinOperator_SQUEEZE no es compatible y
nn_op_type se establece en -1, lo que provocará una llamada FATAL y exit(-1) . creo que ese es el
causa principal. ¿Podría decirme si será compatible con una versión futura? ¿Hay alguna otra forma de trabajar?
alrededor para probar la ruta NNAPI? Gracias.

@andrehentz
bazel run -c opt tensorflow/python/tools/optimize_for_inference --\
--input=$DETECT_PB --output=$STRIPPED_PB --frozen_graph=Verdadero \
--input_names=Preprocesador/sub --output_names=concat,concat_1 \
--alsologtostderr

¿Por qué no es input_names image_tensor?
Intenté de esta manera y encontré un error.

@nanamare
Debería usar frozen_inference_graph_stripped.pb en lugar de frozen_inference_graph.pb.
intente "bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=frozen_inference_graph_stripped.pb"
y se puede ver el siguiente resultado:
Se encontraron 1 entradas posibles: (nombre=Preprocesador/sub, tipo=flotante(1), forma=Ninguna)
No se detectaron variables.
Se encontraron 2 salidas posibles: (name=concat, op=ConcatV2) (name=concat_1, op=ConcatV2)

El nombre de entrada es Preprocesador/sub y el nombre de salida es concat.

@nanamare
El último código de tensorflow lite incluye una interfaz java para habilitar NNAPI.

El intérprete de clase tiene una función llamada: setUseNNAPI(true);
Puede llamar directamente a dicha interfaz.

@zhangbo0325
Ya intenté llamar a setUserNNAPI(true); pero no hubo ningún efecto.
Fue una inferencia casi similar sin usar NNAPI.
Especificación de Android: versión 8.1.

@nanamare , ¿usted está ejecutando ssd-mobilenet? Para dicha red, existe una operación SQUEEZE que no es compatible con Android NNAPI. Hice la pregunta de arriba. Para mobilenet-v1, está bien.

<strong i="5">@andrewharp</strong>  Hi, andrewharp. i just followed your quick steps for converting an SSD MobileNet model to tflite format, and then i tried to  build the demo to use it. But something accurred in apk.
for the tflite from mobilenet_ssd_tflite_v1.zip, everything is ok! i can use mobile to detecter things.
And then i tried to use pet data to fine tune the model from the checkpoint in mobilenet_ssd_tflite_v1.zip. this process is also ok. i check the generated frozen_inference_graph.pb with the object_detection_tutorial.ipynb(https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb). the result shown this pb can used to object detection. And then i followed the script to convert frozen pb to tflite. Then build demo with tflite, unfortunately something wrong ocurred. Then log is written below. 
It seems the Shape of output target [1, 1917, 4] does not match with the shape of the Tensor [1, 1917, 1, 4]. Because i am new to use object detection api, i donot know how to deal with the problem. 
Hope you can point out some solutions, Thx!

Registro móvil aquí:
04-04 19:46:36.099 28864-28882/org.tensorflow.lite.demo E/AndroidRuntime: EXCEPCIÓN FATAL: proceso de inferencia: org.tensorflow.lite.demo, PID: 28864 java.lang.IllegalArgumentException: Forma del destino de salida [1, 1917, 4] no coincide con la forma del Tensor [1, 1917, 1, 4]. en org.tensorflow.lite.Tensor.copyTo(Tensor.java:44) en org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:139) en org.tensorflow.demo.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java:226 ) en org.tensorflow.demo.DetectorActivity$3.run(DetectorActivity.java:248) en android.os.Handler.handleCallback(Handler.java:761) en android.os.Handler.dispatchMessage(Handler.java:98) en android.os.Looper.loop(Looper.java:156) en android.os.HandlerThread.run(HandlerThread.java:61)

¡Asombroso! Tratando de hacer que esto funcione en iOS. ¿Cómo analizo la salida de Tensor?

interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);

La interfaz DetectorActivity está atascada en mi proyecto, existe, ¿cómo puedo solucionarlo?

@ zhangbo0325 Gracias por los detalles. Dado que la compresión no es compatible con la NNAPI, ¿eso significa que la NNAPI no se usa en absoluto y la inferencia seguirá siendo tan lenta como es? Como mencioné en el comentario anterior, obtengo un rendimiento realmente bajo en Pixel XL. Esperaría tiempos de inferencia en algún lugar alrededor de 80-120ms. ¡Gracias!

@mpeniak , le hice la misma pregunta a andrewharp. Acabo de ejecutar ssd-mobilenet con la ayuda de la implementación de la CPU tensorflow-lite y también obtuve un rendimiento deficiente.

La charla de TensorFlow Lite en Dev Summit 2018 mostró un rendimiento tres veces mayor en MobileNet:
https://youtu.be/FAMfy7izB6A?t=530

¿Tal vez eso no sea para SSD?
¿Posiblemente requiere cuantificación de peso primero?

He probado mobilnet y es mucho más rápido, aunque esto no se aplica a mobilnet-ssd...

Panda Triste ☹️🐼
@andrewharp ¿ Alguna idea de cuándo estará disponible una implementación SSD de alto rendimiento? ¿Es una cuestión de cuantificación de peso?

También obtuve el bajo rendimiento de ssd-mobilenet en TensorFlowLite :(
Pero, tengo otra pregunta. ¿Por qué la puntuación del resultado supera 1? ¿No es la probabilidad?

@ a1103304122 según tengo entendido, la puntuación es la salida del nodo "concat", antes de softmax, por lo que no es la probabilidad.

Durante la conversión TOCO, se utiliza un nodo de entrada diferente (Preprocesador/sub), así como diferentes nodos de salida (concat, concat_1). Esto omite algunas partes que son problemáticas para tflite, hasta que se reestructura el gráfico o TF Lite alcanza la paridad de TF.

¿Alguien tiene idea de por qué TFlite es más lento que TFmobile en este modelo?

@andrewharp , ¿es posible comentar sobre el rendimiento de la SSD TF Lite? ¿También es posible / viene la cuantización? Sé que están trabajando arduamente para que todo esto suceda, pero sería bueno saber si esto es solo un contratiempo a corto plazo o si hay una solución que podamos aplicar. 😄

@andrewharp Gracias por tu excelente publicación. Sin embargo, tengo una pregunta para tus pasos.

Elimine los nodos problemáticos incluso antes de permitir que TOCO vea el graphdef

bazel run -c opt tensorflow/python/tools/optimize_for_inference --\
--input=$DETECT_PB --output=$STRIPPED_PB --frozen_graph=Verdadero \
--input_names=Preprocesador/sub --output_names=concat,concat_1 \
--alsologtostderr

Si no me malinterpreto, aquí quieres producir STRIPPED_PB, ¿verdad? Si es así, actualmente, la entrada de nuestro archivo de entrada debería ser image_tensor. Entonces, no entiendo muy bien por qué usamos Preprocessor/sub. ¿Podrías explicar más detalladamente?

En segundo lugar, aquí usamos optimize_for_inference, ¿podemos usar la herramienta transform_graph? porque la nueva documentación de tensorflow recomienda transform_graph en lugar de Optimize_for_inference.

@mpeniak ¿cómo lo haces? Por favor, di algunos detalles.

org.tensorflow.lite.demo E/AndroidRuntime: EXCEPCIÓN FATAL: proceso de inferencia: org.tensorflow.lite.demo, PID: 28864 java.lang.IllegalArgumentException: la forma del destino de salida [1, 1917, 4] no coincide con el forma del Tensor [1, 1917, 1, 4].

@Haijunlv ¿Has resuelto el problema? ¿Puedes compartir la solución?

Al importar la nueva demostración de Android de TF Lite, obtengo Error:Plugin with id 'com.android.application' not found. en OS X.

¡El mismo problema que @ csmith105 ! Logré compilar e instalar la demostración con bazel, pero no puedo compilar ni ejecutar el proyecto en Android Studio... ¿alguna solución para este problema?

@ Eddy-zheng Si vio el nodo "concat" en el gráfico congelado, encontrará que la operación de compresión se ejecuta después de la operación concat. Creo que esa es la razón por la cual la forma es incompatible. No probé la velocidad de la operación de compresión. Pero creo que hay dos maneras de resolver el problema.

  1. cambiar el orden de apretar y concatenar op. En ssd_meta_arch.py, cambie ligeramente "box_encodings = tf.squeeze(tf.concat(prediction_dict['box_encodings'], axis=1), axis=2)"
  2. elimine directamente la forma 1 en el eje 2. En box_predictor.py, cambie ligeramente " box_encodings =tf.reshape(
    box_encodings, tf.stack([combined_feature_map_shape[0],
    combine_feature_map_shape[1] *
    combine_feature_map_shape[2] *
    num_predicciones_por_ubicación,
    1, self._box_code_size]))"

En realidad, no entiendo la razón por la cual remodelar el tensor con una forma extra de "1". Puede ser que sea redundante
Op.
Probé la forma 1 y tuve éxito al ejecutar el modelo en el móvil. Pero todavía un poco lento. luego intentaré la forma 2 para ver si puede obtener una mejor velocidad

@Haijunlv ¿Qué tan buenas son las detecciones? El modelo lite de la demostración de @andrewharp simplemente elimina todos los nodos de preproceso y posproceso (miles de ellos) del gráfico y los reemplaza con varias líneas de código. No estoy seguro de cómo funcionará..

Creo que hay una solución para el problema de Android Studio y Gradle. (corríjame si me equivoco o si hay una solución mejor):

  • No es el mejor enfoque, pero hay un complemento de Bazel que podemos instalar dentro de Android Studio para "reemplazar" a Gradle y podemos construir y ejecutar nuestro proyecto usando Bazel a través de AS.

  • Leí varios artículos sobre Bazel y me encontré con esta pregunta en Quora... y de acuerdo con la respuesta, tensorflow continuará usando Bazel ya que explota mejor el marco y da mejores resultados... así que creo que como desarrolladores en este caso particular deberíamos adaptarnos y dejar atrás a Gradle hasta que tensorflow lo admita por completo.

@davidfant
¿Logró llegar a las múltiples salidas en TensorFlow Lite C++?

interpreter->Invoke();
???? output = interpreter->typed_output_tensor<?????>(0);

Estoy progresando, pero aún no sé cómo obtener los resultados en C++. ¿Hay alguna documentación sobre esto? Esto es lo que tengo en este momento. ¿Cómo tengo que acceder a la matriz de datos para obtener las puntuaciones?

(fill inputs)
.......
intepreter->Invoke();
const std::vector<int>& results = interpreter->outputs();
TfLiteTensor* outputLocations = interpreter->tensor(results[0]);
TfLiteTensor* outputClasses   = interpreter->tensor(results[1]);
float *data = tflite::GetTensorData<float>(outputClasses);
for(int i=0;i<NUM_RESULTS;i++)
{
   for(int j=1;j<NUM_CLASSES;j++)
   {
      float score = expit(data[i*NUM_CLASSES+j]); // ¿?
    }
}

@JaviBonilla Hice algo similar y descubrí que no funciona. Usando el corte de la aplicación de demostración de Android, simplemente genera demasiado ruido. Si usa tensorboard para leer el gráfico, encontrará que el modelo lite elimina miles de nodos de posprocesamiento. No creo que la forma actual funcione. Espero que tensorflow lite admita esos nodos de posprocesamiento en el futuro, en lugar de pedirle a la gente que haga esos trucos que no funcionan.

Gracias @YijinLiu. Vi su repositorio tf-cpu, echaré un vistazo a su código para comprobar que mi implementación es correcta y ver los resultados aunque no sean buenos.

@JaviBonilla , ¡avísanos cuando hayas descubierto cómo ejecutar con C++! 🙌

Hola @davidfant ,

Todavía tengo que probarlo, ¡pero @YijinLiu ya lo descubrió!.

Eche un vistazo a su repositorio (https://github.com/YijinLiu/tf-cpu). En particular, puede encontrar cómo obtener los resultados en el archivo tf-cpu/benchmark/obj_detect_lite.cc , la función AnnotateMat() , que se ejecuta después de Interpreter->Invoke() .

@JaviBonilla No terminé obj_detect_lite.cc, especialmente, para usar priors para decodificar las cajas de detección.
Lo que encontré es que las puntuaciones no tienen sentido en todos los escenarios. En algunos casos, genera demasiado ruido. Para otros casos, puede perder algunas buenas detecciones. Miré esos nodos para convertir estos puntajes intermedios en los puntajes de posibilidad finales. Hay miles de nodos...

@YijinLiu gracias por aclarar esto. Entonces, creo que es mejor esperar hasta que se incluyan más mejoras en TensorFlow Lite para la detección de objetos. De todos modos, intentaré decodificar los cuadros de detección en C++ si tengo tiempo.

Hola @andrewharp ,

Gracias por su esfuerzo por hacer el nuevo proyecto de demostración de Android, pero ¿podría escribir un archivo readme.md o algún documento de descripción en tensorflow/contrib/lite/examples/android para que todos podamos entender fácilmente el proceso para hacer tensorflow lite? ¡gracias~!

Hola, ejecuté la demostración de ssd_mobilenet_v1_coco_2017_11_17 con éxito, luego obtuve un modelo ajustado. Cuando ejecuté el proceso de @andrehentz en él, ocurrió un problema:
bazel run tensorflow/contrib/lite/toco:toco -- --input_file=$STRIPPED_PB --output_file=$DETECT_FB --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub --output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

Antes de eliminar operaciones no utilizadas: 586 operadores, 871 matrices (0 cuantificadas)
2018-06-12 15:29:54.273221: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Antes de las transformaciones gráficas generales: 586 operadores, 871 matrices (0 cuantificadas)
2018-06-12 15:29:54.300213: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Después de que las transformaciones de gráficos generales pasen 1: 409 operadores, 688 matrices (0 cuantificadas)
2018-06-12 15:29:54.309735: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Antes de las transformaciones gráficas de descuantificación: 409 operadores, 688 matrices (0 cuantificadas)
2018-06-12 15:29:54.317395: I tensorflow/contrib/lite/toco/allocate_transient_arrays.cc:329] Tamaño total asignado de matriz transitoria: 2880256 bytes, valor óptimo teórico: 2880128 bytes.
2018-06-12 15:29:54.319173: F tensorflow/contrib/lite/toco/tflite/export.cc:330] Algunos de los operadores del modelo no son compatibles con el tiempo de ejecución estándar de TensorFlow Lite. Si tiene una implementación personalizada para ellos, puede deshabilitar este error con --allow_custom_ops, o configurando allow_custom_ops=True al llamar a tf.contrib.lite.toco_convert(). Aquí hay una lista de operadores para los que necesitará implementaciones personalizadas: RSQRT, SquaredDifference, Stack, TensorFlowShape.

Aquí está mi modelo https://drive.google.com/open?id=1IxRSU4VSmVmhUtUpSQew_5anEfxTg3Ca

¿Alguien puede ayudarme?
@andrehentz

@JaviBonilla y @YijinLiu Tengo una implementación de Python que probé con los modelos SSD MobileNet V{1,2} y SSDLIte MobileNet V2 de Google. Ver documentación simple aquí .

@freedomtan , ¿qué versión de tf usas? tf 1.8?

Rama maestra de @hengshanji después del enlace Python del intérprete tflite (29c129c6). No creo que 1.8 tenga el enlace.

@freedomtan tf1.8 tiene un enlace de intérprete de Python, pero encuentro ese tipo de problema "error de nnapi: no se puede abrir la biblioteca libneuralnetworks.so". ¿dónde conseguir este .so o cómo generarlo? Gracias.

Ignóralo :) Es para Android NNAPI.

@freedomtan ¿Probó el ejemplo en el dispositivo o en la computadora? Cuando lo pruebo en la PC, uso android-28/x86 libneuralnetworks. Entonces, muestra el error "Abortando desde que tflite devolvió el error".

Como dije, ignore ese problema de NNAPI. No se espera que tenga un libneuralnetwork.so funcionamiento. Probé mis scripts tanto en un x86 con Ubuntu como en una placa ARMv8 con Debian.

@freedomtan , gracias por compartir el código y la documentación.

Basado en el repositorio (https://github.com/YijinLiu/tf-cpu). Actualicé tf-cpu/benchmark/obj_detect_lite.cc para obtener los resultados. En la función AnnotateMat (), agregue el código decodeCenterSizeBoxes para manejar las ubicaciones de salida, luego haga nms para estos resultados.
Al mismo tiempo, al usar https://github.com/tensorflow/tensorflow/issues/14688 para generar libtensorflow-lite.a, puede ejecutarse tanto en un x86 con Ubuntu como en un dispositivo Android con modelo tflite en ssdlite_mobilenet_v2_coco_2018_05_09. tar.gz.
Gracias a todos.

@WeiboXu ¿Puede compartir el código y el modelo aquí?

@freedomtan En su código de implementación de python, hay un archivo "/tmp/box_priors.txt", ¿sabe cómo generar este archivo? ¿O cómo se calcularon los datos de este archivo? No hay ningún problema para hacer inferencias para la imagen con un tamaño de 300X300, pero la precisión de la inferencia se reducirá cuando se haga una inferencia para la imagen con un tamaño de 224X224.

@freedomtan , @andrewharp , el modelo anterior siguiendo estas instrucciones no puede funcionar en la última demostración de TFLite , ya sea cuantificado o flotante, porque el modelo tflite en la última demostración de TFLite requiere 4 salidas, pero el modelo anterior solo tiene 2 salidas ( concat, concat1).

Por favor ayuda, gracias!

Estas instrucciones están siendo actualizadas en este momento. Proporcionará un enlace para obtener instrucciones actualizadas en la próxima semana.

@frontword Lo que en /tmp/box_priors.txt son cajas para procesamiento posterior. Si usa el más nuevo mencionado por @WenguoLi , no lo necesita. Sin embargo, por lo que sé, esas operaciones de posprocesamiento se implementan como operaciones personalizadas de TF Lite. Lo que significa que no puede acelerarlos con aceleradores NNAPI sin más esfuerzos.

Para problemas de tamaño de imagen, sí, creo que alimentar imágenes de 224x224 a SSD300 (los modelos lanzados por Google fueron entrenados con imágenes de 300x300) y empeorar la precisión no es inesperado.

@WenguoLi Me parece que el modelo actualizado que mencionaste es bastante fácil de manejar. Ver mi fragmento de actualización . La siguiente figura es generada por

python  tensorflow/contrib/lite/examples/python/object_detection.py --image /tmp/image2.jpg  --show_image True

image

Para arreglar el puntaje del resultado de la inferencia que excede 1, es posible usar el método Java TrackedObject.getCurrentCorrelation() porque eso siempre parece devolver algo menos que 1 (aunque no estoy seguro de si es correcto o no). El ejemplo de TFLite Android usa Recognition.getConfidence() que siempre parece devolver algo mayor que 1

@mpeniak Ejecutó el modelo ssd mobilenet tflite en Movidius. Yo también estoy planeando hacer algo similar. ¿Puedes por favor orientar un poco sobre cómo lo hiciste?

@achowdhery Hola, vi algunas actualizaciones de las instrucciones de construcción para la última demostración de Android aquí (https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/examples/android/app), pero no indicó cómo podemos convertir el modelo pb congelado en un modelo tflite (el detect.tflite cuantificado que se usó en la última demostración). ¿Alguna otra instrucción sobre el flujo de conversión del modelo cuantificado? Además, creo que primero deberíamos ejecutar el entrenamiento cuantificado con operaciones de cuantificación falsas como se indica aquí (https://www.tensorflow.org/performance/quantization) y luego realizar la conversión del modelo, ¿correcto? Además, ¿es posible habilitar NNAPI en la última demostración de Android? Traté de usar tfLite.setUseNNAPI (true) en TFLiteObjectDetectionAPIModel.java pero se bloqueó en mi Pixel 2 con Android 8.1 (puede funcionar bien sin NNAPI). ¿Alguna sugerencia? ¡Gracias!

@tenoyart La respuesta corta para "¿es posible habilitar NNAPI en la última demostración de Android?" debería ser NO. La respuesta no tan corta es que es posible que si modifica el intérprete de TF Lite, haga algo como dividir el modelo o agregar las operaciones personalizadas correspondientes a NNAPI.

@achowdhery Vi un artículo tuyo en el blog de TensorFlow. ¿Son estas las instrucciones que mencionaste o vienen más?

Si. Estas son las instrucciones para entrenar y servir el modelo de detección de objetos en Android.

@freedomtan Gracias por compartir el guión.
En su última secuencia de comandos con posprocesamiento , ¿qué archivo de modelo está utilizando?
¿Especificaste el argumento deoptimize_for_inference.py como
--input_names="Preprocesador/sub"
--output_names="cajas_detección,puntuaciones_detección,núm_detecciones,clases_detección"

¿Ves alguna diferencia con/sin posprocesamiento?

¡Gracias!

¿Hay alguna forma de convertir modelos SqueezeNet con 4 salidas a tflite?

@chanchanzhang Siga las nuevas instrucciones hacia el final del tutorial en https://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus -b78971cf1193
Tenga en cuenta que esto utiliza un flujo de trabajo diferente al uso deoptimize_for_inference.py

@ashwaniag Si desea reemplazar Mobilenet con el clasificador SqueezeNet y mantener SSD después de eso para la detección, está bien para el flujo de trabajo actual.

@achowdhery Genial ver el modelo TF Lite en ssd mobilenet v1. ¿TF Lite es totalmente compatible con ssdlite mobilenet v2?

@tenoyart Sí. Cualquier SSD Mobilenet funcionará a través de esta canalización. No hemos lanzado los archivos tflite correspondientes en código abierto. Si encuentra problemas, presente un error.

@chanchanzhang como dijo @achowdhery , use object_detection/export_tflite_ssd_graph.py en lugar de optimized_for_inference.py . Y el archivo de modelo tflite que usé es del que usa el ejemplo de Android. Puedes conseguirlo aquí .

@achowdhery Creo que no hay nodos y tensores FakeQuant en los puntos de control de ssd_mobilenet_v1_quantized_coco y ssd_mobilenet_v1_0.75_ depth_quantized_coco . ¿Podrías revisarlos?

@freedomtan Veo los nodos weight_quant y act_quant en el gráfico exportado después de usar object_detection/export_tflite_ssd_graph.py.
Proporcione una captura de pantalla o instrucciones exactas de cómo verificó que no tiene nodos Fakequant.
También puedo convertir con éxito los puntos de control.

@achowdhery Gracias por comprobar. Cuando ejecuté export_tflite_ssd_graph.py en esos dos, no pude obtener modelos tflite, así que inspeccioné los puntos de control. lo que hice es algo asi

curl http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_03.tar.gz | tar xzvf -
cd ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_03
strings model.ckpt.index  |grep quant

No aparece nada.

@andrewharp Muchas gracias por su clase de inferencia cutosm TFLiteObjectDetectionAPIModel.java , lo probé con su ssd mobilenet v1 tflite mobilenet_ssd_tflite_v1.zip pero cuando la aplicación se inicia parece que hay un problema en la función de reconocimiento de imagen (mapa de bits de mapa de bits final) cuando llamo tfLite.runForMultipleInputsOutputs(inputArray, outputMap); lanza esta excepción

07-18 10:37:02.416 19957-19996/com.app.cerist.realtimeobjectdetectionapi E/AndroidRuntime: FATAL EXCEPTION: Camera
    Process: com.app.cerist.realtimeobjectdetectionapi, PID: 19957
    java.lang.IllegalArgumentException: Output error: Outputs do not match with model outputs.
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:170)
        at com.app.cerist.realtimeobjectdetectionapi.ImageClassifierTFLiteAPI.recognizeImage(ImageClassifierTFLiteAPI.java:207)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.classifyFrame(MainActivity.java:421)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.access$1000(MainActivity.java:48)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity$4.run(MainActivity.java:455)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.os.HandlerThread.run(HandlerThread.java:61)
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi V/Process: killProcess [19957] Callers=com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:99 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 <bottom of call stack> 
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi I/Process: Sending signal. PID: 19957 SIG: 9

el error decía que la longitud de la matriz de salidas es mayor que la longitud de la matriz de entradas
Aquí está la condición en Interpreter.java

public void runForMultipleInputsOutputs(Object[] inputs, <strong i="7">@NonNull</strong> Map<Integer, Object> outputs) {
        if (this.wrapper == null) {
            throw new IllegalStateException("Internal error: The Interpreter has already been closed.");
        } else {
            Tensor[] tensors = this.wrapper.run(inputs);
            if (outputs != null && tensors != null && outputs.size() <= tensors.length) {
                int size = tensors.length;
                Iterator var5 = outputs.keySet().iterator();
            }
       }
}

y esta es mi matriz de entradas y salidas:

d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
d.imgData.order(ByteOrder.nativeOrder());
d.intValues = new int[d.inputSize * d.inputSize];
 imgData.rewind();
        for (int i = 0; i < inputSize; ++i) {
            for (int j = 0; j < inputSize; ++j) {
                int pixelValue = intValues[i * inputSize + j];
                if (isModelQuantized) {
                    // Quantized model
                    imgData.put((byte) ((pixelValue >> 16) & 0xFF));
                    imgData.put((byte) ((pixelValue >> 8) & 0xFF));
                    imgData.put((byte) (pixelValue & 0xFF));
                } else { // Float model
                    imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

La matriz de salidas:

// Copy the input data into TensorFlow.
        Trace.beginSection("feed");
        outputLocations = new float[1][NUM_DETECTIONS][4];
        outputClasses = new float[1][NUM_DETECTIONS];
        outputScores = new float[1][NUM_DETECTIONS];
        numDetections = new float[1];

        Object[] inputArray = {imgData};
        Map<Integer, Object> outputMap = new HashMap<>();
        outputMap.put(0, outputLocations);
        outputMap.put(1, outputScores);
        outputMap.put(2, numDetections);
        outputMap.put(3, outputClasses);
        Trace.endSection();

Y la inferencia:

// Run the inference call.
        Trace.beginSection("run");
        Log.d("TAG_INPUT",""+String.valueOf(inputArray.length));
        Log.d("TAG_OUTPUT",""+String.valueOf(outputMap.size()));

        tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
        Trace.endSection();

No entendí el significado de este error porque hice exactamente lo mismo que su clase TFLiteObjectDetectionAPIModel.java.
gracias por ayudar

@achowdhery Hola, siguiendo tu blog convertí el modelo de ssd_mobilenet_v1_coco_2017_11_17. Sin embargo, cuando usé mobilenet_ssd.tflite convertido en tflite_demo.apk, recibí el siguiente error:

    java.lang.IllegalArgumentException: Cannot copy between a TensorFlowLite tensor with shape [1, 1917, 4] and a Java object with shape [1, 10, 4].

¿Alguna idea de por qué lo tengo? Gracias.

Este es un desajuste de forma porque el tensor de salida esperado tiene un tamaño de 1,10,4, no 1,1917,4. Para el archivo del modelo anterior, deberá regresar a la versión de la aplicación de demostración de mayo. De lo contrario, utilice los últimos modelos lanzados para la conversión.

@achowdhery Convertí mi propio modelo a tflite y cuando lo ejecuto. La llamada interpreter->invoke() arroja una falla de segmentación. ¿Alguna idea de lo que podría estar mal?

@ashwaniag Realice los modelos descargados en https://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus-b78971cf1193
compilar para usted?
En caso afirmativo, proporcione las nuevas instrucciones que está utilizando ahora cuando recibe una falla de segmento.
Podría haber una discrepancia en el tipo/tamaño de entrada, etc.

@achowdhery Funcionó. Estaba dando los input_arrays incorrectos. ¡Gracias de todos modos!

ssd_mobilenet_v1_quantized_coco y ssd_mobilenet_v1_0.75_ depth_quantized_coco actualizados funcionan, si siguió el tutorial. Gracias @achowdhery.

Estaba viendo TFLiteObjectDetectionAPIModel.java en la aplicación de demostración de ejemplo. ¿Hay alguna razón por la que outputLocations , outputClasses , outputScores y numDetections se asignan en cada llamada recognizeImage aquí ? Parece que están destinados a ser preasignados.
Intenté ejecutar el código con preasignación y parece funcionar bien, pero solo quería asegurarme de que no haya nada oculto que pueda presentar problemas más adelante.

La preasignación es probablemente más eficiente. ¿Dónde está preasignando que puede prever problemas?

gracias por la respuesta @achowdhery. Dejo la preasignación en el método estático create tal como está. Mi única preocupación era que el código parece estar escrito para usar la preasignación (el método estático preasigna las matrices), pero por alguna razón las matrices se reasignan en cada llamada.

hola @achowdhery , probé la nueva demostración de la aplicación Android tflite. Funciona perfectamente para ssd_mobilenet_v1_coco, ssd_mobilenet_v1_0.75_ depth_coco, ssd_mobilenet_v1_quantized_coco .
Pero obtuve esta excepción para los otros modelos ssd-mobilenet:

07-25 07:41:25.292 31515-31532/org.tensorflow.lite.demo E/AndroidRuntime: FATAL EXCEPTION: inference
    Process: org.tensorflow.lite.demo, PID: 31515
    java.lang.ArrayIndexOutOfBoundsException: length=160; index=-2147483648
        at java.util.Vector.elementData(Vector.java:734)
        at java.util.Vector.get(Vector.java:750)
        at org.tensorflow.demo.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java:218)
        at org.tensorflow.demo.DetectorActivity$3.run(DetectorActivity.java:249)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)

El modelo tflite produjo un índice de clase incorrecto. La excepción hace que la aplicación se bloquee después de detectarla bien durante un par de segundos.
ssd_mobilenet_v1_ppn_coco produce un cuadro delimitador desordenado incorrecto, también etiqueta.

PPN es un modelo flotante: ¿está convirtiendo el modelo TFLITE usando comandos de conversión flotante?
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md
Luego, también debe cambiar lo siguiente en DetectorActivity.java:
booleano final estático privado TF_OD_API_IS_QUANTIZED = verdadero;

Conocía esa configuración. En realidad, cuando esa configuración es incorrecta, la aplicación no puede ejecutarse en absoluto.
¿Pudo ver la ArrayIndexOutOfBoundsException? También probé la ventana acoplable de tu tutorial, pero es lo mismo.

Bueno. presente un nuevo problema de GitHub con instrucciones de reproducción exactas. El modelo PPN es una nueva solicitud de función para la aplicación Java. Responderemos cuando podamos priorizarlo.

Gracias. La ArrayIndexOutOfBoundsException también ocurre con ssd_mobilenet_v1_0.75_ depth_quantized_coco, ssdlite_mobilenet_v2_coco. La diferencia con PPN es que genera resultados correctos antes de que la aplicación fallara por esa excepción.

@achowdhery ¿Hay alguna forma de entrenar el modelo de cuantización con 4 salidas para tflite usando legacy/train.py ya que el nuevo model_main.py tiene errores?
https://github.com/tensorflow/models/issues/4798

@ashwaniag Puede diferenciar los dos códigos y agregar la parte que agrega cuantificación: tenga en cuenta que la función graph_rewriter es donde se agregan las operaciones de cuantificación.

@achowdhery : https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md
¿Hay un ejemplo o código de muestra de cómo hacer lo mismo en iOS? Hasta ahora, lo más parecido que encontré ha sido este https://github.com/YijinLiu/tf-cpu/blob/master/benchmark/obj_detect_lite.cc que no siempre funciona.

la aplicación de demostración actual de iOS no funciona con ssd y modelo flotante.

@achowdhery Entrené mi modelo usando tensorflow v1.9. Convertido a tflite siguiendo los pasos del blog. No recibo ninguna detección. ¿Tienes alguna idea sobre esto?

@ashwaniag COCO o mascotas? Abra un nuevo error con las instrucciones de reproducción exactas. Otros usuarios de GitHub han confirmado que funciona con Tensorflow 1.10

@achowdhery Es mi propio conjunto de datos. Me entrené para la arquitectura mobilenetv2. Cuando ejecuto el modelo .pb (modelo tensorflow), obtengo
No encontrado: Tipo de operación no registrado 'NonMaxSuppressionV3' en ejecución binaria en VAL5-04. Asegúrese de que Op y Kernel estén registrados en el binario que se ejecuta en este proceso.

¿Crees que está relacionado?

@ashwaniag Abra un nuevo error y proporcione instrucciones reproducibles exactas

@ashwaniag verifique estos dos problemas, tuve un problema similar: # 10254 y # 19854

@achraf-boussaada ¡Gracias! Lo arreglé. Era un problema de discrepancia de versiones.
@achowdhery Ahora, el problema es que el modelo completo de tensorflow me da excelentes resultados, pero el modelo tflite da muy malos resultados.

@ashwaniag Por favor, defina resultados muy malos. ¿Tienes objetos pequeños? Adjunte un punto de control modelo, una configuración de canalización y un archivo de etiqueta, así como una imagen de muestra para ayudarnos a reproducir el problema. Gracias

@oopsodd hola, también obtengo un índice de clase incorrecto. se quejó "java.lang.ArrayIndexOutOfBoundsException: length=10; index=-739161663", ¿Me pueden ayudar?

Tenga en cuenta que he creado ejemplos de trabajo mínimos de TensorFlow Lite SSD (Detección de objetos) para iOS y Android; https://github.com/baxterai/tfliteSSDminimalWorkingExample. La versión de iOS se basa en obj_detect_lite.cc de YijinLiu (con la función nms de WeiboXu), y la versión de Android se basa en https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/examples/ android tflDetect. Elimina toda la sobrecarga como la cámara interna y aísla el código central necesario para detectar objetos y mostrar los cuadros de detección.

@baxterai gran trabajo! gracias, lo probare.

¡Gracias por su increíble trabajo a todos! Tengo otra pregunta con respecto a la operación de posprocesamiento recientemente agregada.

La salida del ssd_mobilenet_v1_quantized_coco preentrenado
actualmente está limitado a las 10 detecciones principales en el marco, aunque las configuraciones predeterminadas en models/research/object_detection/samples/configs/ like
ssd_mobilenet_v1_quantized_300x300_coco14_sync.config todos especifican un límite superior de detecciones totales.

post_processing { batch_non_max_suppression { score_threshold: 1e-8 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 100 } score_converter: SIGMOID }

¿Esto se resuelve volviendo a entrenar la red con esta configuración de tubería o es la dimensionalidad de
¿'TFLite_Detection_PostProcess' fijado a 10 por otras configuraciones?

@ Georg-W Deberá cambiar la detección máxima en export_tflite_ssd_graph.py también. Hay una opción de línea de comando.

@achowdhery, ¡gracias! Eso es lo que me perdí.

@andrewharp Muchas gracias por su clase de inferencia cutosm TFLiteObjectDetectionAPIModel.java , lo probé con su ssd mobilenet v1 tflite mobilenet_ssd_tflite_v1.zip pero cuando la aplicación se inicia parece que hay un problema en la función de reconocimiento de imagen (mapa de bits de mapa de bits final) cuando llamo tfLite.runForMultipleInputsOutputs(inputArray, outputMap); lanza esta excepción

07-18 10:37:02.416 19957-19996/com.app.cerist.realtimeobjectdetectionapi E/AndroidRuntime: FATAL EXCEPTION: Camera
    Process: com.app.cerist.realtimeobjectdetectionapi, PID: 19957
    java.lang.IllegalArgumentException: Output error: Outputs do not match with model outputs.
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:170)
        at com.app.cerist.realtimeobjectdetectionapi.ImageClassifierTFLiteAPI.recognizeImage(ImageClassifierTFLiteAPI.java:207)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.classifyFrame(MainActivity.java:421)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.access$1000(MainActivity.java:48)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity$4.run(MainActivity.java:455)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.os.HandlerThread.run(HandlerThread.java:61)
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi V/Process: killProcess [19957] Callers=com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:99 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 <bottom of call stack> 
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi I/Process: Sending signal. PID: 19957 SIG: 9

el error decía que la longitud de la matriz de salidas es mayor que la longitud de la matriz de entradas
Aquí está la condición en Interpreter.java

public void runForMultipleInputsOutputs(Object[] inputs, <strong i="14">@NonNull</strong> Map<Integer, Object> outputs) {
        if (this.wrapper == null) {
            throw new IllegalStateException("Internal error: The Interpreter has already been closed.");
        } else {
            Tensor[] tensors = this.wrapper.run(inputs);
            if (outputs != null && tensors != null && outputs.size() <= tensors.length) {
                int size = tensors.length;
                Iterator var5 = outputs.keySet().iterator();
            }
       }
}

y esta es mi matriz de entradas y salidas:

d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
d.imgData.order(ByteOrder.nativeOrder());
d.intValues = new int[d.inputSize * d.inputSize];

```
imgData.rebobinar();
for (int i = 0; i < tamaño de entrada; ++i) {
for (int j = 0; j < tamaño de entrada; ++j) {
int pixelValue = intValues[i * inputSize + j];
si (esModeloCuantizado) {
// modelo cuantificado
imgData.put((byte) ((pixelValue >> 16) & 0xFF));
imgData.put((byte) ((pixelValue >> 8) & 0xFF));
imgData.put((byte) (pixelValue & 0xFF));
} else { // Modelo flotante
imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

The outputs array :

// Copie los datos de entrada en TensorFlow.
Trace.beginSection("feed");
ubicaciones de salida = new float[1][NUM_DETECTIONS][4];
clases de salida = new float[1][NUM_DETECTIONS];
puntuaciones de salida = new float[1][NUM_DETECTIONS];
numDetections = new float[1];

    Object[] inputArray = {imgData};
    Map<Integer, Object> outputMap = new HashMap<>();
    outputMap.put(0, outputLocations);
    outputMap.put(1, outputScores);
    outputMap.put(2, numDetections);
    outputMap.put(3, outputClasses);
    Trace.endSection();
And the Inference :

// Ejecutar la llamada de inferencia.
Trace.beginSection("ejecutar");
Log.d("TAG_INPUT",""+String.valueOf(inputArray.length));
Log.d("TAG_OUTPUT",""+String.valueOf(outputMap.size()));

    tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
    Trace.endSection();

```
No entendí el significado de este error porque hice exactamente lo mismo que su clase TFLiteObjectDetectionAPIModel.java.
gracias por ayudar

tengo el mismo problema.. tengo solucion?
Gracias..

@ Georg-W Deberá cambiar la detección máxima en export_tflite_ssd_graph.py también. Hay una opción de línea de comando.

Hola

Estoy tratando de detectar más de 10 objetos en la imagen (que es el valor predeterminado)
Estoy usando los siguientes comandos:
bazel run -c opt tensorflow/contrib/lite/ toco:toco ---input_file=$OUTPUT_DIR/tflite_graph.pb --output_file=$OUTPUT_DIR/mobile_net_500.tflite --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor -- output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_Po stProcess:1 ','TFLite_Detection_Po stProcess:2 ','TFLite_Detection_Po stProcess:3 ' --inference_type=FLOAT --max_detections=500 --max_classes_per_detection=1 --allow_custom_ops

yo tambien modifique
export_tflite_ssd_graph.py
flags.DEFINE_integer('max_detections', 500 <--- en lugar de 10,
'Número máximo de detecciones (cajas) para mostrar.')
flags.DEFINE_integer('max_classes_per_detection', 1,
'Número de clases para mostrar por cuadro de detección.')

pero aún dando 10 objetos como salida en android [1,10,4].

¿alguna idea?

También estaría interesado en la solución del problema de @KaviSanth .

Esta solución de @Stevelb debería funcionar. Es posible que desee visualizar el gráfico congelado para asegurarse de que max_detections esté configurado correctamente.

@achowdhery Gracias por su respuesta. Intenté ejecutar los comandos escritos por @andrewharp pero aparece el siguiente error. De hecho, toco no se encuentra en este lugar. Estoy usando la versión maestra y la versión r1.95 del repositorio de github.

bazel ejecuta tensorflow/contrib/lite/ toco:toco --input_file=$STRIPPED_PB --output_file=$DETECT_FB --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=Preprocesador/sub - -output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr
INFORMACIÓN: ID de invocación: 0e58a5ef-9fee-4619-b760-aeb1c83c9661
ERROR: omitir 'tensorflow/contrib/lite/ toco:toco ': no ​​existe el paquete 'tensorflow/contrib/lite/toco': archivo BUILD no encontrado en la ruta del paquete
ADVERTENCIA: Falló el análisis del patrón de destino.
ERROR: no existe el paquete 'tensorflow/contrib/lite/toco': no ​​se encontró el archivo BUILD en la ruta del paquete
INFO: Tiempo transcurrido: 0.179s
INFO: 0 procesos.
FALLADO: la compilación NO se completó con éxito (0 paquetes cargados)
FALLADO: la compilación NO se completó con éxito (0 paquetes cargados)
Tengo que enmendar que estoy ejecutando esos comandos desde mi carpeta tensorflow local que se extrajo de git.

Podría encontrar un toco en tensorflow/lite/toco y solo estoy probando si funciona.
ok, parece funcionar usando este toco y aparte de eso tienes que cambiar la ruta $DETECT_FB a $PWD/ssd_mobilenet.tflite ya que en la carpeta contrib/lite solo se encuentra algo de python y nada más.

Aparece un error de tiempo de ejecución al agregar el archivo .tflite en DetectorActivity desde https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android (https://github.com/tensorflow/tensorflow/blob /master/tensorflow/examples/android/src/org/tensorflow/demo/DetectorActivity.java) con la línea

private static final String TF_OD_API_MODEL_FILE =
            "file:///android_asset/ssd_mobilenet_v1.tflite";

E/AndroidRuntime: EXCEPCIÓN FATAL: principal
Proceso: miProceso, PID: 32611
java.lang.RuntimeException: no se pudo encontrar el nodo de entrada 'image_tensor'
en myPackage.myClass.TensorFlowObjectDetectionAPIModel.create(TensorFlowObjectDetectionAPIModel.java:106)

¿No es posible usar modelos .tflite en esa aplicación?

@defaultUser3214 está utilizando un modelo clasificador en la aplicación de detección. MobileNet v1 es un modelo de clasificación. Utilice el modelo SSD de MobileNet

@achowdhery ¡Gracias! Usar el modelo de wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz resultó en ese error. ¿Pero pensé que esta era la versión ssd?

Pero usar ssd_mobilenet_v1_android_export.pb convertido a .tflite que funcionó como .pb antes produce el mismo error.

@defaultUser3214 Esa es una versión antigua del modelo que no funcionará en la última aplicación de demostración lanzada en julio de 2018. Descargue los últimos modelos en julio de 2018 en el modelo de detección del zoológico: funcionan en la aplicación. Abra un nuevo problema si todavía está bloqueado.

@SteveIb También necesita cambiar NUM_DETECTIONS = 500 en TFLiteObjectDetectionAPIModel.java

no se puede convertir ssdmobilenet v1 .pb a .tflite
pb generado a través de la api de detección de objetos Tensorflow @aselle @achowdhery

¿Algún progreso en esto? Intentando convertir frozen_inference_graph.pb a un archivo .TFLITE pero obteniendo un error

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 49152 bytes and a ByteBuffer with 270000 bytes

Para la detección de objetos personalizados en Android. ¿Alguna idea sobre diferentes métodos de conversión? Transfiera ssd_mobilenet_v1_pets aprendidos en Windows 10 siguiendo el tutorial aquí: https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10

¿Algún progreso en esto? Intentando convertir frozen_inference_graph.pb a un archivo .TFLITE pero obteniendo un error

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 49152 bytes and a ByteBuffer with 270000 bytes

Para la detección de objetos personalizados en Android. ¿Alguna idea sobre diferentes métodos de conversión? Transfiera ssd_mobilenet_v1_pets aprendidos en Windows 10 siguiendo el tutorial aquí: https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10

Solo para hacer un seguimiento de esto y ayudar a cualquier otra persona que tenga el mismo error; esto se debe al uso de un punto de control de modelo incorrecto para entrenar. Para trabajar en Android con .tflite, el modelo inicial debe ser MobileNet y también debe estar cuantificado y tendrá esta sección de código o algo similar en el archivo .config:

graph_rewriter { quantization { delay: 48000 weight_bits: 8 activation_bits: 8 } }

¡Ya está disponible en tensorflow/contrib/lite/examples/android ! Este es un puerto más completo de la demostración original de Android TF (solo le falta el ejemplo Stylize), y reemplazará a la otra demostración en tensorflow/contrib/lite/java/demo en el futuro.

Puede encontrar un búfer plano de TF Lite convertido en mobilenet_ssd_tflite_v1.zip , y puede encontrar la implementación de inferencia de Java en TFLiteObjectDetectionAPIModel.java . Tenga en cuenta que esto difiere de la implementación original de TF en que las cajas deben decodificarse manualmente en Java, y un archivo txt anterior de la caja debe empaquetarse en los activos de las aplicaciones (creo que el que se incluye en el modelo zip anterior debería ser válido para la mayoría gráficos).

Durante la conversión TOCO, se utiliza un nodo de entrada diferente (Preprocesador/sub), así como diferentes nodos de salida (concat, concat_1). Esto omite algunas partes que son problemáticas para tflite, hasta que se reestructura el gráfico o TF Lite alcanza la paridad de TF.

Estos son los pasos rápidos para convertir un modelo SSD MobileNet al formato tflite y crear la demostración para usarlo:

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

¡Esto funciona de maravilla!

¿Fue útil esta página
0 / 5 - 0 calificaciones