Lượng tử hóa số nguyên sau đào tạo với kích hoạt int16

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Tổng quat

TensorFlow Lite bây giờ hỗ trợ chuyển đổi kích hoạt các giá trị số nguyên 16-bit và trọng lượng tới 8-bit số nguyên giá trị trong mô hình chuyển đổi từ TensorFlow sang định dạng đệm phẳng TensorFlow Lite. Chúng tôi gọi chế độ này là "chế độ lượng tử hóa 16x8". Chế độ này có thể cải thiện đáng kể độ chính xác của mô hình lượng tử hóa, khi các kích hoạt nhạy cảm với lượng tử hóa, trong khi vẫn đạt được kích thước mô hình giảm gần 3-4 lần. Hơn nữa, mô hình lượng tử hóa hoàn toàn này có thể được sử dụng bởi các bộ tăng tốc phần cứng chỉ số nguyên.

Một số ví dụ về các mô hình được hưởng lợi từ chế độ lượng tử hóa sau đào tạo này bao gồm:

  • giải pháp tối ưu,
  • xử lý tín hiệu âm thanh như khử tiếng ồn và định dạng chùm tia,
  • khử nhiễu hình ảnh,
  • Tái tạo HDR từ một hình ảnh duy nhất

Trong hướng dẫn này, bạn đào tạo mô hình MNIST từ đầu, kiểm tra độ chính xác của nó trong TensorFlow, sau đó chuyển đổi mô hình thành bộ đệm phẳng Tensorflow Lite bằng chế độ này. Cuối cùng, bạn kiểm tra độ chính xác của mô hình đã chuyển đổi và so sánh với mô hình float32 ban đầu. Lưu ý rằng ví dụ này thể hiện việc sử dụng chế độ này và không cho thấy lợi ích so với các kỹ thuật lượng tử hóa có sẵn khác trong TensorFlow Lite.

Xây dựng mô hình MNIST

Thành lập

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

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

Kiểm tra xem chế độ lượng tử hóa 16x8 có khả dụng không

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'>

Đào tạo và xuất mô hình

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

Ví dụ: bạn đã đào tạo mô hình chỉ trong một kỷ nguyên, vì vậy nó chỉ đào tạo đến độ chính xác ~ 96%.

Chuyển đổi sang mô hình TensorFlow Lite

Sử dụng Python TFLiteConverter , bây giờ bạn có thể chuyển đổi các mô hình đào tạo thành một mô hình TensorFlow Lite.

Bây giờ, chuyển đổi mô hình sử dụng TFliteConverter sang định dạng float32 mặc định:

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.

Viết nó ra một .tflite file:

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

Để thay quantize mô hình để 16x8 chế độ lượng tử, đầu tiên thiết lập optimizations cờ để tối ưu hóa sử dụng mặc định. Sau đó, chỉ định rằng chế độ lượng tử hóa 16x8 là hoạt động được hỗ trợ bắt buộc trong đặc điểm kỹ thuật đích:

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

Như trong trường hợp của int8 lượng tử sau đào tạo, chúng ta có thể tạo ra một mô hình hoàn toàn nguyên lượng tử bằng cách thiết lập tùy chọn chuyển đổi inference_input(output)_type để tf.int16.

Đặt dữ liệu hiệu chuẩn:

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

Cuối cùng, chuyển đổi mô hình như bình thường. Lưu ý, theo mặc định, mô hình được chuyển đổi sẽ vẫn sử dụng đầu vào và đầu ra float để thuận tiện cho việc gọi.

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

Lưu ý cách các tập tin kết quả là khoảng 1/3 kích thước.

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

Chạy các mô hình TensorFlow Lite

Chạy mô hình TensorFlow Lite bằng Trình thông dịch Python TensorFlow Lite.

Tải mô hình vào trình thông dịch

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

Kiểm tra các mô hình trên một hình ảnh

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

Đánh giá các mô hình

# 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

Lặp lại đánh giá trên mô hình lượng tử hóa 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

Trong ví dụ này, bạn đã lượng tử hóa một mô hình thành 16x8 mà không có sự khác biệt về độ chính xác, nhưng với kích thước giảm xuống 3 lần.

