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

Guide complet de regroupement de poids

Voir sur TensorFlow.org Exécuter dans Google Colab Afficher la source sur GitHub Télécharger le cahier

Bienvenue dans le guide complet pour la classification des poids , qui fait partie de la boîte à outils d'optimisation de modèle TensorFlow.

Cette page documente divers cas d'utilisation et montre comment utiliser l'API pour chacun d'eux. Une fois que vous savez de quelles API vous avez besoin, recherchez les paramètres et les détails de bas niveau dans la documentation de l' API :

Dans ce guide, les cas d'utilisation suivants sont traités:

  • Définissez un modèle en cluster.
  • Vérifiez et désérialisez un modèle en cluster.
  • Améliorez la précision du modèle en cluster.
  • Pour le déploiement uniquement, vous devez prendre des mesures pour voir les avantages de la compression.

Installer

 ! pip install -q tensorflow-model-optimization

import tensorflow as tf
import numpy as np
import tempfile
import os
import tensorflow_model_optimization as tfmot

input_dim = 20
output_dim = 20
x_train = np.random.randn(1, input_dim).astype(np.float32)
y_train = tf.keras.utils.to_categorical(np.random.randn(1), num_classes=output_dim)

def setup_model():
  model = tf.keras.Sequential([
      tf.keras.layers.Dense(input_dim, input_shape=[input_dim]),
      tf.keras.layers.Flatten()
  ])
  return model

def train_model(model):
  model.compile(
      loss=tf.keras.losses.categorical_crossentropy,
      optimizer='adam',
      metrics=['accuracy']
  )
  model.summary()
  model.fit(x_train, y_train)
  return model

def save_model_weights(model):
  _, pretrained_weights = tempfile.mkstemp('.h5')
  model.save_weights(pretrained_weights)
  return pretrained_weights

def setup_pretrained_weights():
  model= setup_model()
  model = train_model(model)
  pretrained_weights = save_model_weights(model)
  return pretrained_weights

def setup_pretrained_model():
  model = setup_model()
  pretrained_weights = setup_pretrained_weights()
  model.load_weights(pretrained_weights)
  return model

def save_model_file(model):
  _, keras_file = tempfile.mkstemp('.h5') 
  model.save(keras_file, include_optimizer=False)
  return keras_file

def get_gzipped_model_size(model):
  # It returns the size of the gzipped model in bytes.
  import os
  import zipfile

  keras_file = save_model_file(model)

  _, zipped_file = tempfile.mkstemp('.zip')
  with zipfile.ZipFile(zipped_file, 'w', compression=zipfile.ZIP_DEFLATED) as f:
    f.write(keras_file)
  return os.path.getsize(zipped_file)

setup_model()
pretrained_weights = setup_pretrained_weights()
 
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 20)                420       
_________________________________________________________________
flatten_1 (Flatten)          (None, 20)                0         
=================================================================
Total params: 420
Trainable params: 420
Non-trainable params: 0
_________________________________________________________________
1/1 [==============================] - 0s 1ms/step - loss: 1.3192 - accuracy: 0.0000e+00

Définir un modèle en cluster

Regrouper tout un modèle (séquentiel et fonctionnel)

Conseils pour une meilleure précision du modèle:

  • Vous devez transmettre un modèle pré-entraîné avec une précision acceptable à cette API. La formation des modèles à partir de zéro avec le regroupement donne une précision inférieure à la moyenne.
  • Dans certains cas, le regroupement de certaines couches a un effet néfaste sur la précision du modèle. Cochez "Regrouper certaines couches" pour savoir comment ignorer le regroupement des couches qui affectent le plus la précision.

Pour regrouper toutes les couches, appliquez tfmot.clustering.keras.cluster_weights au modèle.

 import tensorflow_model_optimization as tfmot

cluster_weights = tfmot.clustering.keras.cluster_weights
CentroidInitialization = tfmot.clustering.keras.CentroidInitialization

clustering_params = {
  'number_of_clusters': 3,
  'cluster_centroids_init': CentroidInitialization.DENSITY_BASED
}

model = setup_model()
model.load_weights(pretrained_weights)

clustered_model = cluster_weights(model, **clustering_params)

