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

API de couches TensorFlow.js pour les utilisateurs Keras

L'API Layers de TensorFlow.js est calquée sur Keras et nous nous efforçons de rendre l' API Layers aussi similaire à Keras que raisonnable étant donné les différences entre JavaScript et Python. Cela permet aux utilisateurs ayant l'expérience du développement de modèles Keras en Python de migrer plus facilement vers les couches TensorFlow.js en JavaScript. Par exemple, le code Keras suivant se traduit en JavaScript:

# Python:
import keras
import numpy as np

# Build and compile model.
model = keras.Sequential()
model.add(keras.layers.Dense(units=1, input_shape=[1]))
model.compile(optimizer='sgd', loss='mean_squared_error')

# Generate some synthetic data for training.
xs = np.array([[1], [2], [3], [4]])
ys = np.array([[1], [3], [5], [7]])

# Train model with fit().
model.fit(xs, ys, epochs=1000)

# Run inference with predict().
print(model.predict(np.array([[5]])))
// JavaScript:
import * as tf from '@tensorlowjs/tfjs';

// Build and compile model.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

// Generate some synthetic data for training.
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);
const ys = tf.tensor2d([[1], [3], [5], [7]], [4, 1]);

// Train model with fit().
await model.fit(xs, ys, {epochs: 1000});

// Run inference with predict().
model.predict(tf.tensor2d([[5]], [1, 1])).print();

Cependant, il y a certaines différences que nous aimerions souligner et expliquer dans ce document. Une fois que vous avez compris ces différences et la justification de celles-ci, votre migration Python vers JavaScript (ou migration dans le sens inverse) devrait être une expérience relativement fluide.

Les constructeurs prennent les objets JavaScript comme configurations

Comparez les lignes Python et JavaScript suivantes de l'exemple ci-dessus: elles créent toutes deux une couche dense .

# Python:
keras.layers.Dense(units=1, inputShape=[1])
// JavaScript:
tf.layers.dense({units: 1, inputShape: [1]});

Les fonctions JavaScript n'ont pas d'équivalent des arguments de mot-clé dans les fonctions Python. Nous voulons éviter d'implémenter des options de constructeur comme arguments de position dans JavaScript, ce qui serait particulièrement fastidieux à retenir et à utiliser pour les constructeurs avec un grand nombre d'arguments de mots-clés (par exemple, LSTM ). C'est pourquoi nous utilisons des objets de configuration JavaScript. Ces objets offrent le même niveau d'invariance de position et de flexibilité que les arguments de mots clés Python.

Certaines méthodes de la classe Model, par exemple, Model.compile() , prennent également un objet de configuration JavaScript comme entrée. Cependant, gardez à l'esprit que Model.fit() , Model.evaluate() et Model.predict() sont légèrement différents. Puisque ces méthodes prennent les données obligatoires x (caractéristiques) et y (étiquettes ou cibles) comme entrées; x et y sont des arguments positionnels séparés de l'objet de configuration qui en résulte qui joue le rôle des arguments de mot-clé. Par exemple:

// JavaScript:
await model.fit(xs, ys, {epochs: 1000});

Model.fit () est asynchrone

Model.fit() est la principale méthode avec laquelle les utilisateurs effectuent la formation de modèle dans TensorFlow.js. Cette méthode peut souvent être longue et durer quelques secondes ou minutes. Par conséquent, nous utilisons la fonctionnalité async du langage JavaScript, afin que cette fonction puisse être utilisée de manière à ne pas bloquer le thread d'interface utilisateur principal lors de l'exécution dans le navigateur. Ceci est similaire à d'autres fonctions potentiellement de longue durée en JavaScript, telles que l' extraction async . Notez que async est une construction qui n'existe pas en Python. Alors que la méthode fit() de Keras retourne un objet History, la contrepartie de la méthode fit() en JavaScript renvoie une Promise of History, qui peut être attendue (comme dans l'exemple ci-dessus) ou utilisée avec la méthode then ().

Pas de NumPy pour TensorFlow.js