,

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Tổng quat

TensorFlow Lite bây giờ hỗ trợ chuyển đổi kích hoạt các giá trị số nguyên 16-bit và trọng lượng tới 8-bit số nguyên giá trị trong mô hình chuyển đổi từ TensorFlow sang định dạng đệm phẳng TensorFlow Lite. Chúng tôi gọi chế độ này là "chế độ lượng tử hóa 16x8". Chế độ này có thể cải thiện đáng kể độ chính xác của mô hình lượng tử hóa, khi các kích hoạt nhạy cảm với lượng tử hóa, trong khi vẫn đạt được kích thước mô hình giảm gần 3-4 lần. Hơn nữa, mô hình lượng tử hóa hoàn toàn này có thể được sử dụng bởi các bộ tăng tốc phần cứng chỉ số nguyên.

Một số ví dụ về các mô hình được hưởng lợi từ chế độ lượng tử hóa sau đào tạo này bao gồm:

  • giải pháp tối ưu,
  • xử lý tín hiệu âm thanh như khử tiếng ồn và định dạng chùm tia,
  • khử nhiễu hình ảnh,
  • Tái tạo HDR từ một hình ảnh duy nhất

Trong hướng dẫn này, bạn đào tạo mô hình MNIST từ đầu, kiểm tra độ chính xác của nó trong TensorFlow, sau đó chuyển đổi mô hình thành bộ đệm phẳng Tensorflow Lite bằng chế độ này. Cuối cùng, bạn kiểm tra độ chính xác của mô hình đã chuyển đổi và so sánh với mô hình float32 ban đầu. Lưu ý rằng ví dụ này thể hiện việc sử dụng chế độ này và không cho thấy lợi ích so với các kỹ thuật lượng tử hóa có sẵn khác trong TensorFlow Lite.

Xây dựng mô hình MNIST

Thành lập

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

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

Kiểm tra xem chế độ lượng tử hóa 16x8 có khả dụng không

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'>

Đào tạo và xuất mô hình

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

Ví dụ: bạn đã đào tạo mô hình chỉ trong một kỷ nguyên, vì vậy nó chỉ đào tạo đến độ chính xác ~ 96%.

Chuyển đổi sang mô hình TensorFlow Lite

Sử dụng Python TFLiteConverter , bây giờ bạn có thể chuyển đổi các mô hình đào tạo thành một mô hình TensorFlow Lite.

Bây giờ, chuyển đổi mô hình sử dụng TFliteConverter sang định dạng float32 mặc định:

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.

Viết nó ra một .tflite file:

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

Để thay quantize mô hình để 16x8 chế độ lượng tử, đầu tiên thiết lập optimizations cờ để tối ưu hóa sử dụng mặc định. Sau đó, chỉ định rằng chế độ lượng tử hóa 16x8 là hoạt động được hỗ trợ bắt buộc trong đặc điểm kỹ thuật đích:

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

Như trong trường hợp của int8 lượng tử sau đào tạo, chúng ta có thể tạo ra một mô hình hoàn toàn nguyên lượng tử bằng cách thiết lập tùy chọn chuyển đổi inference_input(output)_type để tf.int16.

Đặt dữ liệu hiệu chuẩn:

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

Cuối cùng, chuyển đổi mô hình như bình thường. Lưu ý, theo mặc định, mô hình được chuyển đổi sẽ vẫn sử dụng đầu vào và đầu ra float để thuận tiện cho việc gọi.

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

Lưu ý cách các tập tin kết quả là khoảng 1/3 kích thước.

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

Chạy các mô hình TensorFlow Lite

Chạy mô hình TensorFlow Lite bằng Trình thông dịch Python TensorFlow Lite.

Tải mô hình vào trình thông dịch

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

Kiểm tra các mô hình trên một hình ảnh

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

Đánh giá các mô hình

# 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

Lặp lại đánh giá trên mô hình lượng tử hóa 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

Trong ví dụ này, bạn đã lượng tử hóa một mô hình thành 16x8 mà không có sự khác biệt về độ chính xác, nhưng với kích thước giảm xuống 3 lần.