Eğitim sonrası niceleme, model boyutunu küçültebilen ve aynı zamanda model doğruluğunda çok az bozulma ile CPU ve donanım hızlandırıcı gecikmesini iyileştirebilen bir dönüştürme tekniğidir. Önceden eğitilmiş bir kayan TensorFlow modelini , TensorFlow Lite Converter'ı kullanarak TensorFlow Lite formatına dönüştürdüğünüzde nicelendirebilirsiniz.
Optimizasyon Yöntemleri
Aralarından seçim yapabileceğiniz birkaç eğitim sonrası niceleme seçeneği vardır. Seçeneklerin ve sağladıkları faydaların özet tablosu aşağıdadır:
teknik | Faydalar | Donanım |
---|---|---|
Dinamik aralık niceleme | 4x daha küçük, 2x-3x hızlanma | İşlemci |
Tam tamsayı niceleme | 4x daha küçük, 3x+ hızlanma | CPU, Edge TPU, Mikrodenetleyiciler |
Float16 niceleme | 2 kat daha küçük, GPU hızlandırma | İşlemci, GPU |
Aşağıdaki karar ağacı, kullanım durumunuz için hangi eğitim sonrası niceleme yönteminin en iyi olduğunu belirlemenize yardımcı olabilir:
Dinamik aralık niceleme
Kalibrasyon için temsili bir veri seti sağlamanıza gerek kalmadan azaltılmış bellek kullanımı ve daha hızlı hesaplama sağladığı için dinamik aralık niceleme önerilen bir başlangıç noktasıdır. Bu niceleme türü, dönüştürme zamanında yalnızca kayan noktadan tamsayıya ağırlıkları statik olarak niceler ve bu da 8 bitlik kesinlik sağlar:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] tflite_quant_model = converter.convert()
Çıkarım sırasındaki gecikmeyi daha da azaltmak için, "dinamik aralık" operatörleri, aktivasyonları 8 bitlik aralıklarına göre dinamik olarak niceler ve 8 bitlik ağırlıklar ve aktivasyonlarla hesaplamalar gerçekleştirir. Bu optimizasyon, tamamen sabit noktalı çıkarımlara yakın gecikmeler sağlar. Bununla birlikte, çıktılar yine de kayan nokta kullanılarak depolanır, bu nedenle dinamik aralıklı işlemlerin artan hızı, tam sabit noktalı bir hesaplamadan daha azdır.
Tam tamsayı niceleme
Tüm model matematiğinin tamsayı nicelemeli olduğundan emin olarak daha fazla gecikme iyileştirmesi, en yüksek bellek kullanımında azalma ve yalnızca tamsayı donanım cihazları veya hızlandırıcılarla uyumluluk elde edebilirsiniz.
Tam tamsayı niceleme için, modeldeki tüm kayan nokta tensörlerinin aralığını (min, maks) kalibre etmeniz veya tahmin etmeniz gerekir. Ağırlıklar ve önyargılar gibi sabit tensörlerin aksine, model girişi, aktivasyonlar (ara katmanların çıktıları) ve model çıktısı gibi değişken tensörler, birkaç çıkarım döngüsü çalıştırmadan kalibre edilemez. Sonuç olarak, dönüştürücü bunları kalibre etmek için temsili bir veri kümesi gerektirir. Bu veri kümesi, eğitim veya doğrulama verilerinin küçük bir alt kümesi (yaklaşık ~100-500 örnek) olabilir. Aşağıdaki representative_dataset()
işlevine bakın.
TensorFlow 2.7 sürümünden, temsili veri setini aşağıdaki örnekte olduğu gibi bir imza aracılığıyla belirtebilirsiniz:
def representative_dataset(): for data in dataset: yield { "image": data.image, "bias": data.bias, }
Verilen TensorFlow modelinde birden fazla imza varsa imza anahtarlarını belirterek birden çok veri kümesini belirleyebilirsiniz:
def representative_dataset(): # Feed data set for the "encode" signature. for data in encode_signature_dataset: yield ( "encode", { "image": data.image, "bias": data.bias, } ) # Feed data set for the "decode" signature. for data in decode_signature_dataset: yield ( "decode", { "image": data.image, "hint": data.hint, }, )
Bir giriş tensörü listesi sağlayarak temsili veri kümesini oluşturabilirsiniz:
def representative_dataset(): for data in tf.data.Dataset.from_tensor_slices((images)).batch(1).take(100): yield [tf.dtypes.cast(data, tf.float32)]
TensorFlow 2.7 sürümünden bu yana, giriş tensörü sıralaması kolayca değiştirilebildiğinden, giriş tensörü listesi tabanlı yaklaşım yerine imza tabanlı yaklaşımı kullanmanızı öneririz.
Test amacıyla, sahte bir veri kümesini aşağıdaki gibi kullanabilirsiniz:
def representative_dataset(): for _ in range(100): data = np.random.rand(1, 244, 244, 3) yield [data.astype(np.float32)]
Kayan geri dönüşlü tamsayı (varsayılan kayan giriş/çıkış kullanılarak)
Bir modeli tamamen tamsayı nicelemek için, ancak bir tamsayı uygulaması olmadığında kayan işleçleri kullanın (dönüşümün sorunsuz bir şekilde gerçekleşmesini sağlamak için), aşağıdaki adımları kullanın:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset tflite_quant_model = converter.convert()
Yalnızca tamsayı
Yalnızca tamsayı modelleri oluşturmak, Mikrodenetleyiciler ve Coral Edge TPU'lar için TensorFlow Lite için yaygın bir kullanım durumudur.
Ek olarak, yalnızca tamsayı cihazlarla (8 bit mikrodenetleyiciler gibi) ve hızlandırıcılarla (Coral Edge TPU gibi) uyumluluğu sağlamak için, aşağıdaki adımları kullanarak giriş ve çıkış dahil tüm işlemler için tam tamsayı nicelemeyi zorunlu kılabilirsiniz:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 # or tf.uint8 converter.inference_output_type = tf.int8 # or tf.uint8 tflite_quant_model = converter.convert()
Float16 niceleme
Ağırlıkları 16 bitlik kayan noktalı sayılar için IEEE standardı olan float16'ya niceleyerek kayan nokta modelinin boyutunu küçültebilirsiniz. Ağırlıkların float16 nicelemesini etkinleştirmek için aşağıdaki adımları kullanın:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_types = [tf.float16] tflite_quant_model = converter.convert()
Float16 nicelemenin avantajları aşağıdaki gibidir:
- Model boyutunu yarıya kadar küçültür (çünkü tüm ağırlıklar orijinal boyutlarının yarısı olur).
- Doğrulukta minimum kayba neden olur.
- Doğrudan float16 verileri üzerinde çalışabilen ve böylece float32 hesaplamalarından daha hızlı yürütme sağlayan bazı delegeleri (örneğin GPU temsilcisi) destekler.
Float16 nicelemenin dezavantajları aşağıdaki gibidir:
- Sabit nokta matematiğine niceleme kadar gecikmeyi azaltmaz.
- Varsayılan olarak, bir float16 nicemlenmiş modeli, CPU üzerinde çalıştırıldığında ağırlık değerlerini float32 olarak "dekuantize eder". (GPU temsilcisinin, float16 verileri üzerinde çalışabileceği için bu dekuantizasyonu gerçekleştirmeyeceğini unutmayın.)
Yalnızca tamsayı: 8 bit ağırlıklı 16 bit aktivasyonlar (deneysel)
Bu deneysel bir kuantizasyon şemasıdır. "Yalnızca tamsayı" şemasına benzer, ancak aktivasyonlar 16 bitlik aralıklarına göre nicelenir, ağırlıklar 8 bit tamsayı olarak nicelenir ve sapma 64 bit tamsayı olarak nicelenir. Buna ayrıca 16x8 niceleme denir.
Bu nicelemenin ana avantajı, doğruluğu önemli ölçüde artırabilmesi, ancak model boyutunu yalnızca biraz artırabilmesidir.
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.representative_dataset = representative_dataset converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8] tflite_quant_model = converter.convert()
Modeldeki bazı işleçler için 16x8 niceleme desteklenmiyorsa, model yine de nicelenebilir, ancak desteklenmeyen işleçler değişken durumda tutulur. Buna izin vermek için target_spec'e aşağıdaki seçenek eklenmelidir.
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.representative_dataset = representative_dataset converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8, tf.lite.OpsSet.TFLITE_BUILTINS] tflite_quant_model = converter.convert()
Bu niceleme şeması tarafından sağlanan doğruluk iyileştirmelerinin yer aldığı kullanım durumlarına örnekler:
- süper çözünürlük,
- gürültü engelleme ve hüzmeleme gibi ses sinyali işleme,
- görüntü parazit giderme,
- Tek bir görüntüden HDR rekonstrüksiyonu.
Bu nicelemenin dezavantajı:
- Şu anda çıkarım, optimize edilmiş çekirdek uygulamasının olmaması nedeniyle 8 bitlik tam sayıdan belirgin şekilde daha yavaştır.
- Şu anda mevcut donanım hızlandırmalı TFLite delegeleri ile uyumsuzdur.
Bu niceleme modu için bir eğitim burada bulunabilir.
model doğruluğu
Ağırlıklar eğitimden sonra nicelendirildiğinden, özellikle daha küçük ağlar için bir doğruluk kaybı olabilir. TensorFlow Hub'da belirli ağlar için önceden eğitilmiş tamamen nicelenmiş modeller sağlanır. Doğruluktaki herhangi bir bozulmanın kabul edilebilir sınırlar içinde olduğunu doğrulamak için nicelenmiş modelin doğruluğunu kontrol etmek önemlidir. TensorFlow Lite model doğruluğunu değerlendirmek için araçlar vardır.
Alternatif olarak, doğruluk düşüşü çok yüksekse niceleme farkında eğitim kullanmayı düşünün. Ancak bunu yapmak, sahte niceleme düğümleri eklemek için model eğitimi sırasında değişiklikler gerektirirken, bu sayfadaki eğitim sonrası niceleme teknikleri önceden eğitilmiş mevcut bir modeli kullanır.
Nicemlenmiş tensörler için temsil
8 bit niceleme, aşağıdaki formülü kullanarak kayan nokta değerlerine yaklaşır.
\[real\_value = (int8\_value - zero\_point) \times scale\]
Temsil iki ana bölümden oluşur:
Sıfır noktası 0'a eşit olan [-127, 127] aralığında int8 iki'nin tümleyen değerleri ile temsil edilen eksen başına (kanal başına olarak da bilinir) veya tensör başına ağırlıklar.
Per-tensor aktivasyonları/girişleri, [-128, 127] aralığında int8 iki'nin tümleyen değerleri ve [-128, 127] aralığında bir sıfır noktası ile temsil edilir.
Niceleme şemamızın ayrıntılı bir görünümü için lütfen niceleme spesifikasyonumuza bakın. TensorFlow Lite'ın delege arayüzüne bağlanmak isteyen donanım satıcılarının burada açıklanan niceleme şemasını uygulamaları önerilir.