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

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

بررسی اجمالی

TensorFlow Lite اکنون از تبدیل فعال سازی ها به مقادیر عدد صحیح 16 بیتی و وزن ها به مقادیر صحیح 8 بیتی در حین تبدیل مدل از TensorFlow به قالب بافر مسطح TensorFlow Lite پشتیبانی می کند. ما از این حالت به عنوان "حالت کوانتیزه 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)
)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step
1875/1875 [==============================] - 13s 2ms/step - loss: 0.2827 - accuracy: 0.9209 - val_loss: 0.1246 - val_accuracy: 0.9664
<tensorflow.python.keras.callbacks.History at 0x7fc6d432cd50>

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

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

با استفاده از Python TFLiteConverter ، اکنون می توانید مدل آموزش دیده را به یک مدل TensorFlow Lite تبدیل کنید.

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

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

آن را در یک پرونده .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)
84552

به جای آنکه مدل را به حالت کوانتاسیون 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 ، یک مدل کاملاً عددی کوانتیزه شده inference_input(output)_type .

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

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

توجه داشته باشید که اندازه پرونده به طور تقریبی 1/3 اندازه است.

ls -lh {tflite_models_dir}
total 112K
-rw-rw-r-- 1 kbuilder kbuilder 83K May 15 11:12 mnist_model.tflite
-rw-rw-r-- 1 kbuilder kbuilder 25K May 15 11:12 mnist_model_quant_16x8.tflite

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

با استفاده از Python TensorFlow Lite Interpreter مدل 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.9664

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

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