Eine Frage haben? Verbinden Sie sich mit der Community im TensorFlow Forum Visit Forum

Quantisierung des Dynamikbereichs nach dem Training

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Überblick

TensorFlow Lite unterstützt jetzt die Konvertierung von Gewichten in 8-Bit-Genauigkeit als Teil der Modellkonvertierung von Tensorflow-Grafikdefs in das flache Pufferformat von TensorFlow Lite. Durch die Quantifizierung des Dynamikbereichs wird die Modellgröße um das Vierfache reduziert. Darüber hinaus unterstützt TFLite die Quantisierung und Dequantisierung von Aktivierungen im laufenden Betrieb, um Folgendes zu ermöglichen:

  1. Verwendung quantisierter Kernel für eine schnellere Implementierung, sofern verfügbar.
  2. Mischen von Gleitkomma-Kerneln mit quantisierten Kerneln für verschiedene Teile des Graphen.

Die Aktivierungen werden immer im Gleitkomma gespeichert. Bei Operationen, die quantisierte Kernel unterstützen, werden die Aktivierungen vor der Verarbeitung dynamisch mit einer Genauigkeit von 8 Bit quantisiert und nach der Verarbeitung de-quantisiert, um die Float-Genauigkeit zu gewährleisten. Abhängig vom zu konvertierenden Modell kann dies zu einer Beschleunigung gegenüber der reinen Gleitkommaberechnung führen.

Im Gegensatz zum quantisierungsbewussten Training werden die Gewichte nach dem Training quantisiert und die Aktivierungen werden bei dieser Methode dynamisch bei Inferenz quantisiert. Daher werden die Modellgewichte nicht umgeschult, um quantisierungsinduzierte Fehler zu kompensieren. Es ist wichtig, die Genauigkeit des quantisierten Modells zu überprüfen, um sicherzustellen, dass die Verschlechterung akzeptabel ist.

In diesem Lernprogramm wird ein MNIST-Modell von Grund auf neu trainiert, seine Genauigkeit in TensorFlow überprüft und anschließend in einen Tensorflow Lite-Flatbuffer mit Quantisierung des Dynamikbereichs konvertiert. Schließlich wird die Genauigkeit des konvertierten Modells überprüft und mit dem ursprünglichen Float-Modell verglichen.

Erstellen Sie ein MNIST-Modell

Einrichten

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

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

Trainiere ein TensorFlow-Modell

# 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.2642 - accuracy: 0.9265 - val_loss: 0.1170 - val_accuracy: 0.9653
<tensorflow.python.keras.callbacks.History at 0x7fc6e9681110>

Da Sie das Modell beispielsweise nur für eine einzelne Epoche trainiert haben, wird es nur mit einer Genauigkeit von ~ 96% trainiert.

Konvertieren Sie in ein TensorFlow Lite-Modell

Mit dem Python TFLiteConverter können Sie das trainierte Modell jetzt in ein TensorFlow Lite-Modell konvertieren.

Laden Sie nun das Modell mit dem TFLiteConverter :

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

Schreiben Sie es in eine tflite-Datei:

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)
84552

Um das Modell beim Export zu quantisieren, setzen Sie das optimizations , um die Größe zu optimieren:

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/tmpxu3xzrre/assets
INFO:tensorflow:Assets written to: /tmp/tmpxu3xzrre/assets
23952

Beachten Sie, dass die resultierende Datei ungefähr 1/4 der Größe hat.

ls -lh {tflite_models_dir}
total 180K
-rw-rw-r-- 1 kbuilder kbuilder 83K May 15 11:15 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 24K May 15 11:15 mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder 25K May 15 11:12 mnist_model_quant_16x8.tflite
-rw-rw-r-- 1 kbuilder kbuilder 44K May 15 11:13 mnist_model_quant_f16.tflite

Führen Sie die TFLite-Modelle aus

Führen Sie das TensorFlow Lite-Modell mit dem Python TensorFlow Lite-Interpreter aus.

Laden Sie das Modell in einen Interpreter

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()

Testen Sie das Modell an einem Bild

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

Bewerten Sie die Modelle

# 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.9653

Wiederholen Sie die Auswertung des quantisierten Modells für den Dynamikbereich, um Folgendes zu erhalten:

print(evaluate_model(interpreter_quant))
0.9652

In diesem Beispiel weist das komprimierte Modell keinen Unterschied in der Genauigkeit auf.

Bestehendes Modell optimieren

Resnets mit Voraktivierungsschichten (Resnet-v2) werden häufig für Bildverarbeitungsanwendungen verwendet. Ein vorab trainiertes eingefrorenes Diagramm für resnet-v2-101 ist auf Tensorflow Hub verfügbar.

Sie können das eingefrorene Diagramm in einen TensorFLow Lite-Flatbuffer mit Quantisierung konvertieren, indem Sie:

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())
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: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.
INFO:tensorflow:Assets written to: /tmp/tmprbf7l1yu/assets
INFO:tensorflow:Assets written to: /tmp/tmprbf7l1yu/assets
178538036
# 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())
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: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.
INFO:tensorflow:Assets written to: /tmp/tmp369vu7_9/assets
INFO:tensorflow:Assets written to: /tmp/tmp369vu7_9/assets
46285552
ls -lh {tflite_models_dir}/*.tflite
-rw-rw-r-- 1 kbuilder kbuilder  83K May 15 11:15 /tmp/mnist_tflite_models/mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder  24K May 15 11:15 /tmp/mnist_tflite_models/mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder  25K May 15 11:12 /tmp/mnist_tflite_models/mnist_model_quant_16x8.tflite
-rw-rw-r-- 1 kbuilder kbuilder  44K May 15 11:13 /tmp/mnist_tflite_models/mnist_model_quant_f16.tflite
-rw-rw-r-- 1 kbuilder kbuilder 171M May 15 11:15 /tmp/mnist_tflite_models/resnet_v2_101.tflite
-rw-rw-r-- 1 kbuilder kbuilder  45M May 15 11:16 /tmp/mnist_tflite_models/resnet_v2_101_quantized.tflite

Die Modellgröße reduziert sich von 171 MB auf 43 MB. Die Genauigkeit dieses Modells im Imagenet kann mithilfe der für die TFLite-Genauigkeitsmessung bereitgestellten Skripte bewertet werden.

Die Top-1-Genauigkeit des optimierten Modells beträgt 76,8, genau wie beim Gleitkommamodell.