clustered_model.summary()
 
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_2 (ClusterWeig (None, 20)                423       
_________________________________________________________________
cluster_flatten_2 (ClusterWe (None, 20)                0         
=================================================================
Total params: 423
Trainable params: 23
Non-trainable params: 400
_________________________________________________________________

Regrouper certaines couches (modèles séquentiels et fonctionnels)

Conseils pour une meilleure précision du modèle:

  • Vous devez transmettre un modèle pré-entraîné avec une précision acceptable à cette API. La formation des modèles à partir de zéro avec le regroupement donne une précision inférieure à la moyenne.
  • Regroupez les couches ultérieures avec des paramètres plus redondants (par exemple tf.keras.layers.Dense , tf.keras.layers.Conv2D ), par opposition aux premières couches.
  • Gelez les premières couches avant les couches groupées lors de la mise au point. Traitez le nombre de couches gelées comme un hyperparamètre. Empiriquement, le gel de la plupart des premières couches est idéal pour l'API de clustering actuelle.
  • Évitez de regrouper les couches critiques (par exemple, mécanisme d'attention).

Plus : la tfmot.clustering.keras.cluster_weights API tfmot.clustering.keras.cluster_weights fournit des détails sur la façon de faire varier la configuration de clustering par couche.

 # Create a base model
base_model = setup_model()
base_model.load_weights(pretrained_weights)

# Helper function uses `cluster_weights` to make only 
# the Dense layers train with clustering
def apply_clustering_to_dense(layer):
  if isinstance(layer, tf.keras.layers.Dense):
    return cluster_weights(layer, **clustering_params)
  return layer

# Use `tf.keras.models.clone_model` to apply `apply_clustering_to_dense` 
# to the layers of the model.
clustered_model = tf.keras.models.clone_model(
    base_model,
    clone_function=apply_clustering_to_dense,
)

clustered_model.summary()
 
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_3 (ClusterWeig (None, 20)                423       
_________________________________________________________________
flatten_3 (Flatten)          (None, 20)                0         
=================================================================
Total params: 423
Trainable params: 23
Non-trainable params: 400
_________________________________________________________________

Vérifier et désérialiser un modèle en cluster

Votre cas d'utilisation: ce code n'est nécessaire que pour le format du modèle HDF5 (pas les poids HDF5 ou d'autres formats).

 # Define the model.
base_model = setup_model()
base_model.load_weights(pretrained_weights)
clustered_model = cluster_weights(base_model, **clustering_params)

# Save or checkpoint the model.
_, keras_model_file = tempfile.mkstemp('.h5')
clustered_model.save(keras_model_file, include_optimizer=True)

# `cluster_scope` is needed for deserializing HDF5 models.
with tfmot.clustering.keras.cluster_scope():
  loaded_model = tf.keras.models.load_model(keras_model_file)

loaded_model.summary()
 
WARNING:tensorflow:No training configuration found in the save file, so the model was *not* compiled. Compile it manually.
Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_4 (ClusterWeig (None, 20)                423       
_________________________________________________________________
cluster_flatten_4 (ClusterWe (None, 20)                0         
=================================================================
Total params: 423
Trainable params: 23
Non-trainable params: 400
_________________________________________________________________

Améliorez la précision du modèle en cluster

Pour votre cas d'utilisation spécifique, vous pouvez prendre en compte des conseils:

  • L'initialisation du centre de gravité joue un rôle clé dans la précision finale du modèle optimisé. En général, l'initialisation linéaire surpasse la densité et l'initialisation aléatoire car elle n'a pas tendance à manquer de gros poids. Cependant, on a observé que l'initialisation de la densité donne une meilleure précision dans le cas de l'utilisation de très peu de grappes sur des poids avec des distributions bimodales.

  • Définissez un taux d'apprentissage inférieur à celui utilisé lors de la formation lors du réglage fin du modèle en cluster.

  • Pour obtenir des idées générales pour améliorer la précision du modèle, recherchez des astuces pour vos cas d'utilisation sous «Définir un modèle en cluster».

Déploiement

Modèle d'exportation avec compression de taille

Erreur courante : à la fois strip_clustering et l'application d'un algorithme de compression standard (par exemple via gzip) sont nécessaires pour voir les avantages de compression du clustering.

 model = setup_model()
clustered_model = cluster_weights(model, **clustering_params)

clustered_model.compile(
    loss=tf.keras.losses.categorical_crossentropy,
    optimizer='adam',
    metrics=['accuracy']
)

clustered_model.fit(
    x_train,
    y_train
)

final_model = tfmot.clustering.keras.strip_clustering(clustered_model)

print("final model")
final_model.summary()

print("\n")
print("Size of gzipped clustered model without stripping: %.2f bytes" 
      % (get_gzipped_model_size(clustered_model)))
print("Size of gzipped clustered model with stripping: %.2f bytes" 
      % (get_gzipped_model_size(final_model)))
 
1/1 [==============================] - 0s 1ms/step - loss: 2.2136 - accuracy: 0.0000e+00
final model
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 20)                420       
_________________________________________________________________
flatten_5 (Flatten)          (None, 20)                0         
=================================================================
Total params: 420
Trainable params: 420
Non-trainable params: 0
_________________________________________________________________


Size of gzipped clustered model without stripping: 1822.00 bytes
Size of gzipped clustered model with stripping: 1408.00 bytes