Tensorflow: la restauration d'un graphique et le modèle d'exécution de l'évaluation sur une seule image
Je pense qu'il serait extrêmement utile à la Tensorflow de la communauté s'il y a bien la solution de la tâche cruciale de l'essai d'une nouvelle image sur le modèle créé par le convnet dans l'ICRA-10 tutoriel.
J'ai peut-être tort, mais cette étape critique qui rend le modèle appris utilisable dans la pratique semble être en manque. Il y a un "chaînon manquant" dans le tutoriel—un script qui permettrait de charger directement une seule image (sous forme de tableau ou binaire), la comparaison avec le modèle appris, et de retourner une classification.
Réponses avant de donner des solutions partielles qui expliquent l'approche globale, mais aucun de qui j'ai été en mesure de mettre en œuvre avec succès. D'autres morceaux peuvent être trouvés ici et là, mais, malheureusement, n'ont pas ajouté à une solution de travail. Veuillez considérer les recherches que j'ai fait, avant de marquage ce des doublons ou déjà répondu.
Tensorflow: comment sauvegarder/restaurer un modèle?
La restauration de TensorFlow modèle
Incapable de restaurer les modèles dans tensorflow v0.8
https://gist.github.com/nikitakit/6ef3b72be67b86cb7868
La réponse la plus populaire est la première, dans laquelle @RyanSepassi et @YaroslavBulatov décrire le problème et une approche: on a besoin de "construire manuellement un graphique avec les mêmes noms de nœud, et l'utilisation de l'Économiseur de charger le poids en elle". Bien que les deux réponses sont utiles, il n'est pas évident comment on allait faire à propos de cela branchant dans l'ICRA-10 projet.
Entièrement fonctionnelle d'une solution serait hautement souhaitable de sorte que nous pourrions porter sur d'autres de l'image unique, les problèmes de classification. Il y a plusieurs questions DONC, à cet égard, que demander cela, mais toujours pas de réponse complète (par exemple La charge de point de contrôle et évaluer une seule image avec tensorflow DNN).
J'espère que nous pourrons aboutir à un travail de script que tout le monde pourrait utiliser.
Le script ci-dessous n'est pas encore fonctionnelle, et je serais heureux de vous entendre sur la façon dont cela peut être amélioré pour offrir une solution unique de classification des images à l'aide de l'ICRA-10 TF tutoriel modèle appris.
Assumer toutes les variables, les noms de fichiers etc. sont intacts de la didacticiel d'origine.
Nouveau fichier: cifar10_eval_single.py
import cv2
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('eval_dir', './input/eval',
"""Directory where to write event logs.""")
tf.app.flags.DEFINE_string('checkpoint_dir', './input/train',
"""Directory where to read model checkpoints.""")
def get_single_img():
file_path = './input/data/single/test_image.tif'
pixels = cv2.imread(file_path, 0)
return pixels
def eval_single_img():
# below code adapted from @RyanSepassi, however not functional
# among other errors, saver throws an error that there are no
# variables to save
with tf.Graph().as_default():
# Get image.
image = get_single_img()
# Build a Graph.
# TODO
# Create dummy variables.
x = tf.placeholder(tf.float32)
w = tf.Variable(tf.zeros([1, 1], dtype=tf.float32))
b = tf.Variable(tf.ones([1, 1], dtype=tf.float32))
y_hat = tf.add(b, tf.matmul(x, w))
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
print('Checkpoint found')
else:
print('No checkpoint found')
# Run the model to get predictions
predictions = sess.run(y_hat, feed_dict={x: image})
print(predictions)
def main(argv=None):
if tf.gfile.Exists(FLAGS.eval_dir):
tf.gfile.DeleteRecursively(FLAGS.eval_dir)
tf.gfile.MakeDirs(FLAGS.eval_dir)
eval_single_img()
if __name__ == '__main__':
tf.app.run()
Vous devez vous connecter pour publier un commentaire.
Il existe deux méthodes pour nourrir une seule nouvelle image à la cifar10 modèle. La première méthode est plus propre approche, mais nécessite une modification dans le fichier principal, auront donc besoin de reconversion. La seconde méthode est applicable lorsqu'un utilisateur ne souhaite pas modifier les fichiers de modèle et cherche à utiliser les check-point/méta-graphe de fichiers.
Le code pour la première approche est la suivante:
Le script nécessite qu'un utilisateur crée deux espaces réservés et une exécution conditionnelle déclaration pour que cela fonctionne.
Les espaces réservés et de l'exécution conditionnelle de déclaration sont ajoutés dans cifar10_train.py comme indiqué ci-dessous:
Les entrées dans cifar10 modèle sont connectés à la file d'attente coureur de l'objet, qui est un processus à plusieurs étapes de la file d'attente qui peut prefetch de données à partir de fichiers en parallèle. Voir une belle animation de file de coureur ici
Alors que la file d'attente des coureurs sont efficaces dans le pré-chargement de grand jeu de données pour la formation, ils sont un overkill pour l'inférence/test où un seul fichier qui est nécessaire pour être classés, ils sont aussi un peu plus compliqué à modifier ou à maintenir.
Pour cette raison, j'ai ajouté un espace réservé "is_training", qui est défini à False, alors qu'une formation comme indiqué ci-dessous:
Un autre espace réservé "dim" est titulaire d'un tenseur de forme (1,32,32,3) de l'image qui seront introduits lors de l'inférence -- la première dimension est la taille du lot qui est dans ce cas. J'ai modifié l'icra modèle d'accepter 32x32 au lieu de 24x24 que l'original cifar10 images sont 32x32.
Enfin, l'instruction conditionnelle se nourrit de l'espace réservé en file d'attente ou coureur de sortie pour le graphique. Le "is_training" espace réservé est définie sur False lors de l'inférence et "img" de l'espace réservé est nourri d'un tableau numpy -- le tableau numpy est de passer de 3 à 4 dimensions vecteur pour se conformer à l'entrée du tenseur à l'inférence de la fonction dans le modèle.
C'est tout là est à lui. N'importe quel modèle peut être déduit avec un seul/défini par l'utilisateur des données de test comme indiqué dans le script ci-dessus. Essentiellement lire le graphique, les données de flux pour les noeuds d'un graphe et d'exécuter le graphe pour obtenir le résultat final.
Maintenant la deuxième méthode. L'autre approche consiste à pirater cifar10.py et cifar10_eval.py pour modifier la taille du lot de l'un et de remplacer les données provenant de la file d'attente de coureur avec la lecture à partir d'un fichier.
Définir la taille du lot de 1:
Appel d'inférence avec une image de lecture de fichier.
Puis passer logits de eval_once et modifier eval une fois pour évaluer les logits:
Il n'y a pas de script pour exécuter cette méthode d'inférence, il suffit d'exécuter cifar10_eval.py qui va lire un fichier à partir de l'emplacement défini par l'utilisateur avec une taille de lot de l'un.
cifar10_train
exemple et il y a un problème avec l'instruction conditionnelle qui génère l'erreur suivante:ValueError: Shape of a new variable (local3/weights) must be fully defined, but instead was (?, 384)
et se répercute de retour àcifar10
. Le problème semble se manifester dans# local3
sousweights = _variable_with_weight_decay('weights', shape=[dim, 384], stddev=0.04, wd=0.004)
. Sans l'ajout de ce codecifar10_train
imprimée correctement.images, labels = cifar10.inputs(eval_data=eval_data)
, puisque niimages
nilabels
sont utilisés.Voici comment j'ai couru une seule image à la fois. Je vais vous avouer que cela semble un peu hacky avec la réutilisation de l'obtention de la portée.
C'est une fonction d'assistance
Ici est la partie principale du code qui s'exécute une seule image à la fois dans la boucle for.
Ici est une variante de mise en œuvre de la ci-dessus en utilisant les détenteurs de place c'est un peu plus propre à mon avis. mais je vais laisser l'exemple ci-dessus, pour des raisons historiques.
l'ai eu à travailler avec cette
sortie
Je n'ai pas le code qui fonctionne pour vous, j'ai peur, mais voici comment nous avons souvent de s'attaquer à ce problème en production:
Enregistrer le GraphDef sur le disque, en utilisant quelque chose comme write_graph.
Utilisation freeze_graph pour charger le GraphDef et des points de contrôle, et d'enregistrer un GraphDef avec les Variables convertis en des Constantes.
Charge de la GraphDef dans quelque chose comme label_image ou classify_image.
Pour votre exemple, c'est exagéré, mais j'aurais au moins suggérer la sérialisation sur le graphe de l'exemple original comme un GraphDef, puis de le charger dans votre script (si vous n'avez pas à dupliquer le code générer le graphique). Avec le même graphique que vous avez créé, vous devriez être en mesure de l'alimenter à partir d'un SaverDef, et la freeze_graph script peut aider comme un exemple.