کمی سازی عدد صحیح پس از آموزش با فعال سازی int16

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

بررسی اجمالی

TensorFlow آرشیو در حال حاضر پشتیبانی از تبدیل فعالانه به 16 بیتی مقادیر صحیح و وزن به 8 بیتی عدد صحیح ارزش ها در هنگام تبدیل مدل از TensorFlow به فرمت بافر تخت TensorFlow بازگشت به محتوا |. ما به این حالت به عنوان "حالت کوانتیزاسیون 16x8" اشاره می کنیم. این حالت می‌تواند دقت مدل کوانتیزه‌شده را به طور قابل‌توجهی بهبود بخشد، زمانی که فعال‌سازی‌ها به کوانتیزه‌سازی حساس هستند، در حالی که هنوز به کاهش تقریباً 3-4 برابری در اندازه مدل دست می‌یابند. علاوه بر این، این مدل کاملاً کوانتیزه شده می تواند توسط شتاب دهنده های سخت افزاری فقط عدد صحیح مصرف شود.

برخی از نمونه‌هایی از مدل‌هایی که از این حالت کوانتیزاسیون پس از آموزش سود می‌برند عبارتند از:

  • وضوح فوق العاده،
  • پردازش سیگنال صوتی مانند حذف نویز و شکل دهی پرتو،
  • حذف نویز تصویر،
  • بازسازی HDR از یک تصویر واحد

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

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

برپایی

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

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

بررسی کنید که حالت کوانتیزاسیون 16x8 موجود باشد

tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8
<OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8: 'EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8'>

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

# 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.2797 - accuracy: 0.9224 - val_loss: 0.1224 - val_accuracy: 0.9641
<keras.callbacks.History at 0x7f6f19eff210>

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

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

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

در حال حاضر، تبدیل مدل با استفاده از TFliteConverter را به فرمت float32 به طور پیش فرض:

converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
2021-10-30 11:55:42.971843: 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/tmpbriefkal/assets
2021-10-30 11:55:43.402148: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-10-30 11:55:43.402187: 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

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

converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8]

همانطور که در مورد از int8 تدریج پس از آموزش، ممکن است برای تولید یک مدل کاملا صحیح کوانتیده با تنظیم گزینه های تبدیل inference_input(output)_type به tf.int16.

داده های کالیبراسیون را تنظیم کنید:

mnist_train, _ = tf.keras.datasets.mnist.load_data()
images = tf.cast(mnist_train[0], tf.float32) / 255.0
mnist_ds = tf.data.Dataset.from_tensor_slices((images)).batch(1)
def representative_data_gen():
  for input_value in mnist_ds.take(100):
    # Model has only one input so each data point has one element.
    yield [input_value]
converter.representative_dataset = representative_data_gen

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

tflite_16x8_model = converter.convert()
tflite_model_16x8_file = tflite_models_dir/"mnist_model_quant_16x8.tflite"
tflite_model_16x8_file.write_bytes(tflite_16x8_model)
INFO:tensorflow:Assets written to: /tmp/tmpfxn_2jql/assets
INFO:tensorflow:Assets written to: /tmp/tmpfxn_2jql/assets
2021-10-30 11:55:44.514461: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-10-30 11:55:44.514507: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
24768

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

ls -lh {tflite_models_dir}
total 136K
-rw-rw-r-- 1 kbuilder kbuilder 83K Oct 30 11:55 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 24K Oct 30 11:54 mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder 25K Oct 30 11:55 mnist_model_quant_16x8.tflite

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

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

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

interpreter = tf.lite.Interpreter(model_path=str(tflite_model_file))
interpreter.allocate_tensors()
interpreter_16x8 = tf.lite.Interpreter(model_path=str(tflite_model_16x8_file))
interpreter_16x8.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_16x8.get_input_details()[0]["index"]
output_index = interpreter_16x8.get_output_details()[0]["index"]

interpreter_16x8.set_tensor(input_index, test_image)
interpreter_16x8.invoke()
predictions = interpreter_16x8.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.9641

ارزیابی را در مدل کوانتیزه 16x8 تکرار کنید:

# NOTE: This quantization mode is an experimental post-training mode,
# it does not have any optimized kernels implementations or
# specialized machine learning hardware accelerators. Therefore,
# it could be slower than the float interpreter.
print(evaluate_model(interpreter_16x8))
0.964

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

،

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

