RSVP pour votre événement TensorFlow Everywhere local dès aujourd'hui!
Cette page a été traduite par l'API Cloud Translation.
Switch to English

Quantification de la plage dynamique après l'entraînement

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

Aperçu

TensorFlow Lite prend désormais en charge la conversion des poids à une précision de 8 bits dans le cadre de la conversion de modèle des graphdefs tensorflow au format de tampon plat de TensorFlow Lite. La quantification de la plage dynamique permet une réduction de 4x de la taille du modèle. De plus, TFLite prend en charge la quantification et la déquantification à la volée des activations pour permettre:

  1. Utilisation de noyaux quantifiés pour une implémentation plus rapide lorsqu'ils sont disponibles.
  2. Mélange de noyaux à virgule flottante avec des noyaux quantifiés pour différentes parties du graphe.

Les activations sont toujours stockées en virgule flottante. Pour les opérations qui prennent en charge les noyaux quantifiés, les activations sont quantifiées dynamiquement à 8 bits de précision avant le traitement et sont dé-quantifiées à la précision flottante après le traitement. Selon le modèle converti, cela peut accélérer le calcul en virgule flottante pure.

Contrairement à l' entraînement conscient de la quantification , les poids sont quantifiés après l'entraînement et les activations sont quantifiées dynamiquement à l'inférence dans cette méthode. Par conséquent, les poids du modèle ne sont pas recyclés pour compenser les erreurs induites par la quantification. Il est important de vérifier l'exactitude du modèle quantifié pour s'assurer que la dégradation est acceptable.

Ce didacticiel entraîne un modèle MNIST à partir de zéro, vérifie sa précision dans TensorFlow, puis convertit le modèle en un tampon plat Tensorflow Lite avec quantification de la plage dynamique. Enfin, il vérifie la précision du modèle converti et le compare au modèle flottant d'origine.

Construire un modèle MNIST

Installer

import logging
logging.getLogger("tensorflow").setLevel(logging.DEBUG)

import tensorflow as tf
from tensorflow import keras
import numpy as np
import pathlib

Former un modèle TensorFlow

# Load MNIST dataset
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# Normalize the input image so that each pixel value is between 0 to 1.
train_images = train_images / 255.0
test_images = test_images / 255.0

# Define the model architecture
model = keras.Sequential([
  keras.layers.InputLayer(input_shape=(28, 28)),
  keras.layers.Reshape(target_shape=(28, 28, 1)),
  keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation=tf.nn.relu),
  keras.layers.MaxPooling2D(pool_size=(2, 2)),
  keras.layers.Flatten(),
  keras.layers.Dense(10)
])

