38 votes

TensorFlow : Comment et pourquoi utiliser SavedModel ?

J'ai quelques questions concernant la SavedModel API, dont les la documentation Je trouve que beaucoup de détails restent inexpliqués.

Les trois premières questions portent sur ce qu'il faut passer aux arguments de la fonction add_meta_graph_and_variables() méthode de tf.saved_model.builder.SavedModelBuilder tandis que la quatrième question porte sur les raisons d'utiliser l'outil d'évaluation de la qualité de l'eau. SavedModel API sur tf.train.Saver .

  1. Quel est le format du signature_def_map argument ? Dois-je normalement définir cet argument lors de l'enregistrement d'un modèle ?

  2. De même, quel est le format du assets_collection argument ?

  3. Pourquoi enregistre-t-on une liste de balises avec un métagraphe plutôt que de lui donner un nom (c'est-à-dire de ne lui associer qu'une seule balise) ? Pourquoi ajouter plusieurs balises à un métagraphe donné ? Que se passe-t-il si j'essaie de charger un métagraphe à partir d'un fichier pb par une certaine étiquette, mais plusieurs métagraphes dans cette pb correspondre à ce tag ?

  4. La documentation indique qu'il est recommandé d'utiliser SavedModel pour enregistrer des modèles entiers (par opposition aux variables uniquement) dans des fichiers autonomes. Mais il n'est pas possible d'enregistrer des modèles entiers. tf.train.Saver enregistre également le graphique en plus des variables dans un fichier .meta fichier. Quels sont donc les avantages de l'utilisation de SavedModel ? La documentation dit

Lorsque vous souhaitez enregistrer et charger des variables, métadonnées du graphique, c'est-à-dire lorsque vous souhaitez sauvegarder ou restaurer votre modèle, nous vous recommandons d'utiliser SavedModel. SavedModel est une sérialisation hermétique, récupérable et neutre sur le plan linguistique, récupérable, hermétique et neutre du point de vue de la langue. SavedModel permet aux systèmes et outils de niveau supérieur de produire, consommer et transformer les modèles de modèles TensorFlow.

mais cette explication est assez abstraite et ne m'aide pas vraiment à comprendre quels sont les avantages des SavedModel sont. Quels seraient les 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 duplicata de la question suivante cette question . Je ne demande pas comment sauvegarder un modèle, je pose des questions très spécifiques sur les propriétés de SavedModel qui n'est qu'un des nombreux mécanismes que TensorFlow fournit pour sauvegarder et charger des modèles. Aucune des réponses à la question liée n'aborde la question du SavedModel (qui, une fois de plus, n'est pas la même chose que l'API tf.train.Saver ).

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 ?

46voto

Dylan F Points 1010

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.

3 votes

J'aimerais pouvoir voter plusieurs fois pour votre excellente réponse. Merci beaucoup.

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