Tensorflow y OpenCV en tiempo real de clasificación.

Estoy probando las aguas de aprendizaje automático y utilicé el modelo de inicio de TS para volver a entrenar la red para clasificar mis objetos deseados.

Inicialmente, mis predicciones se ejecutaron en imágenes almacenadas localmente y me di cuenta de que tardó entre 2 y 5 segundos en desaparecer la gráfica de un archivo y casi al mismo tiempo para ejecutar las predicciones reales.

Después de eso, adapté mi código para incorporar la alimentación de la cámara de OpenCV, pero con los tiempos señalados anteriormente, los retrasos en el video son inevitables.

Se esperaba un golpe de tiempo durante la carga inicial del gráfico; Es por eso que initialSetup() se ejecuta de antemano, pero 2-5 segundos es simplemente absurdo. Me siento como con mi aplicación actual; Clasificación en tiempo real, esta no es la mejor manera de cargarla. ¿Hay otra manera de hacer esto? Sé que con las versiones móviles, TS recomienda recortar el gráfico. ¿Sería el camino para adelgazar? En caso de que importe mi gráfica es actualmente de 87.4MB.

Junto con esto, ¿hay una manera de acelerar el proceso de predicción?

 import os import cv2 import timeit import numpy as np import tensorflow as tf camera = cv2.VideoCapture(0) # Loads label file, strips off carriage return label_lines = [line.rstrip() for line in tf.gfile.GFile('retrained_labels.txt')] def grabVideoFeed(): grabbed, frame = camera.read() return frame if grabbed else None def initialSetup(): os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' start_time = timeit.default_timer() # This takes 2-5 seconds to run # Unpersists graph from file with tf.gfile.FastGFile('retrained_graph.pb', 'rb') as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) tf.import_graph_def(graph_def, name='') print 'Took {} seconds to unpersist the graph'.format(timeit.default_timer() - start_time) def classify(image_data): print '********* Session Start *********' with tf.Session() as sess: start_time = timeit.default_timer() # Feed the image_data as input to the graph and get first prediction softmax_tensor = sess.graph.get_tensor_by_name('final_result:0') print 'Tensor', softmax_tensor print 'Took {} seconds to feed data to graph'.format(timeit.default_timer() - start_time) start_time = timeit.default_timer() # This takes 2-5 seconds as well predictions = sess.run(softmax_tensor, {'Mul:0': image_data}) print 'Took {} seconds to perform prediction'.format(timeit.default_timer() - start_time) start_time = timeit.default_timer() # Sort to show labels of first prediction in order of confidence top_k = predictions[0].argsort()[-len(predictions[0]):][::-1] print 'Took {} seconds to sort the predictions'.format(timeit.default_timer() - start_time) for node_id in top_k: human_string = label_lines[node_id] score = predictions[0][node_id] print('%s (score = %.5f)' % (human_string, score)) print '********* Session Ended *********' initialSetup() while True: frame = grabVideoFeed() if frame is None: raise SystemError('Issue grabbing the frame') frame = cv2.resize(frame, (299, 299), interpolation=cv2.INTER_CUBIC) # adhere to TS graph input structure numpy_frame = np.asarray(frame) numpy_frame = cv2.normalize(numpy_frame.astype('float'), None, -0.5, .5, cv2.NORM_MINMAX) numpy_final = np.expand_dims(numpy_frame, axis=0) classify(numpy_final) cv2.imshow('Main', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break camera.release() cv2.destroyAllWindows() 

EDITAR 1

Después de depurar mi código, me di cuenta de que la creación de sesiones es una operación que consume tanto recursos como tiempo.

En el código anterior, se creó una nueva sesión para cada fuente de OpenCV además de ejecutar las predicciones. Ajustar las operaciones de OpenCV dentro de una sola sesión proporciona una mejora de tiempo masiva pero esto aún agrega una sobrecarga masiva en la ejecución inicial; la predicción tarda 2-3 segundos. Después, la predicción toma alrededor de 0,5 s, lo que hace que la alimentación de la cámara se mantenga lenta.

 import os import cv2 import timeit import numpy as np import tensorflow as tf camera = cv2.VideoCapture(0) # Loads label file, strips off carriage return label_lines = [line.rstrip() for line in tf.gfile.GFile('retrained_labels.txt')] def grabVideoFeed(): grabbed, frame = camera.read() return frame if grabbed else None def initialSetup(): os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' start_time = timeit.default_timer() # This takes 2-5 seconds to run # Unpersists graph from file with tf.gfile.FastGFile('retrained_graph.pb', 'rb') as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) tf.import_graph_def(graph_def, name='') print 'Took {} seconds to unpersist the graph'.format(timeit.default_timer() - start_time) initialSetup() with tf.Session() as sess: start_time = timeit.default_timer() # Feed the image_data as input to the graph and get first prediction softmax_tensor = sess.graph.get_tensor_by_name('final_result:0') print 'Took {} seconds to feed data to graph'.format(timeit.default_timer() - start_time) while True: frame = grabVideoFeed() if frame is None: raise SystemError('Issue grabbing the frame') frame = cv2.resize(frame, (299, 299), interpolation=cv2.INTER_CUBIC) cv2.imshow('Main', frame) # adhere to TS graph input structure numpy_frame = np.asarray(frame) numpy_frame = cv2.normalize(numpy_frame.astype('float'), None, -0.5, .5, cv2.NORM_MINMAX) numpy_final = np.expand_dims(numpy_frame, axis=0) start_time = timeit.default_timer() # This takes 2-5 seconds as well predictions = sess.run(softmax_tensor, {'Mul:0': numpy_final}) print 'Took {} seconds to perform prediction'.format(timeit.default_timer() - start_time) start_time = timeit.default_timer() # Sort to show labels of first prediction in order of confidence top_k = predictions[0].argsort()[-len(predictions[0]):][::-1] print 'Took {} seconds to sort the predictions'.format(timeit.default_timer() - start_time) for node_id in top_k: human_string = label_lines[node_id] score = predictions[0][node_id] print('%s (score = %.5f)' % (human_string, score)) print '********* Session Ended *********' if cv2.waitKey(1) & 0xFF == ord('q'): sess.close() break camera.release() cv2.destroyAllWindows() 

Editar 2

Después de juguetear, me topé con la cuantificación de gráficos y la transformación de gráficos, y estos fueron los resultados obtenidos.

Gráfico original: 87.4MB

Gráfico cuantificado: 87.5MB

Gráfica transformada: 87.1MB

Cálculo de ocho bits: 22 MB, pero se encontró con esto al usarlo.

Recientemente agregué la opción de entrenar los modelos más pequeños de Mobilenet usando TensorFlow para Poetas: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/docs_src/tutorials/image_retraining.md#other-model-architectures

Esto puede ayudar a acelerar su clasificación, a costa de cierta precisión.