بررسی اجمالی

TensorFlow آرشیو در حال حاضر پشتیبانی از تبدیل فعالانه به 16 بیتی مقادیر صحیح و وزن به 8 بیتی عدد صحیح ارزش ها در هنگام تبدیل مدل از TensorFlow به فرمت بافر تخت TensorFlow بازگشت به محتوا |. ما به این حالت به عنوان "حالت کوانتیزاسیون 16x8" اشاره می کنیم. این حالت می‌تواند دقت مدل کوانتیزه‌شده را به طور قابل‌توجهی بهبود بخشد، زمانی که فعال‌سازی‌ها به کوانتیزه‌سازی حساس هستند، در حالی که هنوز به کاهش تقریباً 3-4 برابری در اندازه مدل دست می‌یابند. علاوه بر این، این مدل کاملاً کوانتیزه شده می تواند توسط شتاب دهنده های سخت افزاری فقط عدد صحیح مصرف شود.

برخی از نمونه‌هایی از مدل‌هایی که از این حالت کوانتیزاسیون پس از آموزش سود می‌برند عبارتند از:

  • وضوح فوق العاده،
  • پردازش سیگنال صوتی مانند حذف نویز و شکل دهی پرتو،
  • حذف نویز تصویر،
  • بازسازی HDR از یک تصویر واحد

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

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

برپایی

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

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

بررسی کنید که حالت کوانتیزاسیون 16x8 موجود باشد

tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8
<OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8: 'EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8'>

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

# 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.2797 - accuracy: 0.9224 - val_loss: 0.1224 - val_accuracy: 0.9641
<keras.callbacks.History at 0x7f6f19eff210>

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

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

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

در حال حاضر، تبدیل مدل با استفاده از TFliteConverter را به فرمت float32 به طور پیش فرض:

converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
2021-10-30 11:55:42.971843: 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/tmpbriefkal/assets
2021-10-30 11:55:43.402148: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-10-30 11:55:43.402187: 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

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

converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8]

همانطور که در مورد از int8 تدریج پس از آموزش، ممکن است برای تولید یک مدل کاملا صحیح کوانتیده با تنظیم گزینه های تبدیل inference_input(output)_type به tf.int16.

داده های کالیبراسیون را تنظیم کنید:

mnist_train, _ = tf.keras.datasets.mnist.load_data()
images = tf.cast(mnist_train[0], tf.float32) / 255.0
mnist_ds = tf.data.Dataset.from_tensor_slices((images)).batch(1)
def representative_data_gen():
  for input_value in mnist_ds.take(100):
    # Model has only one input so each data point has one element.
    yield [input_value]
converter.representative_dataset = representative_data_gen

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

tflite_16x8_model = converter.convert()
tflite_model_16x8_file = tflite_models_dir/"mnist_model_quant_16x8.tflite"
tflite_model_16x8_file.write_bytes(tflite_16x8_model)
INFO:tensorflow:Assets written to: /tmp/tmpfxn_2jql/assets
INFO:tensorflow:Assets written to: /tmp/tmpfxn_2jql/assets
2021-10-30 11:55:44.514461: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format.
2021-10-30 11:55:44.514507: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
24768

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

ls -lh {tflite_models_dir}
total 136K
-rw-rw-r-- 1 kbuilder kbuilder 83K Oct 30 11:55 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 24K Oct 30 11:54 mnist_model_quant.tflite
-rw-rw-r-- 1 kbuilder kbuilder 25K Oct 30 11:55 mnist_model_quant_16x8.tflite

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

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

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

interpreter = tf.lite.Interpreter(model_path=str(tflite_model_file))
interpreter.allocate_tensors()
interpreter_16x8 = tf.lite.Interpreter(model_path=str(tflite_model_16x8_file))
interpreter_16x8.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_16x8.get_input_details()[0]["index"]
output_index = interpreter_16x8.get_output_details()[0]["index"]

interpreter_16x8.set_tensor(input_index, test_image)
interpreter_16x8.invoke()
predictions = interpreter_16x8.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.9641

ارزیابی را در مدل کوانتیزه 16x8 تکرار کنید:

# NOTE: This quantization mode is an experimental post-training mode,
# it does not have any optimized kernels implementations or
# specialized machine learning hardware accelerators. Therefore,
# it could be slower than the float interpreter.
print(evaluate_model(interpreter_16x8))
0.964

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