Les utilisateurs de Python Keras utilisent souvent NumPy pour effectuer des opérations numériques et matricielles de base, telles que la génération de tenseurs 2D dans l'exemple ci-dessus.

# Python:
xs = np.array([[1], [2], [3], [4]])

Dans TensorFlow.js, ce type d'opérations numériques de base est effectué avec le package lui-même. Par exemple:

// JavaScript:
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);

L'espace de noms tf.* Fournit également un certain nombre d'autres fonctions pour les opérations de tableau et d'algèbre linéaire telles que la multiplication matricielle. Consultez la documentation TensorFlow.js Core pour plus d'informations.

Utilisez des méthodes d'usine, pas des constructeurs

Cette ligne en Python (de l'exemple ci-dessus) est un appel au constructeur:

# Python:
model = keras.Sequential()

S'il était traduit strictement en JavaScript, l'appel de constructeur équivalent ressemblerait à ceci:

// JavaScript:
const model = new tf.Sequential();  // !!! DON'T DO THIS !!!

Cependant, nous avons décidé de ne pas utiliser les «nouveaux» constructeurs car 1) le mot clé «new» rendrait le code plus gonflé et 2) le «nouveau» constructeur est considéré comme une «mauvaise partie» de JavaScript: un écueil potentiel, car est argumenté en JavaScript: les bonnes parties . Pour créer des modèles et des couches dans TensorFlow.js, vous appelez des méthodes de fabrique, qui ont des noms inférieursCamelCase, par exemple:

// JavaScript:
const model = tf.sequential();

const layer = tf.layers.batchNormalization({axis: 1});

Les valeurs de chaîne d'option sont lowerCamelCase, pas snake_case

En JavaScript, il est plus courant d'utiliser la casse camel pour les noms de symboles (par exemple, voir le guide de style JavaScript de Google ), par rapport à Python, où la casse serpent est courante (par exemple, dans Keras). En tant que tel, nous avons décidé d'utiliser lowerCamelCase pour les valeurs de chaîne pour les options comprenant les suivantes:

  • DataFormat, par exemple, channelsFirst au lieu de channels_first
  • Initialiseur, par exemple, glorotNormal au lieu de glorot_normal
  • Perte et métriques, par exemple, meanSquaredError au lieu de mean_squared_error , categoricalCrossentropy au lieu de categorical_crossentropy .

Par exemple, comme dans l'exemple ci-dessus:

// JavaScript:
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

En ce qui concerne la sérialisation et la désérialisation des modèles, soyez rassurés. Le mécanisme interne de TensorFlow.js garantit que les cas de serpent dans les objets JSON sont gérés correctement, par exemple, lors du chargement de modèles pré-entraînés à partir de Python Keras.

Exécutez les objets Layer avec apply (), pas en les appelant comme des fonctions

Dans Keras, un objet Layer a la méthode __call__ définie. Par conséquent, l'utilisateur peut invoquer la logique de la couche en appelant l'objet en tant que fonction, par exemple,

# Python:
my_input = keras.Input(shape=[2, 4])
flatten = keras.layers.Flatten()

print(flatten(my_input).shape)

Ce sucre de syntaxe Python est implémenté en tant que méthode apply () dans TensorFlow.js:

// JavaScript:
const myInput = tf.input({shape: [2, 4]});
const flatten = tf.layers.flatten();

console.log(flatten.apply(myInput).shape);

Layer.apply () prend en charge l'évaluation impérative (impatiente) sur les tenseurs concrets

Actuellement, dans Keras, la méthode d' appel ne peut fonctionner que sur les objets tf.Tensor (Python) de TensorFlow (en supposant le backend TensorFlow), qui sont symboliques et ne contiennent pas de valeurs numériques réelles. C'est ce qui est montré dans l'exemple de la section précédente. Cependant, dans TensorFlow.js, la méthode apply () des couches peut fonctionner à la fois en modes symbolique et impératif. Si apply() est appelé avec un SymbolicTensor (une analogie proche de tf.Tensor), la valeur de retour sera un SymbolicTensor. Cela se produit généralement lors de la création du modèle. Mais si apply() est invoqué avec une valeur Tensor concrète réelle, il retournera un Tensor concret. Par exemple:

// JavaScript:
const flatten = tf.layers.flatten();

flatten.apply(tf.ones([2, 3, 4])).print();

Cette fonctionnalité rappelle Eager Execution de (Python) TensorFlow. Il offre une plus grande interactivité et une meilleure capacité de débogage pendant le développement du modèle, en plus d'ouvrir les portes à la composition de réseaux neuronaux dynamiques.

Les optimiseurs sont en cours. , pas des optimiseurs.

Dans Keras, les constructeurs des objets Optimizer se trouvent sous l'espace de noms keras.optimizers.* . Dans les couches TensorFlow.js, les méthodes de fabrique des optimiseurs se trouvent sous l'espace de noms tf.train.* . Par exemple:

# Python:
my_sgd = keras.optimizers.sgd(lr=0.2)
// JavaScript:
const mySGD = tf.train.sgd({lr: 0.2});

loadLayersModel () se charge à partir d'une URL, pas d'un fichier HDF5

Dans Keras, les modèles sont généralement enregistrés dans un fichier HDF5 (.h5), qui peut être chargé ultérieurement à l'aide de la méthode keras.models.load_model() . La méthode prend un chemin vers le fichier .h5. L'équivalent de load_model() dans TensorFlow.js est tf.loadLayersModel() . Comme HDF5 n'est pas un format de fichier convivial pour les navigateurs, tf.loadLayersModel() prend un format spécifique à TensorFlow.js. tf.loadLayersModel() prend un fichier model.json comme argument d'entrée. Le model.json peut être converti à partir d'un fichier Keras HDF5 à l'aide du package tensorflowjs pip.

// JavaScript:
const model = await tf.loadLayersModel('https://foo.bar/model.json');

Notez également que tf.loadLayersModel() renvoie une Promise de tf.Model .

En général, l'enregistrement et le chargement des tf.Model s dans TensorFlow.js se font à l'aide des méthodes tf.Model.save et tf.loadLayersModel , respectivement. Nous avons conçu ces API pour qu'elles soient similaires à l'API save et load_model de Keras. Mais l'environnement du navigateur est assez différent de l'environnement backend sur lequel s'exécutent les frameworks d'apprentissage en profondeur de base tels que Keras, en particulier dans le tableau des routes pour la persistance et la transmission de données. Il existe donc des différences intéressantes entre les API de sauvegarde / chargement de TensorFlow.js et de Keras. Consultez notre tutoriel sur la sauvegarde et le chargement de tf.Model pour plus de détails.

Utilisez fitDataset() pour former des modèles à l'aide d'objets tf.data.Dataset

Dans tf.keras de Python TensorFlow, un modèle peut être entraîné à l'aide d'un objet Dataset . La méthode fit() du modèle accepte directement un tel objet. Un modèle TensorFlow.js peut également être entraîné avec l'équivalent JavaScript des objets Dataset (voir la documentation de l'API tf.data dans TensorFlow.js ). Cependant, contrairement à Python, l'entraînement basé sur un ensemble de données est effectué via une méthode dédiée, à savoir fitDataset . La méthode fit () est uniquement destinée à l'entraînement de modèle basé sur des tenseurs.

Gestion de la mémoire des objets Layer et Model

TensorFlow.js s'exécute sur WebGL dans le navigateur, où les poids des objets Layer et Model sont soutenus par des textures WebGL. Cependant, WebGL n'a pas de prise en charge intégrée du garbage collection. Les objets Layer et Model gèrent en interne la mémoire tensorielle de l'utilisateur lors de ses appels d'inférence et d'apprentissage. Mais ils permettent également à l'utilisateur de les disposer afin de libérer la mémoire WebGL qu'ils occupent. Ceci est utile dans les cas où de nombreuses instances de modèle sont créées et publiées au cours d'un seul chargement de page. Pour supprimer un objet Layer ou Model, utilisez la méthode dispose() .