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

Modèles et couches

Dans l'apprentissage automatique, un modèle est une fonction avec des paramètres apprenables qui mappe une entrée à une sortie. Les paramètres optimaux sont obtenus en entraînant le modèle sur des données. Un modèle bien formé fournira une cartographie précise de l'entrée à la sortie souhaitée.

Dans TensorFlow.js, il existe deux façons de créer un modèle d'apprentissage automatique:

  1. en utilisant l'API Layers où vous créez un modèle à l'aide de couches .
  2. en utilisant l'API Core avec des opérations de niveau inférieur telles que tf.matMul() , tf.add() , etc.

Tout d'abord, nous examinerons l'API Layers, qui est une API de niveau supérieur pour la création de modèles. Ensuite, nous montrerons comment créer le même modèle à l'aide de l'API Core.

Création de modèles avec l'API Layers

Il existe deux façons de créer un modèle à l'aide de l'API Layers: un modèle séquentiel et un modèle fonctionnel . Les deux sections suivantes examinent chaque type de plus près.

Le modèle séquentiel

Le type de modèle le plus courant est le modèle Sequential , qui est une pile linéaire de couches. Vous pouvez créer un modèle Sequential en passant une liste de couches à la fonction sequential() :

const model = tf.sequential({
 layers: [
   tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
   tf.layers.dense({units: 10, activation: 'softmax'}),
 ]
});

Ou via la méthode add() :

const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));

IMPORTANT: la première couche du modèle nécessite une forme d' inputShape . Assurez-vous d'exclure la taille du lot lors de la fourniture de inputShape . Par exemple, si vous prévoyez d'alimenter les tenseurs de modèle de forme [B, 784] , où B peut être n'importe quelle taille de lot, spécifiez inputShape comme [784] lors de la création du modèle.

Vous pouvez accéder aux couches du modèle via model.layers , et plus précisément model.inputLayers et model.outputLayers .

Le modèle fonctionnel

Une autre façon de créer un LayersModel consiste à tf.model() fonction tf.model() . La principale différence entre tf.model() et tf.sequential() est que tf.model() vous permet de créer un graphe arbitraire de couches, tant qu'elles n'ont pas de cycles.

Voici un extrait de code qui définit le même modèle que ci-dessus en utilisant l'API tf.model() :

// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});

Nous appelons apply() sur chaque couche afin de la connecter à la sortie d'une autre couche. Le résultat de apply() dans ce cas est un SymbolicTensor , qui agit comme un Tensor mais sans aucune valeur concrète.

Notez que contrairement au modèle séquentiel, nous créons un SymbolicTensor via tf.input() au lieu de fournir un inputShape à la première couche.

apply() peut également vous donner un Tensor concret, si vous lui passez un Tensor concret:

const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]

Cela peut être utile lors du test des couches isolées et de la visualisation de leur sortie.

Tout comme dans un modèle séquentiel, vous pouvez accéder aux couches du modèle via model.layers , et plus précisément model.inputLayers et model.outputLayers .

Validation

Le modèle séquentiel et le modèle fonctionnel sont des instances de la classe LayersModel . L'un des principaux avantages de travailler avec un LayersModel est la validation: elle vous oblige à spécifier la forme d'entrée et l'utilisera plus tard pour valider votre entrée. Le LayersModel également une inférence de forme automatique lorsque les données circulent à travers les couches. Connaître la forme à l'avance permet au modèle de créer automatiquement ses paramètres et peut vous dire si deux couches consécutives ne sont pas compatibles l'une avec l'autre.

Résumé du modèle

Appelez model.summary() pour imprimer un résumé utile du modèle, qui comprend:

  • Nom et type de toutes les couches du modèle.
  • Forme de sortie pour chaque couche.
  • Nombre de paramètres de poids de chaque couche.
  • Si le modèle a une topologie générale (décrite ci-dessous), les entrées que chaque couche reçoit
  • Le nombre total de paramètres entraînables et non entraînables du modèle.

Pour le modèle que nous avons défini ci-dessus, nous obtenons la sortie suivante sur la console:

