2 votes

Exécution de label_image.py en boucle

Mon objectif est de classer en continu des images .jpg provenant d'un flux vidéo.

Pour ce faire, j'ai juste modifié l'exemple label_image.py.

Je charge le graphe et ouvre les sessions préalablement. Ensuite, je n'exécute que le code suivant dans une boucle :

t = read_tensor_from_image_file(file_name,
                                input_height=input_height,
                                input_width=input_width,
                                input_mean=input_mean,
                                input_std=input_std)

input_operation = graph.get_operation_by_name(input_name);
output_operation = graph.get_operation_by_name(output_name);

results = sess2.run(output_operation.outputs[0],
                  {input_operation.outputs[0]: t}
                  )

results = np.squeeze(results)

top_k = results.argsort()[-5:][::-1]
labels = load_labels(label_file)

Cela fonctionne bien pendant quelques minutes, mais le problème est que la classification ralentit progressivement à chaque cycle. Elle passe d'une demi-seconde à quelques secondes en une minute. Mon utilisation de la mémoire augmente également lentement, d'environ 1 Mo toutes les 3 secondes.

Si je classe une seule image plusieurs fois en omettant la fonction "read_tensor_from_image_file", je n'ai pas ce problème.

Ainsi, quelque chose dans le code de chargement des images doit prendre de plus en plus d'espace à chaque fois, sans se nettoyer correctement :

def read_tensor_from_image_file(file_name, input_height=192, input_width=192,
                                input_mean=0, input_std=255):
  input_name = "file_reader"
  output_name = "normalized"
  file_reader = tf.read_file(file_name, input_name)
  if file_name.endswith(".png"):
    image_reader = tf.image.decode_png(file_reader, channels = 3,
                                       name='png_reader')
  elif file_name.endswith(".gif"):
    image_reader = tf.squeeze(tf.image.decode_gif(file_reader,
                                                  name='gif_reader'))
  elif file_name.endswith(".bmp"):
    image_reader = tf.image.decode_bmp(file_reader, name='bmp_reader')
  else:
    image_reader = tf.image.decode_jpeg(file_reader, channels = 3,
                                        name='jpeg_reader')
  float_caster = tf.cast(image_reader, tf.float32)
  dims_expander = tf.expand_dims(float_caster, 0);
  resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
  normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])

  result = sess1.run(normalized)

  return result

Toute suggestion est grandement appréciée, je suis totalement bloqué sur celui-ci.

J'utilise python 3.4.2 avec tensorflow 1.1.0 sur un raspberry pi avec raspbian jessie.

Merci beaucoup !

2voto

Max Points 729

Chaque fois que vous appelez read_tensor_from_image_file, cela créerait beaucoup de nouveaux nœuds dans le graphe TensorFlow. Comme vous l'avez dit, cette fonction est appelée dans une boucle dans votre code, donc cela créerait dynamiquement beaucoup de nouveaux nœuds de graphe à chaque itération. Cela pourrait être la raison de l'augmentation de l'utilisation de la mémoire et de la lenteur.

Une meilleure façon est de créer le graphe une fois, puis simplement exécuter le graphe dans votre boucle. Par exemple, vous pouvez modifier votre read_tensor_from_image_file comme suit:

def read_tensor_from_image_file(input_height=192, input_width=192, input_mean=0, input_std=255):
  input_name = "file_reader"
  output_name = "normalized"

  # [NOUVEAU] faire de file_name un espace réservé.
  file_name = tf.placeholder("string", name="fname")

  file_reader = tf.read_file(file_name, input_name)
  ...
  normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])

  # [NOUVEAU] ne pas appeler sess1 lors de la construction du graphe.
  # result = sess1.run(normalized)    
  # return result
  return normalized

Dans votre serveur, vous invoquez uniquement read_tensor_from_image_file une fois, et vous l'enregistrez comme read_tensor_from_image_file_op = read_tensor_from_image_file(...) quelque part.

Dans votre boucle, vous pouvez simplement appeler:

t = sess2.run(read_tensor_from_image_file_op, feed_dict={"fname:0": file_name})

input_operation = graph.get_operation_by_name(input_name);
output_operation = graph.get_operation_by_name(output_name);
results = sess2.run(output_operation.outputs[0],
                  {input_operation.outputs[0]: t}
                  )
results = np.squeeze(results)

top_k = results.argsort()[-5:][::-1]
labels = load_labels(label_file)

J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X