int16 aktivasyonları ile eğitim sonrası tamsayı niceleme

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

genel bakış

TensorFlow Lite hemen TensorFlow Lite düz tampon biçimine TensorFlow model dönüştürme sırasında değerleri tam sayı 8-bit, 16-bit tamsayı değerleri ve ağırlıklarına etkinleştirme dönüştürme destekler. Bu moda "16x8 nicemleme modu" diyoruz. Bu mod, aktivasyonlar nicelemeye duyarlı olduğunda nicelenmiş modelin doğruluğunu önemli ölçüde iyileştirirken, yine de model boyutunda neredeyse 3-4 kat azalma sağlar. Ayrıca, bu tamamen nicelenmiş model, yalnızca tamsayılı donanım hızlandırıcıları tarafından tüketilebilir.

Eğitim sonrası nicelemenin bu modundan yararlanan bazı model örnekleri şunları içerir:

  • süper çözünürlük,
  • gürültü engelleme ve hüzmeleme gibi ses sinyali işleme,
  • görüntü gürültü giderme,
  • Tek bir görüntüden HDR rekonstrüksiyonu

Bu öğreticide, bir MNIST modelini sıfırdan eğitecek, doğruluğunu TensorFlow'da kontrol edecek ve ardından bu modu kullanarak modeli bir Tensorflow Lite düz arabelleğe dönüştüreceksiniz. Sonunda dönüştürülmüş modelin doğruluğunu kontrol eder ve orijinal float32 modeliyle karşılaştırırsınız. Bu örneğin, bu modun kullanımını gösterdiğini ve TensorFlow Lite'taki diğer mevcut niceleme tekniklerine göre faydalar göstermediğini unutmayın.

Bir MNIST modeli oluşturun

Kurmak

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

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

16x8 niceleme modunun mevcut olup olmadığını kontrol edin

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

Modeli eğitin ve dışa aktarın

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

Örneğin, modeli yalnızca tek bir dönem için eğittiniz, bu nedenle yalnızca ~%96 doğrulukla eğitir.

TensorFlow Lite modeline dönüştürün

Python kullanarak TFLiteConverter , artık TensorFlow Lite modeline eğitilmiş modelini dönüştürebilirsiniz.

Şimdi kullanarak modeli dönüştürmek TFliteConverter varsayılan float32 biçime:

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.

Bir bunu dışarı yazın .tflite dosyası:

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

Yerine 16x8 nicemleme moduna modelin kuantize için, ilk set optimizations kullanım varsayılan optimizasyonlar bayrağı. Ardından, 16x8 niceleme modunun hedef belirtimde desteklenen gerekli işlem olduğunu belirtin:

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

İnt8 eğitim sonrası Nicemlemenin durumunda olduğu gibi, dönüştürücü seçenekleri ayarlayarak tam tamsayı nicelenmiş modelini üretmek mümkündür inference_input(output)_type tf.int16 için.

Kalibrasyon verilerini ayarlayı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

Son olarak, modeli her zamanki gibi dönüştürün. Varsayılan olarak dönüştürülen modelin, çağırma kolaylığı için kayan giriş ve çıkışları kullanmaya devam edeceğini unutmayın.

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

Ortaya çıkan dosya yaklaşık ne kadar Not 1/3 boyutu.

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 modellerini çalıştırın

Python TensorFlow Lite Yorumlayıcıyı kullanarak TensorFlow Lite modelini çalıştırın.

Modeli tercümanlara yükleyin

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

Modelleri tek bir görüntü üzerinde test edin

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

Modelleri değerlendirin

# 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

Değerlendirmeyi 16x8 nicelenmiş model üzerinde tekrarlayın:

# 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

Bu örnekte, bir modeli 16x8'e, doğrulukta hiçbir fark olmaksızın, ancak 3x küçültülmüş boyutta nicelleştirdiniz.

,

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

genel bakış

TensorFlow Lite hemen TensorFlow Lite düz tampon biçimine TensorFlow model dönüştürme sırasında değerleri tam sayı 8-bit, 16-bit tamsayı değerleri ve ağırlıklarına etkinleştirme dönüştürme destekler. Bu moda "16x8 nicemleme modu" diyoruz. Bu mod, aktivasyonlar nicelemeye duyarlı olduğunda nicelenmiş modelin doğruluğunu önemli ölçüde iyileştirirken, yine de model boyutunda neredeyse 3-4 kat azalma sağlar. Ayrıca, bu tamamen nicelenmiş model, yalnızca tamsayılı donanım hızlandırıcıları tarafından tüketilebilir.

Eğitim sonrası nicelemenin bu modundan yararlanan bazı model örnekleri şunları içerir:

  • süper çözünürlük,
  • gürültü engelleme ve hüzmeleme gibi ses sinyali işleme,
  • görüntü gürültü giderme,
  • Tek bir görüntüden HDR rekonstrüksiyonu

Bu öğreticide, bir MNIST modelini sıfırdan eğitecek, doğruluğunu TensorFlow'da kontrol edecek ve ardından bu modu kullanarak modeli bir Tensorflow Lite düz arabelleğe dönüştüreceksiniz. Sonunda dönüştürülmüş modelin doğruluğunu kontrol eder ve orijinal float32 modeliyle karşılaştırırsınız. Bu örneğin, bu modun kullanımını gösterdiğini ve TensorFlow Lite'taki diğer mevcut niceleme tekniklerine göre faydalar göstermediğini unutmayın.

Bir MNIST modeli oluşturun

Kurmak

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

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

16x8 niceleme modunun mevcut olup olmadığını kontrol edin

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

Modeli eğitin ve dışa aktarın

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

Örneğin, modeli yalnızca tek bir dönem için eğittiniz, bu nedenle yalnızca ~%96 doğrulukla eğitir.

TensorFlow Lite modeline dönüştürün

Python kullanarak TFLiteConverter , artık TensorFlow Lite modeline eğitilmiş modelini dönüştürebilirsiniz.

Şimdi kullanarak modeli dönüştürmek TFliteConverter varsayılan float32 biçime:

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.

Bir bunu dışarı yazın .tflite dosyası:

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

Yerine 16x8 nicemleme moduna modelin kuantize için, ilk set optimizations kullanım varsayılan optimizasyonlar bayrağı. Ardından, 16x8 niceleme modunun hedef belirtimde desteklenen gerekli işlem olduğunu belirtin:

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

İnt8 eğitim sonrası Nicemlemenin durumunda olduğu gibi, dönüştürücü seçenekleri ayarlayarak tam tamsayı nicelenmiş modelini üretmek mümkündür inference_input(output)_type tf.int16 için.

Kalibrasyon verilerini ayarlayı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

Son olarak, modeli her zamanki gibi dönüştürün. Varsayılan olarak dönüştürülen modelin, çağırma kolaylığı için kayan giriş ve çıkışları kullanmaya devam edeceğini unutmayın.

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

Ortaya çıkan dosya yaklaşık ne kadar Not 1/3 boyutu.

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 modellerini çalıştırın

Python TensorFlow Lite Yorumlayıcıyı kullanarak TensorFlow Lite modelini çalıştırın.

Modeli tercümanlara yükleyin

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

Modelleri tek bir görüntü üzerinde test edin

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

Modelleri değerlendirin

# 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

Değerlendirmeyi 16x8 nicelenmiş model üzerinde tekrarlayın:

# 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

Bu örnekte, bir modeli 16x8'e, doğrulukta hiçbir fark olmaksızın, ancak 3x küçültülmüş boyutta nicelleştirdiniz.