Calque (type) Forme de sortie Param #
dense_Dense1 (dense) [nul, 32] 25120
dense_Dense2 (dense) [null, 10] 330
Paramètres totaux: 25450
Paramètres entraînables: 25450
Paramètres non entraînables: 0

Notez les valeurs null dans les formes de sortie des calques: un rappel que le modèle s'attend à ce que l'entrée ait une taille de lot comme dimension la plus externe, ce qui dans ce cas peut être flexible en raison de la valeur null .

Sérialisation

L'un des principaux avantages de l'utilisation d'un LayersModel rapport à l'API de niveau inférieur est la possibilité d'enregistrer et de charger un modèle. Un LayersModel connaît:

  • l'architecture du modèle, vous permettant de recréer le modèle.
  • les poids du modèle
  • la configuration de la formation (perte, optimiseur, métriques).
  • l'état de l'optimiseur, vous permettant de reprendre l'entraînement.

Pour enregistrer ou charger un modèle, il suffit d'une ligne de code:

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

L'exemple ci-dessus enregistre le modèle dans le stockage local dans le navigateur. Consultez la model.save() documentation et le guide de sauvegarde et de chargement pour savoir comment enregistrer sur différents supports (par exemple, stockage de fichiers, IndexedDB , déclencher un téléchargement de navigateur, etc.)

Calques personnalisés

Les calques sont les éléments constitutifs d'un modèle. Si votre modèle effectue un calcul personnalisé, vous pouvez définir une couche personnalisée, qui interagit bien avec le reste des couches. Ci-dessous, nous définissons une couche personnalisée qui calcule la somme des carrés:

class SquaredSumLayer extends tf.layers.Layer {
 constructor() {
   super({});
 }
 // In this case, the output is a scalar.
 computeOutputShape(inputShape) { return []; }

 // call() is where we do the computation.
 call(input, kwargs) { return input.square().sum();}

 // Every layer needs a unique name.
 getClassName() { return 'SquaredSum'; }
}

Pour le tester, nous pouvons appeler la méthode apply() avec un tenseur concret:

const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30

IMPORTANT: si vous ajoutez une couche personnalisée, vous perdez la possibilité de sérialiser un modèle.

Créer des modèles avec l'API Core

Au début de ce guide, nous avons mentionné qu'il existe deux façons de créer un modèle d'apprentissage automatique dans TensorFlow.js.

La règle générale est de toujours essayer d'utiliser l'API Layers en premier, car elle est modelée sur l'API Keras bien adoptée qui suit les meilleures pratiques et réduit la charge cognitive . L'API Layers propose également diverses solutions prêtes à l'emploi telles que l'initialisation du poids, la sérialisation du modèle, la formation au suivi, la portabilité et le contrôle de sécurité.

Vous souhaiterez peut-être utiliser l'API Core chaque fois que:

  • Vous avez besoin d'un maximum de flexibilité ou de contrôle.
  • Vous n'avez pas besoin de sérialisation ou pouvez implémenter votre propre logique de sérialisation.

Les modèles de l'API Core ne sont que des fonctions qui prennent un ou plusieurs Tensors et renvoient un Tensor . Le même modèle que ci-dessus écrit à l'aide de l'API Core ressemble à ceci:

// The weights and biases for the two dense layers.
const w1 = tf.variable(tf.randomNormal([784, 32]));
const b1 = tf.variable(tf.randomNormal([32]));
const w2 = tf.variable(tf.randomNormal([32, 10]));
const b2 = tf.variable(tf.randomNormal([10]));

function model(x) {
  return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
}

Notez que dans l'API Core, nous sommes responsables de la création et de l'initialisation des poids du modèle. Chaque poids est soutenu par une Variable qui signale à TensorFlow.js que ces tenseurs sont apprenables. Vous pouvez créer une Variable utilisant tf.variable () et en passant un Tensor existant.

Dans ce guide, vous vous êtes familiarisé avec les différentes façons de créer un modèle à l'aide des couches et de l'API principale. Ensuite, consultez le guide des modèles de formation pour savoir comment entraîner un modèle.