7.8. Tensör G/Ƕ
Motor giriş tarafında tek bir tensör kabul eder ve çıkış tarafında bir veya daha fazlasını üretir. Tensörler, numpy bölümünde tanıtılan şekil, dtype ve tanımlayıcı sözcük dağarcığına sahip ndarray nesneleridir. Şekilleri ve dtype’ları model dosyasından gelir ve input_shape / output_shape ve input_dtype / output_dtype aracılığıyla raporlanır.
7.8.1. Kuantizasyon¶
Kameranın çalıştırdığı çoğu ağ, kameranın RAM ve hesaplama bütçesine sığmak için kuantize edilmiş tamsayı tensörleri – int8 ya da uint8 – üzerinde çalışır. Kuantize edilmiş bir tensör, gerçek değerli sayıları tensör başına bir ölçek ve sıfır noktası aracılığıyla temsil eden tamsayı değerleri taşır:
Ölçek ve sıfır noktası, modelin eğitim zamanı kalibrasyonundan gelir ve model dosyasında saklanır. Bunlar input_scale, input_zero_point, output_scale ve output_zero_point olarak açığa çıkarılır – her biri giriş veya çıkış tensörü başına bir girdiye sahip bir liste.
ml.utils.quantize() ve ml.utils.dequantize(), formülleri belirtilen bir çıkış indeksine karşı uygular:
import ml.utils
real_tensor = ml.utils.dequantize(model, q_tensor, index=0)
q_tensor = ml.utils.quantize(model, real_tensor, index=0)
Verilen indeksteki çıkış dtype’ı zaten float olduğunda her iki fonksiyon da değeri değiştirmeden döndürür, dolayısıyla çağrı modelin kuantizasyon durumundan bağımsız olarak güvenlidir.
7.8.2. Betiğin çıkış tarafında gördüğü şey¶
predict() metodunun döndürdüğü şey, bir son işlemcinin kayıtlı olup olmadığına bağlıdır.
Son işlemci olmadığında, motorun ham tamsayı çıkışları float’a otomatik dekuantize edilir ve float ndarray nesnelerinin bir listesi olarak döndürülür. Betik, okunmaya hazır gerçek değerli sayılar alır. Bu, tek çıkış tensörü zaten uygulamanın üzerinde yinelediği sınıf başına güven skorlarının bir listesi olan sınıflandırma ağları için doğru yoldur – çözme adımına gerek yoktur. Aynı zamanda bilinmeyen bir modeli hızlıca çalıştırmak ya da REPL’den anlık inceleme yapmak için de kolay yoldur.
Bir son işlemci kayıtlı olduğunda (yapıcı üzerindeki postprocess= ya da predict çağrısındaki callback= aracılığıyla), ham kuantize edilmiş tensörler doğrudan son işlemcinin çağrılabilir nesnesine verilir. Son işlemci ham kuantize edilmiş tensörleri alır ve ihtiyaç duyduğu her türlü dekuantizasyondan sorumludur.
Bu ayrım bir performans tercihidir. Otomatik dekuantizasyon, her çıkış için yeni bir float tensör ayırır ve her öğeyi gezer. Her tensörden yalnızca birkaç değere ihtiyaç duyan bir son işlemci – güven skorlarını eşikle, ardından hayatta kalanlar için kutuları çöz – geri kalanını dekuantize etmenin maliyetini atlar. ml.postprocessing altında gelen kutu çözücülerin tümü bu yolu izler ve ml.utils.threshold() tam olarak bu durum için yapılmıştır: kuantize edilmiş bir skor tensörü alır ve dekuantize edilmiş değerleri gerçek değerli bir eşiği geçen indeksleri, tensörün tamamını dekuantize etmeden döndürür.