Ajuda a proteger a Grande Barreira de Corais com TensorFlow em Kaggle Junte Desafio

Guia abrangente de clustering de peso

Ver no TensorFlow.org Executar no Google Colab Ver fonte no GitHub Baixar caderno

Bem-vindo ao guia completo para clustering de peso, que faz parte do kit de ferramentas TensorFlow modelo de otimização.

Esta página documenta vários casos de uso e mostra como usar a API para cada um. Depois de saber quais APIs você precisa, encontrar os parâmetros e os detalhes de baixo nível nos docs API :

Neste guia, os seguintes casos de uso são cobertos:

  • Defina um modelo em cluster.
  • Faça checkpoint e desserialize um modelo em cluster.
  • Melhore a precisão do modelo em cluster.
  • Apenas para implantação, você deve seguir etapas para ver os benefícios da compactação.

Configurar

! 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()
2021-08-31 11:04:26.070553: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected

Defina um modelo em cluster

Agrupe um modelo completo (sequencial e funcional)

Dicas para uma melhor precisão do modelo:

  • Você deve passar um modelo pré-treinado com precisão aceitável para esta API. Modelos de treinamento do zero com resultados de agrupamento em precisão abaixo da média.
  • Em alguns casos, o agrupamento de certas camadas tem um efeito prejudicial na precisão do modelo. Marque "Agrupar algumas camadas" para ver como ignorar o agrupamento das camadas que mais afetam a precisão.

