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

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

بررسی اجمالی

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

در این آموزش ، شما یک مدل MNIST را از ابتدا آموزش می دهید ، صحت آن را در TensorFlow بررسی می کنید و سپس مدل را با کوانتاسیون float16 به یک flatbuffer 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
tf.float16
tf.float16

مدل را آموزش دهید و صادر کنید

# 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
2021-09-12 11:11:37.167262: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_SYSTEM_DRIVER_MISMATCH: system has unsupported display driver / cuda driver combination
2021-09-12 11:11:37.167422: E tensorflow/stream_executor/cuda/cuda_diagnostics.cc:313] kernel version 470.57.2 does not match DSO version 470.63.1 -- cannot find working devices in this configuration
1875/1875 [==============================] - 11s 5ms/step - loss: 0.2643 - accuracy: 0.9280 - val_loss: 0.1068 - val_accuracy: 0.9681
<keras.callbacks.History at 0x7f173f943f90>

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

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

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

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

converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
2021-09-12 11:11:48.574339: 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/tmpqgyupoty/assets
2021-09-12 11:11:49.006295: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-09-12 11:11:49.006342: 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

به جای فرمول اندازهگیری مدل به 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/tmpw53m2y4_/assets
INFO:tensorflow:Assets written to: /tmp/tmpw53m2y4_/assets
2021-09-12 11:11:49.600290: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-09-12 11:11:49.600336: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
44432

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

ls -lh {tflite_models_dir}
total 128K
-rw-rw-r-- 1 kbuilder kbuilder 83K Sep 12 11:11 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 44K Sep 12 11:11 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.9681

ارزیابی را در مدل کوانتومی 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.9681

در این مثال ، شما مدلی را برای 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 و نحوه استفاده از آن در برنامه خود را می توان یافت در اینجا