Cette page a été traduite par l'API Cloud Translation.
Switch to English

Format du concentrateur TF1

Lors de son lancement en 2018, TensorFlow Hub proposait un seul type d'actif: le format TF1 Hub pour l'importation dans les programmes TensorFlow 1.

Cette page explique comment utiliser le format TF1 Hub dans TF1 (ou le mode de compatibilité TF1 de TF2) avec la classe hub.Module et les API associées. (L'utilisation typique est de construire un tf.Graph , éventuellement à l'intérieur d'un Estimator TF1, en combinant un ou plusieurs modèles au format TF1 Hub avec tf.compat.layers ou tf.layers ).

Les utilisateurs de TensorFlow 2 (en dehors du mode de compatibilité TF1) doivent utiliser la nouvelle API avec hub.load() ou hub.KerasLayer . La nouvelle API charge le nouveau type d'actif TF2 SavedModel, mais a également une prise en charge limitée pour le chargement du format TF1 Hub dans TF2 .

Utilisation d'un modèle au format TF1 Hub

Instancier un modèle au format TF1 Hub

Un modèle au format TF1 Hub est importé dans un programme TensorFlow en créant un objet hub.Module partir d'une chaîne avec son URL ou son chemin d'accès au système de fichiers, tel que:

 m = hub.Module("path/to/a/module_dir")
 

Cela ajoute les variables du module au graphique TensorFlow actuel. L'exécution de leurs initialiseurs lira leurs valeurs pré-entraînées à partir du disque. De même, des tableaux et d'autres états sont ajoutés au graphique.

Modules de mise en cache

Lors de la création d'un module à partir d'une URL, le contenu du module est téléchargé et mis en cache dans le répertoire temporaire du système local. L'emplacement où les modules sont mis en cache peut être remplacé à l'aide de la variable d'environnement TFHUB_CACHE_DIR . Pour plus de détails, consultez Mise en cache .

Appliquer un module

Une fois instancié, un module m peut être appelé zéro ou plusieurs fois comme une fonction Python des entrées tensorielles aux sorties tensorielles:

 y = m(x)
 

Chaque appel de ce type ajoute des opérations au graphe TensorFlow actuel pour calculer y partir de x . Si cela implique des variables avec des poids entraînés, ceux-ci sont partagés entre toutes les applications.

Les modules peuvent définir plusieurs signatures nommées afin de permettre leur application de plusieurs manières (de la même manière que les objets Python ont des méthodes ). La documentation d'un module doit décrire les signatures disponibles. L'appel ci-dessus applique la signature nommée "default" . Toute signature peut être sélectionnée en passant son nom à l'argument optionnel signature= .

Si une signature a plusieurs entrées, elles doivent être passées en tant que dict, avec les clés définies par la signature. De même, si une signature a plusieurs sorties, celles-ci peuvent être récupérées sous forme de dict en passant as_dict=True , sous les clés définies par la signature (la clé "default" est pour la sortie unique retournée si as_dict=False ). La forme la plus générale d'application d'un module ressemble donc à:

 outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]
 

Un appelant doit fournir toutes les entrées définies par une signature, mais il n'est pas nécessaire d'utiliser toutes les sorties d'un module. TensorFlow exécutera uniquement les parties du module qui se retrouvent en tant que dépendances d'une cible dans tf.Session.run() . En effet, les éditeurs de modules peuvent choisir de fournir diverses sorties pour des utilisations avancées (comme les activations de couches intermédiaires) en plus des sorties principales. Les consommateurs de module doivent gérer les sorties supplémentaires avec élégance.

Essayer des modules alternatifs

Chaque fois qu'il y a plusieurs modules pour la même tâche, TensorFlow Hub encourage à les équiper de signartures (interfaces) compatibles, de sorte qu'il soit aussi simple d'essayer différents modules que de faire varier la poignée du module comme un hyperparamètre à valeur de chaîne.

À cette fin, nous maintenons une collection de signatures communes recommandées pour les tâches courantes.

Créer un nouveau module

Note de compatibilité

Le format TF1 Hub est orienté vers TensorFlow 1. Il n'est que partiellement pris en charge par TF Hub dans TensorFlow 2. Veuillez plutôt envisager de publier dans le nouveau format TF2 SavedModel .

Le format TF1 Hub est similaire au format SavedModel de TensorFlow 1 au niveau syntaxique (mêmes noms de fichier et messages de protocole) mais sémantiquement différent pour permettre la réutilisation, la composition et le recyclage des modules (par exemple, stockage différent des initialiseurs de ressources, balisage différent conventions pour les métagraphes). Le moyen le plus simple de les distinguer sur le disque est la présence ou l'absence du fichier tfhub_module.pb .

