Enregistrer et charger des modèles

TensorFlow.js fournit des fonctionnalités permettant d'enregistrer et de charger des modèles créés avec l'API Layers ou convertis à partir de modèles TensorFlow existants. Il peut s'agir de modèles que vous avez formés vous-même ou de ceux formés par d'autres. L'un des principaux avantages de l'utilisation de l'API Layers est que les modèles créés avec celle-ci sont sérialisables et c'est ce que nous allons explorer dans ce didacticiel.

Ce tutoriel se concentrera sur l'enregistrement et le chargement de modèles TensorFlow.js (identifiables par des fichiers JSON). Nous pouvons également importer des modèles TensorFlow Python. Le chargement de ces modèles est abordé dans les deux didacticiels suivants :

Enregistrer un modèle tf.

tf.Model et tf.Sequential fournissent tous deux une fonction model.save qui vous permet de sauvegarder la topologie et les poids d'un modèle.

  • Topologie : Il s'agit d'un fichier décrivant l'architecture d'un modèle (c'est-à-dire les opérations qu'il utilise). Il contient des références aux poids des modèles qui sont stockés en externe.

  • Poids : Ce sont des fichiers binaires qui stockent les poids d'un modèle donné dans un format efficace. Ils sont généralement stockés dans le même dossier que la topologie.

Voyons à quoi ressemble le code pour enregistrer un modèle

const saveResult = await model.save('localstorage://my-model-1');

Quelques points à noter :

  • La méthode save prend un argument de chaîne de type URL qui commence par un schéma . Ceci décrit le type de destination dans laquelle nous essayons d'enregistrer un modèle. Dans l'exemple ci-dessus, le schéma est localstorage://
  • Le schéma est suivi d'un chemin . Dans l'exemple ci-dessus, le chemin est my-model-1 .
  • La méthode save est asynchrone.
  • La valeur de retour de model.save est un objet JSON qui contient des informations telles que la taille en octets de la topologie et les poids du modèle.
  • L'environnement utilisé pour enregistrer le modèle n'a pas d'impact sur les environnements pouvant charger le modèle. Enregistrer un modèle dans node.js n'empêche pas son chargement dans le navigateur.

Ci-dessous, nous examinerons les différents schémas disponibles.

Stockage local (navigateur uniquement)

Schéma : localstorage://

await model.save('localstorage://my-model');

Cela enregistre un modèle sous le nom my-model dans le stockage local du navigateur. Cela persistera entre les actualisations, bien que le stockage local puisse être effacé par les utilisateurs ou le navigateur lui-même si l'espace devient un problème. Chaque navigateur définit également sa propre limite quant à la quantité de données pouvant être stockées dans le stockage local pour un domaine donné.

IndexedDB (navigateur uniquement)

Schéma : indexeddb://

await model.save('indexeddb://my-model');

Cela enregistre un modèle dans le stockage IndexedDB du navigateur. Comme le stockage local, il persiste entre les actualisations, mais il a également tendance à avoir des limites plus grandes quant à la taille des objets stockés.

Téléchargements de fichiers (navigateur uniquement)

Schéma : downloads://

await model.save('downloads://my-model');

Le navigateur téléchargera alors les fichiers de modèle sur la machine de l'utilisateur. Deux fichiers seront produits :

  1. Un fichier texte JSON nommé [my-model].json , qui contient la topologie et la référence au fichier de pondérations décrit ci-dessous.
  2. Un fichier binaire contenant les valeurs de poids nommé [my-model].weights.bin .

Vous pouvez modifier le nom [my-model] pour obtenir des fichiers portant un nom différent.

Étant donné que le fichier .json pointe vers le .bin à l'aide d'un chemin relatif, les deux fichiers doivent se trouver dans le même dossier.

Requête HTTP(S)

Schéma : http:// ou https://

await model.save('http://model-server.domain/upload')

Cela créera une requête Web pour enregistrer un modèle sur un serveur distant. Vous devez contrôler ce serveur distant afin de pouvoir vous assurer qu'il est capable de traiter la demande.

Le modèle sera envoyé au serveur HTTP spécifié via une requête POST . Le corps du POST est au format multipart/form-data et se compose de deux fichiers

  1. Un fichier texte JSON nommé model.json , qui contient la topologie et la référence au fichier de pondérations décrit ci-dessous.
  2. Un fichier binaire contenant les valeurs de poids nommé model.weights.bin .

Notez que le nom des deux fichiers sera toujours exactement comme spécifié ci-dessus (le nom est intégré à la fonction). Ce document API contient un extrait de code Python qui montre comment utiliser le framework Web Flask pour gérer la requête provenant de save .

