כימות טווח דינמי לאחר אימון

הצג באתר TensorFlow.org הפעל בגוגל קולאב צפה במקור ב-GitHub הורד מחברת ראה דגם TF Hub

סקירה כללית

TensorFlow לייט תומך כעת המרת משקולות כדי 8 ביט דיוק כחלק המרה מודל מ graphdefs tensorflow לפורמט חיץ שטוח של TensorFlow לייט. קוונטיזציה של טווח דינמי משיגה הפחתה פי 4 בגודל הדגם. בנוסף, TFLite תומך בכימות וביטול קוונטיזציה של הפעלות כדי לאפשר:

  1. שימוש בקרנלים כמותיים ליישום מהיר יותר כאשר זמין.
  2. ערבוב של גרעיני נקודה צפה עם גרעינים כמותיים עבור חלקים שונים של הגרף.

ההפעלות נשמרות תמיד בנקודה צפה. עבור אופציות התומכות בליעינים מכוונטיים, ההפעלות מקוימות ל-8 סיביות של דיוק באופן דינמי לפני העיבוד והן מבוטלות כדי לצוף דיוק לאחר העיבוד. בהתאם לדגם המומר, זה יכול להגביר מהירות על פני חישוב נקודה צפה טהורה.

בניגוד אימונים קוונטיזציה מודעים , את המשקולות הן אימונים בדידים פוסט ואת ההפעלות הם בדיד דינמי ממסקנה בשיטה זו. לכן, משקלי המודל אינם מאומנים מחדש כדי לפצות על שגיאות שנגרמו באמצעות קוונטיזציה. חשוב לבדוק את הדיוק של המודל המדויק כדי לוודא שההשפלה מקובלת.

מדריך זה מאמן מודל MNIST מאפס, בודק את הדיוק שלו ב-TensorFlow, ולאחר מכן ממיר את המודל למאגר Tensorflow Lite flatbuffer עם קוונטיזציה של טווח דינמי. לבסוף, הוא בודק את הדיוק של הדגם שהומר ומשווה אותו לדגם הצוף המקורי.

בנה מודל MNIST

להכין

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

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

אימון דגם 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.3260 - accuracy: 0.9063 - val_loss: 0.1721 - val_accuracy: 0.9499
<keras.callbacks.History at 0x7fb7a1c4ed90>

לדוגמא, מכיוון שאימנת את המודל רק לתקופה בודדת, אז הוא מתאמן רק ל-~96% דיוק.

המר לדגם TensorFlow Lite

בפייתון TFLiteConverter , מעתה ניתן להמיר את המודל מאומן למודל לייט TensorFlow.

עכשיו לטעון את המודל באמצעות TFLiteConverter :

converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
2021-11-02 11:23:32.211024: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmpua453ven/assets
2021-11-02 11:23:32.640259: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-11-02 11:23:32.640302: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.

כתוב את זה לקובץ 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)
84500

לקוואנטיזציה המודל על הייצוא, להגדיר את optimizations דגל לבצע אופטימיזציה עבור גודל:

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/tmpaw0wsb_y/assets
INFO:tensorflow:Assets written to: /tmp/tmpaw0wsb_y/assets
2021-11-02 11:23:33.235475: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-11-02 11:23:33.235512: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
23904

שים לב איך את הקובץ שנוצר, הוא כ 1/4 הגודל.

ls -lh {tflite_models_dir}
total 136K
-rw-rw-r-- 1 kbuilder kbuilder 83K Nov  2 11:23 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 24K Nov  2 11:23 mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder 25K Nov  2 11:20 mnist_model_quant_16x8.tflite

הפעל את דגמי TFLite

הפעל את מודל TensorFlow Lite באמצעות מתורגמן Python TensorFlow Lite.

טען את הדגם לתוך מתורגמן

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

בדוק את הדגם על תמונה אחת

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

העריכו את המודלים

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

חזור על ההערכה במודל הקוונטי של הטווח הדינמי כדי לקבל:

print(evaluate_model(interpreter_quant))
0.95

בדוגמה זו, למודל הדחוס אין הבדל ברמת הדיוק.

אופטימיזציה של דגם קיים

רשתות רשת עם שכבות קדם-הפעלה (Resnet-v2) נמצאות בשימוש נרחב עבור יישומי ראייה. טרום מאומן גרף קפוא במשך resnet-v2-101 נגיש Hub Tensorflow .

אתה יכול להמיר את הגרף הקפוא ל- TensorFLow Lite flatbuffer עם קוונטיזציה על ידי:

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/tmpxtji1amp/assets
INFO:tensorflow:Assets written to: /tmp/tmpxtji1amp/assets
2021-11-02 11:23:57.616139: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-11-02 11:23:57.616201: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
178509352
# 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/tmpg169iato/assets
INFO:tensorflow:Assets written to: /tmp/tmpg169iato/assets
2021-11-02 11:24:12.965799: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-11-02 11:24:12.965851: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
46256864
ls -lh {tflite_models_dir}/*.tflite
-rw-rw-r-- 1 kbuilder kbuilder  83K Nov  2 11:23 /tmp/mnist_tflite_models/mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder  24K Nov  2 11:23 /tmp/mnist_tflite_models/mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder  25K Nov  2 11:20 /tmp/mnist_tflite_models/mnist_model_quant_16x8.tflite
-rw-rw-r-- 1 kbuilder kbuilder 171M Nov  2 11:23 /tmp/mnist_tflite_models/resnet_v2_101.tflite
-rw-rw-r-- 1 kbuilder kbuilder  45M Nov  2 11:24 /tmp/mnist_tflite_models/resnet_v2_101_quantized.tflite

גודל הדגם מצטמצם מ-171 מגה-בייט ל-43 מגה-בייט. הדיוק של מודל זה על אימג'נט ניתן להעריך באמצעות סקריפטים מסופקים מדידת דיוק TFLite .

הדיוק האופטימלי של הדגם העליון 1 הוא 76.8, זהה לדגם הנקודה הצפה.