Approche générale

Pour définir un nouveau module, un éditeur appelle hub.create_module_spec() avec une fonction module_fn . Cette fonction construit un graphique représentant la structure interne du module, en utilisant tf.placeholder() pour les entrées à fournir par l'appelant. Ensuite, il définit les signatures en appelant hub.add_signature(name, inputs, outputs) une ou plusieurs fois.

Par exemple:

 def module_fn():
  inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
  layer1 = tf.layers.dense(inputs, 200)
  layer2 = tf.layers.dense(layer1, 100)
  outputs = dict(default=layer2, hidden_activations=layer1)
  # Add default signature.
  hub.add_signature(inputs=inputs, outputs=outputs)

...
spec = hub.create_module_spec(module_fn)
 

Le résultat de hub.create_module_spec() peut être utilisé, au lieu d'un chemin, pour instancier un objet module dans un graphe TensorFlow particulier. Dans ce cas, il n'y a pas de point de contrôle et l'instance de module utilisera les initialiseurs de variable à la place.

Toute instance de module peut être sérialisée sur disque via sa méthode d' export(path, session) . L'exportation d'un module sérialise sa définition avec l'état actuel de ses variables en session dans le chemin passé. Cela peut être utilisé lors de l'exportation d'un module pour la première fois, ainsi que lors de l'exportation d'un module affiné.

Pour la compatibilité avec les estimateurs TensorFlow, hub.LatestModuleExporter exporte les modules à partir du dernier point de contrôle, tout comme tf.estimator.LatestExporter exporte le modèle entier à partir du dernier point de contrôle.

Les éditeurs de modules doivent mettre en œuvre une signature commune lorsque cela est possible, afin que les consommateurs puissent facilement échanger des modules et trouver le meilleur pour leur problème.

Exemple réel

Jetez un œil à notre exportateur de module d'intégration de texte pour un exemple concret de la création d'un module à partir d'un format d'incorporation de texte courant.

Réglage fin

L'entraînement des variables d'un module importé avec celles du modèle qui l'entoure est appelé réglage fin . Un réglage fin peut entraîner une meilleure qualité, mais ajoute de nouvelles complications. Nous conseillons aux consommateurs de se pencher sur le réglage fin uniquement après avoir exploré des ajustements de qualité plus simples, et uniquement si l'éditeur du module le recommande.

Pour les consommateurs

Pour activer le réglage fin, instanciez le module avec hub.Module(..., trainable=True) pour rendre ses variables entraînables et importez REGULARIZATION_LOSSES de TensorFlow. Si le module comporte plusieurs variantes de graphique, assurez-vous de choisir celle appropriée pour la formation. Habituellement, c'est celui avec les balises {"train"} .

Choisissez un régime de formation qui ne ruine pas les poids pré-entraînés, par exemple, un taux d'apprentissage inférieur à celui de la formation à partir de zéro.

Pour les éditeurs

Pour faciliter la mise au point pour les consommateurs, veuillez tenir compte des points suivants:

  • Le réglage fin doit être régularisé. Votre module est exporté avec la collection REGULARIZATION_LOSSES , qui est ce qui place votre choix de tf.layers.dense(..., kernel_regularizer=...) etc. dans ce que le consommateur obtient de tf.losses.get_regularization_losses() . Préférez cette manière de définir les pertes de régularisation L1 / L2.

  • Dans le modèle de l'éditeur, évitez de définir la régularisation L1 / L2 via les paramètres l1_ et l2_regularization_strength de tf.train.FtrlOptimizer , tf.train.ProximalGradientDescentOptimizer et d'autres optimiseurs proximaux. Ceux-ci ne sont pas exportés avec le module et la définition des forces de régularisation à l'échelle mondiale peut ne pas être appropriée pour le consommateur. À l'exception de la régularisation L1 dans des modèles larges (c'est-à-dire linéaires clairsemés) ou larges et profonds, il devrait être possible d'utiliser des pertes de régularisation individuelles à la place.

  • Si vous utilisez l'abandon, la normalisation par lots ou des techniques d'entraînement similaires, définissez leurs hyperparamètres sur des valeurs qui ont du sens pour de nombreuses utilisations attendues. Le taux d'abandon peut devoir être ajusté en fonction de la propension du problème cible au surajustement. Dans la normalisation par lots, le momentum (aka coefficient de décroissance) doit être suffisamment petit pour permettre un réglage fin avec de petits ensembles de données et / ou de grands lots. Pour les consommateurs avancés, pensez à ajouter une signature qui expose le contrôle des hyperparamètres critiques.