Souvent, vous devrez transmettre plus d'arguments ou d'en-têtes de requête à votre serveur HTTP (par exemple pour l'authentification ou si vous souhaitez spécifier un dossier dans lequel le modèle doit être enregistré). Vous pouvez obtenir un contrôle précis sur ces aspects des requêtes à partir de save en remplaçant l'argument de chaîne d'URL dans tf.io.browserHTTPRequest . Cette API offre une plus grande flexibilité dans le contrôle des requêtes HTTP.

Par exemple:

await model.save(tf.io.browserHTTPRequest(
    'http://model-server.domain/upload',
    {method: 'PUT', headers: {'header_key_1': 'header_value_1'} }));

Système de fichiers natif (Node.js uniquement)

Schéma : file://

await model.save('file:///path/to/my-model');

Lorsque nous exécutons sur Node.js, nous avons également un accès direct au système de fichiers et pouvons y enregistrer des modèles. La commande ci-dessus enregistrera deux fichiers dans le path spécifié après le scheme .

  1. Un fichier texte JSON nommé [model].json , qui contient la topologie et la référence au fichier de pondérations décrit ci-dessous.
  2. Un fichier binaire contenant les valeurs de poids nommé [model].weights.bin .

Notez que le nom des deux fichiers sera toujours exactement comme spécifié ci-dessus (le nom est intégré à la fonction).

Chargement d'un tf.Model

Étant donné un modèle enregistré à l'aide de l'une des méthodes ci-dessus, nous pouvons le charger à l'aide de l'API tf.loadLayersModel .

Voyons à quoi ressemble le code de chargement d'un modèle

const model = await tf.loadLayersModel('localstorage://my-model-1');

Quelques points à noter :

  • Comme model.save() , la fonction loadLayersModel prend un argument de chaîne de type URL qui commence par un schéma . Ceci décrit le type de destination à partir de laquelle nous essayons de charger un modèle.
  • Le schéma est suivi d'un chemin . Dans l'exemple ci-dessus, le chemin est my-model-1 .
  • La chaîne de type URL peut être remplacée par un objet qui correspond à l'interface IOHandler.
  • La fonction tf.loadLayersModel() est asynchrone.
  • La valeur de retour de tf.loadLayersModel est tf.Model

Ci-dessous, nous examinerons les différents schémas disponibles.

Stockage local (navigateur uniquement)

Schéma : localstorage://

const model = await tf.loadLayersModel('localstorage://my-model');

Cela charge un modèle nommé my-model à partir du stockage local du navigateur.

IndexedDB (navigateur uniquement)

Schéma : indexeddb://

const model = await tf.loadLayersModel('indexeddb://my-model');

Cela charge un modèle à partir du stockage IndexedDB du navigateur.

HTTP(S)

Schéma : http:// ou https://

const model = await tf.loadLayersModel('http://model-server.domain/download/model.json');

Cela charge un modèle à partir d'un point de terminaison http. Après avoir chargé le fichier json , la fonction effectuera des requêtes pour les fichiers .bin correspondants auxquels le fichier json fait référence.

Système de fichiers natif (Node.js uniquement)

Schéma : file://

const model = await tf.loadLayersModel('file://path/to/my-model/model.json');

Lorsque nous exécutons Node.js, nous avons également un accès direct au système de fichiers et pouvons charger des modèles à partir de là. Notez que dans l'appel de fonction ci-dessus, nous référençons le fichier model.json lui-même (alors que lors de l'enregistrement, nous spécifions un dossier). Le(s) fichier(s) .bin correspondant doivent se trouver dans le même dossier que le fichier json .

Chargement de modèles avec IOHandlers

Si les schémas ci-dessus ne suffisent pas à vos besoins, vous pouvez implémenter un comportement de chargement personnalisé avec un IOHandler . Un IOHandler fourni par TensorFlow.js est tf.io.browserFiles qui permet aux utilisateurs du navigateur de télécharger des fichiers de modèle dans le navigateur. Consultez la documentation pour plus d'informations.

Enregistrement et chargement de modèles avec des IOHandlers personnalisés

Si les schémas ci-dessus ne suffisent pas à vos besoins de chargement ou de sauvegarde, vous pouvez implémenter un comportement de sérialisation personnalisé en implémentant un IOHandler .

Un IOHandler est un objet avec une méthode save et load .

La fonction save prend un paramètre qui correspond à l'interface ModelArtifacts et doit renvoyer une promesse qui se résout en un objet SaveResult .

La fonction load ne prend aucun paramètre et doit renvoyer une promesse qui se résout en un objet ModelArtifacts . C'est le même objet qui est passé à save .

Voir BrowserHTTPRequest pour un exemple de comment implémenter un IOHandler.