Para agrupar todas as camadas, aplicar tfmot.clustering.keras.cluster_weights ao modelo.

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.KMEANS_PLUS_PLUS
}

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)                823       
_________________________________________________________________
cluster_flatten_2 (ClusterWe (None, 20)                0         
=================================================================
Total params: 823
Trainable params: 423
Non-trainable params: 400
_________________________________________________________________

Agrupe algumas camadas (modelos sequenciais e funcionais)

Dicas para uma melhor precisão do modelo:

  • Você deve passar um modelo pré-treinado com precisão aceitável para esta API. Modelos de treinamento do zero com resultados de agrupamento em precisão abaixo da média.
  • Cluster camadas posteriores com os parâmetros mais redundantes (por exemplo, tf.keras.layers.Dense , tf.keras.layers.Conv2D ), em oposição às primeiras camadas.
  • Congele as primeiras camadas antes das camadas agrupadas durante o ajuste fino. Trate o número de camadas congeladas como um hiperparâmetro. Empiricamente, congelar a maioria das camadas iniciais é ideal para a API de clustering atual.
  • Evite agrupar camadas críticas (por exemplo, mecanismo de atenção).

Mais: os tfmot.clustering.keras.cluster_weights API docs fornecem detalhes sobre como variar a configuração de cluster por camada.

# 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)                823       
_________________________________________________________________
flatten_3 (Flatten)          (None, 20)                0         
=================================================================
Total params: 823
Trainable params: 423
Non-trainable params: 400
_________________________________________________________________

Agrupe a camada Keras personalizada ou especifique quais espessuras de camada agrupar

tfmot.clustering.keras.ClusterableLayer serve dois casos de uso:

  1. Agrupe qualquer camada que não tenha suporte nativo, incluindo uma camada Keras personalizada.
  2. Especifique quais pesos de uma camada com suporte devem ser agrupados.

Por exemplo, os padrões de API a única aglomerando o núcleo do Dense camada. O exemplo abaixo mostra como modificá-lo para também agrupar o viés. Note que quando decorrentes da camada keras, você precisa substituir a função get_clusterable_weights , onde você especifica o nome da variável treinável a ser agrupados e da própria variável treinável. Por exemplo, se você retornar uma lista vazia [], nenhum peso será agrupável.

Erro comum: aglomerando o viés geralmente prejudica a precisão do modelo demais.

class MyDenseLayer(tf.keras.layers.Dense, tfmot.clustering.keras.ClusterableLayer):

  def get_clusterable_weights(self):
   # Cluster kernel and bias. This is just an example, clustering
   # bias usually hurts model accuracy.
   return [('kernel', self.kernel), ('bias', self.bias)]

# Use `cluster_weights` to make the `MyDenseLayer` layer train with clustering as usual.
model_for_clustering = tf.keras.Sequential([
  tfmot.clustering.keras.cluster_weights(MyDenseLayer(20, input_shape=[input_dim]), **clustering_params),
  tf.keras.layers.Flatten()
])

model_for_clustering.summary()
Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_my_dense_layer (Clus (None, 20)                846       
_________________________________________________________________
flatten_4 (Flatten)          (None, 20)                0         
=================================================================
Total params: 846
Trainable params: 426
Non-trainable params: 420
_________________________________________________________________

Você também pode usar tfmot.clustering.keras.ClusterableLayer a agrupar uma camada personalizada keras. Para fazer isso, você estender tf.keras.Layer como de costume e implementar o __init__ , call , e build funções, mas você também precisa estender a clusterable_layer.ClusterableLayer classe e implementar:

  1. get_clusterable_weights , onde você especificar o kernel peso a ser agrupados, como mostrado acima.
  2. get_clusterable_algorithm , onde você especificar o algoritmo de agrupamento para o tensor de peso. Isso ocorre porque você precisa especificar como os pesos da camada personalizada são moldados para agrupamento. A classe algoritmo de agrupamento devolvido deve ser derivado da clustering_algorithm.ClusteringAlgorithm classe e a função get_pulling_indices deve ser substituído. Um exemplo desta função, que suporta pesos de fileiras 1D, 2D e 3D, pode ser encontrada aqui .

Um exemplo deste caso de uso pode ser encontrada aqui .

Faça checkpoint e desserialize um modelo em cluster

Seu caso de uso: este código só é necessária para o efeito o modelo HDF5 (não HDF5 pesos ou outros formatos).

# 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:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
WARNING:tensorflow:No training configuration found in the save file, so the model was *not* compiled. Compile it manually.
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_4 (ClusterWeig (None, 20)                823       
_________________________________________________________________
cluster_flatten_5 (ClusterWe (None, 20)                0         
=================================================================
Total params: 823
Trainable params: 423
Non-trainable params: 400
_________________________________________________________________

Melhore a precisão do modelo em cluster

Para seu caso de uso específico, existem dicas que você pode considerar:

  • A inicialização do centróide desempenha um papel fundamental na precisão do modelo otimizado final. Em geral, a inicialização do kmeans ++ supera a inicialização linear, de densidade e aleatória. Ao não usar o kmeans ++, a inicialização linear tende a superar a densidade e a inicialização aleatória, uma vez que não tende a perder grandes pesos. No entanto, a inicialização da densidade foi observada para fornecer melhor precisão para o caso de usar muito poucos clusters em pesos com distribuições bimodais.

  • Defina uma taxa de aprendizado inferior à usada no treinamento ao ajustar o modelo em cluster.

  • Para obter ideias gerais para melhorar a precisão do modelo, procure dicas para seu (s) caso (s) de uso em "Definir um modelo em cluster".

Desdobramento, desenvolvimento

Exportar modelo com compressão de tamanho

Erro comum: ambos strip_clustering e aplicar um algoritmo de compressão padrão (por exemplo, através de gzip) são necessários para ver os benefícios de compressão de 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 343ms/step - loss: 16.1181 - accuracy: 0.0000e+00
final model
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 20)                420       
_________________________________________________________________
flatten_6 (Flatten)          (None, 20)                0         
=================================================================
Total params: 420
Trainable params: 420
Non-trainable params: 0
_________________________________________________________________


Size of gzipped clustered model without stripping: 3447.00 bytes
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
Size of gzipped clustered model with stripping: 1433.00 bytes