Zobacz na TensorFlow.org | Uruchom w Google Colab | Wyświetl źródło na GitHub | Pobierz notatnik | Zobacz model piasty TF |
Przegląd
TensorFlow Lite obsługuje konwersję wagi do 8 bitowej precyzji w ramach modelu konwersji z graphdefs tensorflow do płaskiego formatu bufora TensorFlow Lite. Kwantyzacja zakresu dynamicznego zapewnia 4-krotne zmniejszenie rozmiaru modelu. Ponadto TFLite obsługuje kwantyzację w locie i dekwantyzację aktywacji, aby umożliwić:
- Używanie skwantyzowanych jąder do szybszej implementacji, jeśli jest to możliwe.
- Mieszanie jąder zmiennoprzecinkowych ze skwantowanymi jądrami dla różnych części grafu.
Aktywacje są zawsze przechowywane w postaci zmiennoprzecinkowej. W przypadku operacji obsługujących skwantowane jądra aktywacje są kwantowane dynamicznie do 8 bitów precyzji przed przetwarzaniem i są dekwantowane do precyzji zmiennoprzecinkowej po przetworzeniu. W zależności od konwertowanego modelu może to przyspieszyć obliczenia w stosunku do obliczeń zmiennoprzecinkowych.
W przeciwieństwie do kwantyzacji świadomego szkolenia , wagi są kwantowane szkolenie post i aktywacje są krokowe dynamicznie przy wnioskowaniu w tej metodzie. W związku z tym wagi modelu nie są ponownie trenowane, aby skompensować błędy wywołane kwantyzacją. Ważne jest, aby sprawdzić dokładność modelu skwantowanego, aby upewnić się, że degradacja jest akceptowalna.
Ten samouczek szkoli model MNIST od podstaw, sprawdza jego dokładność w TensorFlow, a następnie konwertuje model na płaski bufor Tensorflow Lite z kwantyzacją zakresu dynamicznego. Na koniec sprawdza dokładność przekonwertowanego modelu i porównuje go z oryginalnym modelem swobodnym.
Zbuduj model MNIST
Ustawiać
import logging
logging.getLogger("tensorflow").setLevel(logging.DEBUG)
import tensorflow as tf
from tensorflow import keras
import numpy as np
import pathlib
Wytrenuj model TensorFlow
# 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.3260 - accuracy: 0.9063 - val_loss: 0.1721 - val_accuracy: 0.9499 <keras.callbacks.History at 0x7fb7a1c4ed90>
Na przykład, ponieważ trenowałeś model tylko dla jednej epoki, trenuje on tylko z dokładnością ~96%.
Konwersja na model TensorFlow Lite
Używanie Pythona TFLiteConverter można teraz przekształcić wyszkolony modelu do modelu TensorFlow Lite.
Teraz załadować model używając TFLiteConverter
:
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
2021-11-02 11:23:32.211024: 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/tmpua453ven/assets 2021-11-02 11:23:32.640259: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-11-02 11:23:32.640302: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency.
Zapisz to do pliku 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
Do kwantowania modelu na eksport, ustaw optimizations
flagę optymalizacja pod kątem wielkości:
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_quant_model = converter.convert()
tflite_model_quant_file = tflite_models_dir/"mnist_model_quant.tflite"
tflite_model_quant_file.write_bytes(tflite_quant_model)
INFO:tensorflow:Assets written to: /tmp/tmpaw0wsb_y/assets INFO:tensorflow:Assets written to: /tmp/tmpaw0wsb_y/assets 2021-11-02 11:23:33.235475: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-11-02 11:23:33.235512: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 23904
Zauważ, że plik wynikowy, wynosi około 1/4
wielkości.
ls -lh {tflite_models_dir}
total 136K -rw-rw-r-- 1 kbuilder kbuilder 83K Nov 2 11:23 mnist_model.tflite -rw-rw-r-- 1 kbuilder kbuilder 24K Nov 2 11:23 mnist_model_quant.tflite -rw-rw-r-- 1 kbuilder kbuilder 25K Nov 2 11:20 mnist_model_quant_16x8.tflite
Uruchom modele TFLite
Uruchom model TensorFlow Lite za pomocą interpretera Python TensorFlow Lite.
Załaduj model do interpretera
interpreter = tf.lite.Interpreter(model_path=str(tflite_model_file))
interpreter.allocate_tensors()
interpreter_quant = tf.lite.Interpreter(model_path=str(tflite_model_quant_file))
interpreter_quant.allocate_tensors()
Przetestuj model na jednym obrazie
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)
Oceń modele
# 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.9499
Powtórz ocenę na skwantowanym modelu zakresu dynamicznego, aby uzyskać:
print(evaluate_model(interpreter_quant))
0.95
W tym przykładzie skompresowany model nie ma różnicy w dokładności.
Optymalizacja istniejącego modelu
Resnet z warstwami preaktywacji (Resnet-v2) są szeroko stosowane w aplikacjach wizyjnych. Pre-przeszkolony mrożone wykres dla resnet-v2-101 jest dostępny na Tensorflow Hub .
Możesz przekonwertować zamrożony wykres do płaskiego bufora TensorFLow Lite z kwantyzacją przez:
import tensorflow_hub as hub
resnet_v2_101 = tf.keras.Sequential([
keras.layers.InputLayer(input_shape=(224, 224, 3)),
hub.KerasLayer("https://tfhub.dev/google/imagenet/resnet_v2_101/classification/4")
])
converter = tf.lite.TFLiteConverter.from_keras_model(resnet_v2_101)
# Convert to TF Lite without quantization
resnet_tflite_file = tflite_models_dir/"resnet_v2_101.tflite"
resnet_tflite_file.write_bytes(converter.convert())
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model. WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model. INFO:tensorflow:Assets written to: /tmp/tmpxtji1amp/assets INFO:tensorflow:Assets written to: /tmp/tmpxtji1amp/assets 2021-11-02 11:23:57.616139: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-11-02 11:23:57.616201: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 178509352
# Convert to TF Lite with quantization
converter.optimizations = [tf.lite.Optimize.DEFAULT]
resnet_quantized_tflite_file = tflite_models_dir/"resnet_v2_101_quantized.tflite"
resnet_quantized_tflite_file.write_bytes(converter.convert())
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model. WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model. INFO:tensorflow:Assets written to: /tmp/tmpg169iato/assets INFO:tensorflow:Assets written to: /tmp/tmpg169iato/assets 2021-11-02 11:24:12.965799: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-11-02 11:24:12.965851: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 46256864
ls -lh {tflite_models_dir}/*.tflite
-rw-rw-r-- 1 kbuilder kbuilder 83K Nov 2 11:23 /tmp/mnist_tflite_models/mnist_model.tflite -rw-rw-r-- 1 kbuilder kbuilder 24K Nov 2 11:23 /tmp/mnist_tflite_models/mnist_model_quant.tflite -rw-rw-r-- 1 kbuilder kbuilder 25K Nov 2 11:20 /tmp/mnist_tflite_models/mnist_model_quant_16x8.tflite -rw-rw-r-- 1 kbuilder kbuilder 171M Nov 2 11:23 /tmp/mnist_tflite_models/resnet_v2_101.tflite -rw-rw-r-- 1 kbuilder kbuilder 45M Nov 2 11:24 /tmp/mnist_tflite_models/resnet_v2_101_quantized.tflite
Rozmiar modelu zmniejsza się ze 171 MB do 43 MB. Dokładność tego modelu na IMAGEnet można ocenić za pomocą skryptów przewidzianych Dokładność pomiaru TFLite .
Zoptymalizowana dokładność modelu top-1 wynosi 76,8, tak samo jak w modelu zmiennoprzecinkowym.