کمی سازی شناور 16 پس از آموزش

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

بررسی اجمالی

TensorFlow آرشیو در حال حاضر پشتیبانی از تبدیل وزن به 16 بیتی مقادیر ممیز شناور در هنگام تبدیل مدل از TensorFlow به فرمت بافر تخت TensorFlow بازگشت به محتوا |. این منجر به کاهش 2 برابری اندازه مدل می شود. برخی از سخت‌افزارها، مانند پردازنده‌های گرافیکی، می‌توانند به صورت بومی در این محاسبات دقیق کاهش‌یافته محاسبه کنند و سرعت اجرای ممیز شناور سنتی را افزایش دهند. نماینده GPU Tensorflow Lite را می توان برای اجرا به این روش پیکربندی کرد. با این حال، مدلی که به وزن‌های float16 تبدیل شده است، همچنان می‌تواند بدون تغییر اضافی روی CPU اجرا شود: وزن‌های float16 قبل از اولین استنتاج به float32 نمونه‌برداری می‌شوند. این امکان کاهش قابل توجه در اندازه مدل را در ازای کمترین تأثیر بر تأخیر و دقت فراهم می کند.

در این آموزش، شما یک مدل MNIST را از ابتدا آموزش می‌دهید، دقت آن را در TensorFlow بررسی می‌کنید و سپس مدل را با کوانتیزه کردن float16 به یک بافر مسطح Tensorflow Lite تبدیل می‌کنید. در نهایت دقت مدل تبدیل شده را بررسی کرده و با مدل اصلی float32 مقایسه کنید.

یک مدل MNIST بسازید

برپایی

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

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

آموزش و صادرات مدل

# 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)
)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step
11501568/11490434 [==============================] - 0s 0us/step
1875/1875 [==============================] - 13s 2ms/step - loss: 0.2655 - accuracy: 0.9244 - val_loss: 0.1237 - val_accuracy: 0.9654
<keras.callbacks.History at 0x7f3f8428e6d0>

برای مثال، شما مدل را فقط برای یک دوره آموزش داده‌اید، بنابراین فقط با دقت 96% تمرین می‌کند.

تبدیل به یک مدل TensorFlow Lite

با استفاده از پایتون TFLiteConverter ، شما می توانید در حال حاضر مدل آموزش دیده را به یک مدل TensorFlow بازگشت به محتوا | تبدیل کنید.

در حال حاضر مدل با استفاده از بار TFLiteConverter :

converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
2021-12-14 12:18:07.073783: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmpm1s3vkrd/assets
2021-12-14 12:18:07.876066: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-12-14 12:18:07.876112: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
WARNING:absl:Buffer deduplication procedure will be skipped when flatbuffer library is not properly loaded

ارسال آن را به یک .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)
84540

به جای فرمول اندازهگیری مدل به float16 بر صادرات، ابتدا مجموعه optimizations پرچم را به بهینه سازی استفاده از پیش فرض. سپس مشخص کنید که float16 نوع پشتیبانی شده در پلت فرم هدف است:

converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]

در نهایت، مدل را مانند همیشه تبدیل کنید. توجه داشته باشید، به طور پیش فرض مدل تبدیل شده همچنان از ورودی و خروجی شناور برای راحتی فراخوانی استفاده می کند.

tflite_fp16_model = converter.convert()
tflite_model_fp16_file = tflite_models_dir/"mnist_model_quant_f16.tflite"
tflite_model_fp16_file.write_bytes(tflite_fp16_model)
INFO:tensorflow:Assets written to: /tmp/tmpvjt9l68i/assets
INFO:tensorflow:Assets written to: /tmp/tmpvjt9l68i/assets
2021-12-14 12:18:08.810262: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:363] Ignored output_format.
2021-12-14 12:18:08.810303: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:366] Ignored drop_control_dependency.
WARNING:absl:Buffer deduplication procedure will be skipped when flatbuffer library is not properly loaded
44384

توجه داشته باشید که فایل منجر حدود است 1/2 اندازه.

ls -lh {tflite_models_dir}
total 128K
-rw-rw-r-- 1 kbuilder kbuilder 83K Dec 14 12:18 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 44K Dec 14 12:18 mnist_model_quant_f16.tflite

مدل های TensorFlow Lite را اجرا کنید

مدل TensorFlow Lite را با استفاده از مترجم Python TensorFlow Lite اجرا کنید.

مدل را در مفسرها بارگذاری کنید

interpreter = tf.lite.Interpreter(model_path=str(tflite_model_file))
interpreter.allocate_tensors()
interpreter_fp16 = tf.lite.Interpreter(model_path=str(tflite_model_fp16_file))
interpreter_fp16.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

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

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

interpreter_fp16.set_tensor(input_index, test_image)
interpreter_fp16.invoke()
predictions = interpreter_fp16.get_tensor(output_index)
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.9654

ارزیابی را در مدل کوانتیزه float16 تکرار کنید تا به دست آورید:

# NOTE: Colab runs on server CPUs. At the time of writing this, TensorFlow Lite
# doesn't have super optimized server CPU kernels. For this reason this may be
# slower than the above float interpreter. But for mobile CPUs, considerable
# speedup can be observed.
print(evaluate_model(interpreter_fp16))
0.9654

در این مثال، شما یک مدل را به float16 بدون تفاوت در دقت کوانتیزه کرده اید.

همچنین امکان ارزیابی مدل کوانتیزه fp16 در GPU وجود دارد. برای انجام تمام حساب با ارزش دقت کاهش می یابد، لازم است تا ایجاد TfLiteGPUDelegateOptions در برنامه و مجموعه خود را ساختار precision_loss_allowed به 1 ، مثل این:

//Prepare GPU delegate.
const TfLiteGpuDelegateOptions options = {
  .metadata = NULL,
  .compile_options = {
    .precision_loss_allowed = 1,  // FP16
    .preferred_gl_object_type = TFLITE_GL_OBJECT_TYPE_FASTEST,
    .dynamic_batch_enabled = 0,   // Not fully functional yet
  },
};

مستندات دقیق در مورد نماینده TFLite GPU و نحوه استفاده از آن در برنامه خود را می توان یافت در اینجا