python - reconocimiento - Tensorflow y OpenCV clasificación en tiempo real
tensorflow reconocimiento de imagen (1)
Estoy probando las aguas de aprendizaje automático y utilicé el modelo de inicio TS para reciclar la red y clasificar los objetos que desea.
Inicialmente, mis predicciones se ejecutaron en imágenes almacenadas localmente y me di cuenta de que tardaba entre 2 y 5 segundos en no usar el gráfico de un archivo y al mismo tiempo para ejecutar las predicciones reales.
A partir de entonces, adapté mi código para incorporar la alimentación de la cámara desde OpenCV, pero con los tiempos indicados anteriormente, los retrasos de video son inevitables.
Se esperaba un golpe de tiempo durante la carga gráfica inicial; por eso initialSetup()
se ejecuta de antemano, pero 2-5 segundos es simplemente absurdo. Me siento con mi aplicación actual; clasificación en tiempo real, esta no es la mejor manera de cargarlo. ¿Hay otra manera de hacer esto? Sé que con las versiones móviles TS recomienda recortar el gráfico. ¿Lo adelgazaría sería el camino para llegar aquí? En caso de que importe, mi gráfico actualmente es de 87.4MB
Junto con esto, ¿hay alguna forma 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()
EDIT 1
Después de depurar mi código, me di cuenta de que la creación de la sesión es una operación que consume mucho tiempo y recursos.
En el código anterior, se creó una nueva sesión para cada feed de OpenCV además de ejecutar las predicciones. Envolver las operaciones de OpenCV dentro de una sola sesión proporciona una mejora masiva de tiempo, pero esto aún agrega una sobrecarga masiva en la ejecución inicial; la predicción toma 2-3 segundos. Luego, la predicción toma alrededor de 0.5 segundos, lo que hace que la alimentación de la cámara siga siendo 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()
EDIT 2
Después de juguetear, tropecé con la cuantización de gráficos y la transformación de gráficos, y estos fueron los resultados obtenidos.
Original Graph: 87.4MB
Gráfico cuantificado: 87.5MB
Gráfico transformado: 87.1MB
Cálculo de ocho bits: 22 MB pero se encontró con esto al usarlo.
Recientemente agregué la opción para entrenar a los modelos más pequeños de Mobilenet usando TensorFlow for Poets: 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.