J'ai quelques questions concernant l'API SavedModel
, dont documentation je trouve laisse beaucoup de détails inexpliqués.
Les trois premières questions portent sur ce qu'il faut passer aux arguments de la méthode add_meta_graph_and_variables()
de tf.saved_model.builder.SavedModelBuilder
, tandis que la quatrième question porte sur les raisons d'utiliser l'API SavedModel
sur tf.train.Saver
.
Quel est le format du signature_def_map
argument? Dois-je normalement définir cet argument lors de l'enregistrement d'un modèle?
De même, quel est le format du assets_collection
argument?
Pourquoi enregistrez-vous une liste de balises avec un métagraphie au lieu de simplement lui donner un nom (c'est-à-dire y attacher une seule balise unique)? Pourquoi ajouter plusieurs balises à un métagraphie donné? Que se passe-t-il si j'essaie de charger une métagrpa à partir d'un pb
par une certaine balise, mais plusieurs métagraphes dans cette pb
correspondent à cette balise?
La documentation fait valoir qu'il est recommandé d'utiliser SavedModel
pour enregistrer des modèles entiers (par opposition aux variables uniquement) dans des fichiers autonomes. Mais tf.train.Saver
enregistre également le graphique en plus des variables dans un .meta
fichier. Quels sont donc les avantages de l'utilisation de SavedModel
? La documentation dit
Lorsque vous souhaitez enregistrer et charger des variables, le graphique et les métadonnées du graphique - en gros, lorsque vous souhaitez enregistrer ou restaurer votre modèle - nous vous recommandons d'utiliser SavedModel. SavedModel est un format de sérialisation hermétique indépendant du langage. SavedModel permet aux systèmes et outils de niveau supérieur de produire, consommer et transformer les modèles TensorFlow.
mais cette explication est assez abstraite et ne m'aide pas vraiment à comprendre les avantages de SavedModel
. Quels seraient des exemples concrets où SavedModel
(par opposition à tf.train.Saver
) serait-il préférable d'utiliser?
Veuillez noter que ma question n'est pas un double de cette question . Je ne demande pas comment enregistrer un modèle, je pose des questions très spécifiques sur les propriétés de SavedModel
, qui n'est qu'un des multiples mécanismes que TensorFlow fournit pour enregistrer et charger des modèles. Aucune des réponses de la question liée ne concerne l'API SavedModel
(qui, une fois de plus, n'est pas la même chose que tf.train.Saver
).
[~ # ~] éditez [~ # ~] : J'ai réécrit ceci à TensorFlow 1.4. À ce jour (TensorFlow 1.12 est stable, il y a un 1.13rc et 2.0 est au coin de la rue) les documents liés dans la question sont bien améliorés.
J'essaie d'utiliser tf.saved_model
et a également trouvé les Docs assez (trop) abstraits. Voici mon coup de couteau pour une réponse complète à vos questions:
signature_def_map
: a. Format Voir la réponse de Tom à Tensorflow: comment enregistrer/restaurer un modèle . (Ctrl-F
pour "tf.saved_model" - actuellement, les seules utilisations de la phrase sur cette question se trouvent dans sa réponse).
b. besoin Je crois comprendre que vous en avez normalement besoin. Si vous avez l'intention d'utiliser le modèle, vous devez connaître les entrées et sorties du graphique. Je pense que cela ressemble à une signature de fonction C++: Si vous avez l'intention de définir une fonction après son appel 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).
assets_collection
: format: Impossible de trouver une documentation claire, donc je suis allé voir le constructeur code source . Il apparaît que l'argument est un itérable des tenseurs de dtype=tf.string
, où chaque tenseur est un chemin d'accès au répertoire d'actifs. Ainsi, un TensorFlow Collection de graphes devrait fonctionner. Je suppose que c'est l'homonyme du paramètre, mais d'après le code source, je m'attendrais à ce qu'un Python list
fonctionne aussi.
(Vous n'avez pas demandé si vous avez besoin de le définir, mais à en juger par la réponse de Zoe à Quels sont les actifs dans tensorflow? et la réponse d'iga à la relation tangentielle Tensorflow servant: "Aucun actif à sauvegarder/écrit" lors de l'exportation de modèles , il n'a généralement pas besoin d'être défini.)
a. Pourquoi lister Je ne sais pas pourquoi vous devez passer une liste, mais vous pouvez passer une liste avec un élément. Par exemple, dans mon projet actuel, j'utilise uniquement le [tf...tag_constants.SERVING]
tag.
b. Quand utiliser plusieurs Supposons que vous utilisez un placement d'appareil explicite pour les opérations. Vous souhaitez peut-être enregistrer une version CPU et une version GPU de votre graphique. De toute évidence, vous souhaitez enregistrer une version de service de chacun et dire que vous souhaitez enregistrer les points de contrôle de la formation. Vous pouvez utiliser une balise CPU/GPU et une balise de formation/service pour gérer tous les cas. Le docs fait allusion:
Chaque MetaGraphDef ajouté au SavedModel doit être annoté avec des balises spécifiées par l'utilisateur. Les balises fournissent un moyen d'identifier le 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 ses fonctionnalités (par exemple, servir ou former), et éventuellement avec des aspects spécifiques au matériel (par exemple, GPU).
c. Collision Trop paresseux pour forcer moi-même une collision - Je vois deux cas qui auraient besoin d'être résolus - Je suis allé au chargeur code source . À l'intérieur def load
, tu verras:
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 cherche une correspondance exacte. Par exemple. disons que vous avez un métagraphie avec les balises "GPU" et "Serving" et un métagraphie avec la balise "Serving". Si vous chargez "Serving", vous obtiendrez ce dernier métagraphie. Par contre, disons que vous avez un métagraphie "GPU" et "Serving" et un métagraphie "CPU" et "Serving". Si vous essayez de charger "Serving", vous obtiendrez l'erreur. Si vous essayez d'enregistrer deux métagraphes avec exactement les mêmes balises dans le même dossier, je suppose que vous écraserez le premier. Il ne semble pas que le code de construction gère une telle collision d'une manière spéciale.
SavedModel
ou tf.train.Saver
:Cela m'a aussi troublé. La réponse de wicke à Les utilisateurs de TensorFlow devraient-ils préférer SavedModel à Checkpoint ou GraphDef? m'a éclairé. Je jette mes deux cents:
Dans le cadre de Python + TensorFlow local, vous pouvez faire tf.train.Saver
faire tout. Mais cela vous coûtera. Permettez-moi de décrire le cas d'utilisation de l'enregistrement d'un modèle et d'un déploiement formés. Vous aurez besoin de votre objet économiseur. Il est plus facile de le configurer pour enregistrer le graphique complet (chaque variable). Vous ne voulez probablement pas enregistrer le .meta
tout le temps depuis que vous travaillez avec un graphique statique. Vous devrez spécifier cela 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 point de contrôle en un fichier pb
. Cela signifie généralement effacer le graphique actuel, restaurer le point de contrôle, geler vos variables en constantes avec tf.python.framework.graph_util
, et l'écrire avec tf.gfile.GFile
. Vous pouvez lire à ce sujet en moyenne . Après cela, vous souhaitez le déployer en Python. Vous aurez besoin des noms de tenseur d'entrée et de sortie - les noms de chaîne dans le graphique def. Vous pouvez en lire plus sur metaflow (en fait un très bon article de blog pour le tf.train.Saver
méthode) . Certains nœuds opérationnels vous permettront de les alimenter facilement. Certains pas tellement. J'ai généralement abandonné la recherche d'un nœud approprié et ajouté un tf.reshape
qui n'a en fait rien remodelé à la définition du graphique. C'était mon nœud d'entrée ad hoc. Idem pour la sortie. Et enfin, vous pouvez déployer votre modèle, au moins localement en Python.
Ou, vous pouvez utiliser la réponse que j'ai liée au point 1 pour accomplir tout cela avec l'API SavedModel
. Moins de maux de tête grâce à la réponse de Tom . Vous obtiendrez plus de support et de fonctionnalités à l'avenir si jamais il est correctement documenté . Il semble qu'il soit plus facile d'utiliser le service en ligne de commande (le lien moyen couvre cela avec Saver
- ça a l'air difficile, bonne chance!). Il est pratiquement intégré aux nouveaux estimateurs. Et selon les documents,
SavedModel est un format de sérialisation hermétique indépendant du langage (- === -).
Je souligne: il semble que vous puissiez obtenir vos modèles formés dans l'API C++ en pleine croissance beaucoup plus facilement.
Pour moi, c'est comme l'API Datasets. C'est juste plus facile que l'ancienne!
Pour des exemples concrets de SavedModel
de tf.train.Saver
: Si "fondamentalement, 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 que cela vous facilite la vie. Pour moi, cela ressemble à toujours. Surtout si vous utilisez des estimateurs, un déploiement en C++ ou un service en 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 t'aides.