EDIT : J'ai écrit ceci à l'époque de TensorFlow 1.4. A ce jour (TensorFlow 1.12 est stable, il y a une 1.13rc et la 2.0 est sur le point d'arriver) les documents liés à la question sont bien meilleurs.
J'essaie d'utiliser tf.saved_model
et j'ai également trouvé les documents assez (trop) abstraits. Voici ma tentative de réponse complète à vos questions :
1. signature_def_map
:
a. Format Voir la réponse de Tom à Tensorflow : comment sauvegarder/restaurer un modèle . ( Ctrl-F
pour "tf.saved_model" - actuellement, les seules utilisations de la phrase sur cette question sont dans sa réponse).
b. besoin Je crois savoir que vous n'en avez normalement pas besoin. Si vous avez l'intention d'utiliser le modèle, vous devez connaître les entrées et les sorties du graphique. Je pense que cela s'apparente à la signature d'une fonction C++ : Si vous avez l'intention de définir une fonction après qu'elle a été appelée ou dans un autre fichier C++, vous avez besoin de la signature dans votre fichier principal (c'est-à-dire prototypé ou dans un fichier d'en-tête).
2. assets_collection
:
format : N'ayant pas trouvé de documentation claire, je me suis adressé au constructeur. code source . Il apparaît que l'argument est un itérable de tenseurs de dtype=tf.string
où chaque tenseur est un chemin d'accès au répertoire des actifs. Ainsi, un TensorFlow Collection de graphiques devrait fonctionner. Je suppose que c'est l'homonyme du paramètre, mais d'après le code source, je m'attendrais à un paramètre Python list
à travailler aussi.
(Vous n'avez pas demandé si vous besoin pour le fixer, mais à en juger par la réponse de Zoé à la question Que sont les actifs dans tensorflow ? et la réponse de l'iga à la question tangentiellement liée Tensorflow serving : "No assets to save/writes" lors de l'exportation de modèles Il n'a généralement pas besoin d'être réglé.)
3. Tags :
a. Pourquoi une liste Je ne sais pas pourquoi vous doit passer une liste, mais vous pouvez passer une liste avec un seul élément. Par exemple, dans mon projet actuel, je n'utilise que l'élément [tf...tag_constants.SERVING]
étiquette.
b. Quand utiliser les multiples Disons que vous utilisez le placement explicite des appareils pour les opérations. Vous souhaitez peut-être enregistrer une version CPU et une version GPU de votre graphique. Il est évident que vous voulez sauvegarder une version de service de chacune d'entre elles, et que vous voulez sauvegarder des points de contrôle d'entraînement. Vous pouvez utiliser une balise CPU/GPU et une balise training/serving pour gérer tous les cas. La balise documents y faire allusion :
Chaque MetaGraphDef ajouté au SavedModel doit être annoté avec des balises spécifiées par l'utilisateur. Les balises permettent d'identifier la MetaGraphDef spécifique à charger et à restaurer, ainsi que l'ensemble partagé de variables et d'actifs. Ces balises annotent généralement un MetaGraphDef avec sa fonctionnalité (par exemple, servir ou former), et éventuellement avec des aspects spécifiques au matériel (par exemple, GPU).
c. Collision Trop paresseux pour forcer une collision moi-même - je vois deux cas qui devraient être traités - je me suis tourné vers le chargeur. code source . A l'intérieur def load
Vous verrez :
saved_model = _parse_saved_model(export_dir)
found_match = False
for meta_graph_def in saved_model.meta_graphs:
if set(meta_graph_def.meta_info_def.tags) == set(tags):
meta_graph_def_to_load = meta_graph_def
found_match = True
break
if not found_match:
raise RuntimeError(
"MetaGraphDef associated with tags " + str(tags).strip("[]") +
" could not be found in SavedModel. To inspect available tag-sets in"
" the SavedModel, please use the SavedModel CLI: `saved_model_cli`"
)
Il me semble qu'il recherche une correspondance exacte. Par exemple, disons que vous avez un métagraphe avec les étiquettes "GPU" et "Serving" et un métagraphe avec l'étiquette "Serving". Si vous chargez "Servir", vous obtiendrez ce dernier métagraphe. D'un autre côté, supposons que vous ayez un métagraphe "GPU" et "Serving" et un métagraphe "CPU" et "Serving". Si vous essayez de charger "Serving", vous obtiendrez l'erreur. Si vous essayez d'enregistrer deux métagraphes avec les mêmes balises dans le même dossier, je m'attends à ce que vous écrasiez le premier. Il ne semble pas que le code de construction gère une telle collision d'une manière particulière.
4. SavedModel
o tf.train.Saver
:
Je ne comprends pas non plus. La réponse de Wicke à la question suivante Les utilisateurs de TensorFlow devraient-ils préférer SavedModel à Checkpoint ou GraphDef ? a clarifié la situation pour moi. Je me permets d'ajouter mon grain de sel :
Dans le cadre de Python+TensorFlow local, vous pouvez faire tf.train.Saver
tout faire. Mais cela vous coûtera cher. Permettez-moi de vous présenter le cas d'utilisation de la sauvegarde d'un modèle formé et d'un déploiement. Vous aurez besoin de votre objet sauveur. Il est plus facile de le configurer pour sauvegarder le graphique complet (chaque variable). Vous ne voudrez probablement pas sauvegarder le .meta
tout le temps puisque vous travaillez avec un graphique statique. Vous devrez le spécifier dans votre crochet d'entraînement. Vous pouvez lire à ce sujet sur cv-tricks . Une fois votre formation terminée, vous devrez convertir votre fichier de points de contrôle en un fichier pb
fichier. Cela signifie généralement qu'il faut effacer le graphique actuel, restaurer le point de contrôle, geler les variables en constantes avec la fonction tf.python.framework.graph_util
et en l'écrivant avec tf.gfile.GFile
. Vous pouvez lire à ce sujet sur support . Ensuite, vous voulez le déployer en Python. Vous aurez besoin des noms des tenseurs d'entrée et de sortie - les noms des chaînes de caractères dans la définition du graphe. sur le métaflux (en fait un très bon article de blog pour le tf.train.Saver
méthode) . Certains nœuds optiques vous permettent d'y introduire facilement des données. D'autres moins. J'ai généralement renoncé à trouver un nœud approprié et j'ai ajouté un élément tf.reshape
qui n'a en fait rien remodelé du graphe def. C'était mon nœud d'entrée ad-hoc. Même chose pour la sortie. Enfin, vous pouvez déployer votre modèle, au moins localement en Python.
Vous pouvez également utiliser la réponse que j'ai indiquée au point 1 pour réaliser tout cela avec le logiciel SavedModel
API. Moins de maux de tête <sup>grâce à la réponse de Tom </sup> . Vous obtiendrez plus de soutien et de fonctionnalités à l'avenir. <sup>s'il est un jour documenté de manière appropriée </sup> . Il semble qu'il soit plus facile d'utiliser le service en ligne de commande (le lien moyen couvre l'utilisation de Saver
- a l'air difficile, bonne chance !) C'est pratiquement intégré dans les nouveaux estimateurs. Et selon les documents,
SavedModel est un neutre sur le plan linguistique format de sérialisation hermétique, récupérable.
C'est moi qui souligne : Il semble que vous puissiez intégrer plus facilement vos modèles formés dans l'API C++ en pleine expansion.
Pour moi, c'est comme l'API Datasets. C'est tout simplement plus facile que l'ancienne méthode !
En ce qui concerne les exemples concrets de SavedModel
de tf.train.Saver
: Si "en gros, quand vous voulez sauvegarder ou restaurer votre modèle" n'est pas assez clair pour vous : Le bon moment pour l'utiliser est chaque fois qu'il vous facilite la vie. Pour moi, c'est toujours le cas. Surtout si vous utilisez des estimateurs, si vous déployez en C++ ou si vous utilisez la ligne de commande.
Voilà donc mes recherches sur votre question. Ou quatre questions énumérées. Euh, huit points d'interrogation. J'espère que cela vous aidera.
4 votes
@WendingPeng ce n'est pas un duplicata de la question liée, voir le dernier paragraphe que j'ai ajouté dans ma question. Veuillez lire plus attentivement et ne pas marquer comme duplicate si facilement.
0 votes
Si vous avez une tentative spécifique d'utilisation de l'API qui vous a posé problème, veuillez l'inclure. Nous demander de documenter entièrement une API peut être trop vaste pour SO.
4 votes
@E_net4 Interrogation sur le format de l'écran d'affichage.
signature_def_map
est une question très spécifique, tout comme mes trois autres questions. Où lisez-vous dans ma question que je demande à quiconque de "documenter entièrement" l'API ?0 votes
Là encore, envisagez de réduire votre choix. Vous avez là 4 points d'énumération, avec au moins une question. Bien sûr, nous interprétons cela comme "s'il vous plaît, documentez cette API mieux que les développeurs de TensorFlow". D'un autre côté, le fait d'avoir un exemple minimal reproductible permet de mieux répondre à cette question.
0 votes
@E_net4 une réponse sur l'un de ces quatre points serait utile. Les trois premières questions portent toutes sur la même méthode (j'ai modifié ma question initiale pour la rendre plus claire), j'espère donc que vous êtes d'accord pour dire qu'elles vont ensemble d'un point de vue thématique. Prenons à nouveau l'exemple de la première question : Je demande quelle est l'entrée de la méthode
signature_def_map
Je ne comprends pas le format de l'argument. N'est-ce pas une question claire ? Si quelqu'un connaît la réponse à cette question, il lui suffirait de donner un exemple "voici à quoi ressemble l'entrée de cet argument".0 votes
@Alex Bonjour, la question que vous avez posée à propos d'une couche de conv avec un noyau "centrosymétrique" est la suivante avait du sens et j'en ai mis en œuvre une version opérationnelle. Si vous avez déjà résolu le problème, faites-le moi savoir et je supprimerai ce commentaire. Sinon, si vous souhaitez connaître ma solution, supprimez votre question et faites-le moi savoir.