Signatures courantes pour les images

Cette page décrit les signatures courantes qui doivent être implémentées par les modules au format TF1 Hub pour les tâches liées aux images. (Pour le format TF2 SavedModel , voir l' API SavedModel analogue.)

Certains modules peuvent être utilisés pour plus d'une tâche (par exemple, les modules de classification d'images ont tendance à effectuer certaines extractions de fonctionnalités en cours de route). Par conséquent, chaque module fournit (1) des signatures nommées pour toutes les tâches prévues par l'éditeur, et (2) une output = m(images) pour sa tâche principale désignée.

Vecteur de caractéristiques d'image

Résumé d'utilisation

Un vecteur de caractéristiques d'image est un tenseur 1D dense qui représente une image entière, généralement destinée à être classée par le modèle consommateur. (Contrairement aux activations intermédiaires des CNN, elle n'offre pas de répartition spatiale. Contrairement à la classification d'images , elle ignore la classification apprise par le modèle éditeur.)

Un module d'extraction de caractéristiques d'image possède une signature par défaut qui mappe un lot d'images à un lot de vecteurs de caractéristiques. Il peut être utilisé comme ceci :

  module_spec = hub.load_module_spec("path/to/module")
  height, width = hub.get_expected_image_size(module_spec)
  images = ...  # A batch of images with shape [batch_size, height, width, 3].
  module = hub.Module(module_spec)
  features = module(images)   # A batch with shape [batch_size, num_features].

Il définit également la signature nommée correspondante.

Spécification de la signature

La signature nommée pour extraire les vecteurs de caractéristiques de l'image est invoquée comme

  outputs = module(dict(images=images), signature="image_feature_vector",
                   as_dict=True)
  features = outputs["default"]

La saisie suit la convention générale pour la saisie d'images .

Le dictionnaire de sorties contient une sortie "default" de type float32 et shape [batch_size, num_features] . Le batch_size est le même que celui de l'entrée, mais n'est pas connu au moment de la construction du graphique. num_features est une constante connue, spécifique au module, indépendante de la taille d'entrée.

Ces vecteurs de caractéristiques sont censés être utilisables pour la classification avec un simple classificateur à action directe (comme les caractéristiques regroupées de la couche convolutive la plus élevée dans un CNN typique pour la classification d'images).

L'application ou non de la suppression aux fonctionnalités de sortie doit être laissée au consommateur du module. Le module lui-même ne doit pas effectuer de suppression sur les sorties réelles (même s'il utilise une suppression en interne à d'autres endroits).

Le dictionnaire de sorties peut fournir d'autres sorties, par exemple les activations de couches cachées à l'intérieur du module. Leurs clés et valeurs dépendent du module. Il est recommandé de préfixer les clés dépendant de l'architecture avec un nom d'architecture (par exemple, pour éviter de confondre la couche intermédiaire "InceptionV3/Mixed_5c" avec la couche convolutive la plus élevée "InceptionV2/Mixed_5c" ).

Classement des images

Résumé d'utilisation

La classification d'images mappe les pixels d'une image à des scores linéaires (logits) pour l'appartenance aux classes d'une taxonomie sélectionnée par l'éditeur du module . Cela permet aux consommateurs de tirer des conclusions de la classification particulière apprise par le module éditeur, et pas seulement de ses fonctionnalités sous-jacentes (cf. Image Feature Vector ).

Un module d'extraction de caractéristiques d'image possède une signature par défaut qui mappe un lot d'images à un lot de logits. Il peut être utilisé comme ceci :

  module_spec = hub.load_module_spec("path/to/module")
  height, width = hub.get_expected_image_size(module_spec)
  images = ...  # A batch of images with shape [batch_size, height, width, 3].
  module = hub.Module(module_spec)
  logits = module(images)   # A batch with shape [batch_size, num_classes].

Il définit également la signature nommée correspondante.

Spécification de la signature

La signature nommée pour extraire les vecteurs de caractéristiques de l'image est invoquée comme

  outputs = module(dict(images=images), signature="image_classification",
                   as_dict=True)
  logits = outputs["default"]

La saisie suit la convention générale pour la saisie d'images .

Le dictionnaire de sorties contient une sortie "default" de type float32 et shape [batch_size, num_classes] . Le batch_size est le même que celui de l'entrée, mais n'est pas connu au moment de la construction du graphique. num_classes est le nombre de classes dans la classification, qui est une constante connue indépendante de la taille d'entrée.

L'évaluation outputs["default"][i, c] donne un score prédisant l'appartenance de l'exemple i à la classe d'index c .

Cela dépend de la classification sous-jacente si ces scores sont destinés à être utilisés avec softmax (pour les classes mutuellement exclusives), sigmoïde (pour les classes orthogonales) ou autre chose. La documentation du module doit décrire cela et faire référence à une définition des indices de classe.

Le dictionnaire de sorties peut fournir d'autres sorties, par exemple les activations de couches cachées à l'intérieur du module. Leurs clés et valeurs dépendent du module. Il est recommandé de préfixer les clés dépendant de l'architecture avec un nom d'architecture (par exemple, pour éviter de confondre la couche intermédiaire "InceptionV3/Mixed_5c" avec la couche convolutive la plus élevée "InceptionV2/Mixed_5c" ).

Saisie d'images

Ceci est commun à tous les types de modules d’image et de signatures d’image.

Une signature qui prend un lot d'images en entrée les accepte comme un tenseur 4D dense de type float32 et de forme [batch_size, height, width, 3] dont les éléments sont des valeurs de couleur RVB de pixels normalisés dans la plage [0, 1] . C'est ce que vous obtenez de tf.image.decode_*() suivi de tf.image.convert_image_dtype(..., tf.float32) .

Un module avec exactement une (ou une principale) entrée d'images utilise le nom "images" pour cette entrée.

Le module accepte n'importe quel batch_size et définit en conséquence la première dimension de TensorInfo.tensor_shape sur "inconnu". La dernière dimension est fixée au numéro 3 des canaux RVB. Les dimensions height et width sont fixées à la taille attendue des images d'entrée. (Des travaux futurs pourraient supprimer cette restriction pour les modules entièrement convolutifs.)

Les consommateurs du module ne doivent pas inspecter la forme directement, mais obtenir les informations de taille en appelant hub.get_expected_image_size() sur le module ou la spécification du module, et doivent redimensionner les images d'entrée en conséquence (généralement avant/pendant le traitement par lots).

Pour plus de simplicité, les modules TF-Hub utilisent la channels_last (ou NHWC ) de Tensors et laissent à l'optimiseur de graphique de TensorFlow le soin de réécrire channels_first (ou NCHW ) si nécessaire. Il le fait par défaut depuis la version 1.7 de TensorFlow.