# Train the digit classification model
model.compile(optimizer='adam',
              loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
model.fit(
  train_images,
  train_labels,
  epochs=1,
  validation_data=(test_images, test_labels)
)
1875/1875 [==============================] - 6s 2ms/step - loss: 0.5085 - accuracy: 0.8544 - val_loss: 0.1425 - val_accuracy: 0.9585

<tensorflow.python.keras.callbacks.History at 0x7fcc5b6bc5c0>

Pour l'exemple, puisque vous avez entraîné le modèle pour une seule époque, il ne s'entraîne qu'à une précision d'environ 96%.

Convertir en modèle TensorFlow Lite

À l'aide de Python TFLiteConverter , vous pouvez désormais convertir le modèle entraîné en modèle TensorFlow Lite.

TFLiteConverter maintenant le modèle à l'aide du TFLiteConverter :

converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
INFO:tensorflow:Assets written to: /tmp/tmpa03qi_6g/assets

Écrivez-le dans un fichier tflite:

tflite_models_dir = pathlib.Path("/tmp/mnist_tflite_models/")
tflite_models_dir.mkdir(exist_ok=True, parents=True)
tflite_model_file = tflite_models_dir/"mnist_model.tflite"
tflite_model_file.write_bytes(tflite_model)
84488

Pour quantifier le modèle à l' exportation, définir l' optimizations drapeau pour optimiser la taille:

converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_quant_model = converter.convert()
tflite_model_quant_file = tflite_models_dir/"mnist_model_quant.tflite"
tflite_model_quant_file.write_bytes(tflite_quant_model)
INFO:tensorflow:Assets written to: /tmp/tmpvnuvkuc_/assets

INFO:tensorflow:Assets written to: /tmp/tmpvnuvkuc_/assets

23888

Notez que le fichier résultant est d'environ 1/4 la taille.

ls -lh {tflite_models_dir}
total 152K
-rw-rw-r-- 1 kbuilder kbuilder 83K Dec 17 20:23 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 24K Dec 17 20:23 mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder 44K Dec 17 20:21 mnist_model_quant_f16.tflite

Exécutez les modèles TFLite

Exécutez le modèle TensorFlow Lite à l'aide de l'interpréteur Python TensorFlow Lite.

Charger le modèle dans un interpréteur

interpreter = tf.lite.Interpreter(model_path=str(tflite_model_file))
interpreter.allocate_tensors()
interpreter_quant = tf.lite.Interpreter(model_path=str(tflite_model_quant_file))
interpreter_quant.allocate_tensors()

Tester le modèle sur une image

test_image = np.expand_dims(test_images[0], axis=0).astype(np.float32)

input_index = interpreter.get_input_details()[0]["index"]
output_index = interpreter.get_output_details()[0]["index"]

interpreter.set_tensor(input_index, test_image)
interpreter.invoke()
predictions = interpreter.get_tensor(output_index)
import matplotlib.pylab as plt

plt.imshow(test_images[0])
template = "True:{true}, predicted:{predict}"
_ = plt.title(template.format(true= str(test_labels[0]),
                              predict=str(np.argmax(predictions[0]))))
plt.grid(False)

png

Évaluer les modèles

# A helper function to evaluate the TF Lite model using "test" dataset.
def evaluate_model(interpreter):
  input_index = interpreter.get_input_details()[0]["index"]
  output_index = interpreter.get_output_details()[0]["index"]

  # Run predictions on every image in the "test" dataset.
  prediction_digits = []
  for test_image in test_images:
    # Pre-processing: add batch dimension and convert to float32 to match with
    # the model's input data format.
    test_image = np.expand_dims(test_image, axis=0).astype(np.float32)
    interpreter.set_tensor(input_index, test_image)

    # Run inference.
    interpreter.invoke()

    # Post-processing: remove batch dimension and find the digit with highest
    # probability.
    output = interpreter.tensor(output_index)
    digit = np.argmax(output()[0])
    prediction_digits.append(digit)

  # Compare prediction results with ground truth labels to calculate accuracy.
  accurate_count = 0
  for index in range(len(prediction_digits)):
    if prediction_digits[index] == test_labels[index]:
      accurate_count += 1
  accuracy = accurate_count * 1.0 / len(prediction_digits)

  return accuracy
print(evaluate_model(interpreter))
0.9585

Répétez l'évaluation sur le modèle quantifié de plage dynamique pour obtenir:

print(evaluate_model(interpreter_quant))
0.9583

Dans cet exemple, le modèle compressé n'a aucune différence de précision.

Optimiser un modèle existant

Les réinitialisations avec des couches de pré-activation (Resnet-v2) sont largement utilisées pour les applications de vision. Le graphe figé pré-entraîné pour resnet-v2-101 est disponible sur Tensorflow Hub .

Vous pouvez convertir le graphique figé en un flatbuffer TensorFLow Lite avec quantification en:

import tensorflow_hub as hub

resnet_v2_101 = tf.keras.Sequential([
  keras.layers.InputLayer(input_shape=(224, 224, 3)),
  hub.KerasLayer("https://tfhub.dev/google/imagenet/resnet_v2_101/classification/4")
])

converter = tf.lite.TFLiteConverter.from_keras_model(resnet_v2_101)
# Convert to TF Lite without quantization
resnet_tflite_file = tflite_models_dir/"resnet_v2_101.tflite"
resnet_tflite_file.write_bytes(converter.convert())
INFO:tensorflow:Assets written to: /tmp/tmpsw6oxs4l/assets

INFO:tensorflow:Assets written to: /tmp/tmpsw6oxs4l/assets

178509356
# Convert to TF Lite with quantization
converter.optimizations = [tf.lite.Optimize.DEFAULT]
resnet_quantized_tflite_file = tflite_models_dir/"resnet_v2_101_quantized.tflite"
resnet_quantized_tflite_file.write_bytes(converter.convert())
INFO:tensorflow:Assets written to: /tmp/tmp714gxt1v/assets

INFO:tensorflow:Assets written to: /tmp/tmp714gxt1v/assets

46256896
ls -lh {tflite_models_dir}/*.tflite
-rw-rw-r-- 1 kbuilder kbuilder  83K Dec 17 20:23 /tmp/mnist_tflite_models/mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder  24K Dec 17 20:23 /tmp/mnist_tflite_models/mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder  44K Dec 17 20:21 /tmp/mnist_tflite_models/mnist_model_quant_f16.tflite
-rw-rw-r-- 1 kbuilder kbuilder 171M Dec 17 20:24 /tmp/mnist_tflite_models/resnet_v2_101.tflite
-rw-rw-r-- 1 kbuilder kbuilder  45M Dec 17 20:24 /tmp/mnist_tflite_models/resnet_v2_101_quantized.tflite

La taille du modèle passe de 171 Mo à 43 Mo. La précision de ce modèle sur imagenet peut être évaluée à l'aide des scripts fournis pour la mesure de la précision TFLite .

La précision optimisée du top 1 du modèle est de 76,8, identique à celle du modèle à virgule flottante.