2 回答

TA貢獻1982條經驗 獲得超2個贊
當僅設置 post_training_quantize = True 時會發生什么?即為什么第一種情況可以正常工作,但第二種情況則不能。
在 TF 1.14 中,這似乎只是在 .tflite 文件中量化存儲在磁盤上的權重。這本身不會將推理模式設置為量化推理。
即,您可以擁有一個具有推理類型的 tflite 模型,float32
但post_training_quantize=True
為了減小磁盤大小并在運行時更快地加載模型,模型權重被量化(使用)。
如何估計第二種情況的均值、標準差和范圍參數?
文檔讓很多人感到困惑。讓我解釋一下我經過一些研究得出的結論:
不幸的是,量化參數/統計數據在整個 TF 庫和文檔中有 3 種等效的形式/表示:
一種)
(mean, std_dev)
乙)
(zero_point, scale)
C)
(min,max)
從 B) 和 A) 轉換:
std_dev = 1.0 / scale
mean = zero_point
從 C) 到 A) 的轉換:
mean = 255.0*min / (min - max)
std_dev = 255.0 / (max - min)
說明:quantization stats 是用于將范圍 (0,255) 映射到任意范圍的參數,您可以從 2 個方程開始:
min / std_dev + mean = 0
和max / std_dev + mean = 255
,然后按照數學計算得出上述轉換公式從 A) 到 C) 的轉換:
min = - mean * std_dev
max = (255 - mean) * std_dev
命名“mean”和“std_dev”令人困惑,在很大程度上被視為用詞不當。
回答您的問題: ,如果您的輸入圖像具有:
范圍 (0,255) 然后
mean = 0, std_dev = 1
范圍 (-1,1) 然后
mean = 127.5, std_dev = 127.5
范圍 (0,1) 然后
mean = 0, std_dev = 255
看起來在第二種情況下模型推理更快,是否取決于模型輸入是 uint8 的事實?
是的,可能。然而,量化模型通常較慢,除非您使用特定硬件的矢量化指令。TFLite 經過優化,可以運行那些針對 ARM 處理器的專用指令。從 TF 1.14 或 1.15 開始,如果您在本地機器 x86 Intel 或 AMD 上運行它,那么如果量化模型運行得更快,我會感到驚訝。[更新:在 TFLite 的路線圖上添加對 x86 向量化指令的一流支持以使量化推理比浮點更快]
'quantization': (0.0, 0) 在第一種情況下是什么意思,'quantization': (0.003921568859368563, 0),'quantization': (0.7843137383460999, 128) 在第二種情況下是什么意思?
這里的格式是 quantization: (scale, zero_point)
在您的第一種情況下,您只激活了post_training_quantize=True
,這不會使模型運行量化推理,因此無需將輸入或輸出從 float 轉換為 uint8。因此,這里的量化統計基本上null
是 ,表示為(0,0)
。
在第二種情況下,您通過提供inference_type = tf.contrib.lite.constants.QUANTIZED_UINT8
. 因此,您有輸入和輸出的量化參數,在進入模型的途中將浮點輸入轉換為 uint8,在退出時將 uint8 輸出轉換為浮點輸出。
在輸入處,進行轉換:
uint8_array = (float_array / std_dev) + mean
在輸出處,進行轉換:
float_array = (uint8_array.astype(np.float32) - mean) * std_dev
注意 .astype(float32) 這在 python 中是必要的,以獲得正確的計算
請注意,其他文本可能會使用
scale
代替,std_dev
因此除法將變為乘法,反之亦然。
這里另一個令人困惑的事情是,即使在您指定的轉換期間quantization_stats = (mean, std_dev)
,get_output_details
將返回quantization: (scale, zero_point)
,不僅形式不同(比例與 std_dev)而且順序不同!
現在要了解您為輸入和輸出獲得的這些量化參數值,讓我們使用上面的公式來推導出(min,max)
輸入和輸出的實際值 ( )的范圍。使用上面的公式我們得到:
輸入范圍:(
min = 0, max=1
是您通過提供來指定的quantized_input_stats = {input_node_names[0]: (0.0, 255.0)} # (mean, stddev)
)輸出范圍:
min = -100.39, max=99.6

TA貢獻1785條經驗 獲得超4個贊
1) 見文檔。簡而言之,這種技術可以讓你得到一個量化的 uint8 圖,其工作精度接近原始圖,并且不需要對量化模型進行進一步的訓練。然而,速度明顯低于使用傳統量化的速度。
2) 如果您的模型已經使用歸一化 [-1.0, 1.0] 輸入進行訓練,您應該設置converter.quantized_input_stats = {input_node_names[0]: (128, 127)}
,然后輸入張量的量化將接近(0.003921568859368563, 0)
。mean
是從 0 到 255 映射到浮點 0.0f 的整數值。std_dev
是 255 / (float_max - float_min)。這將解決一個可能的問題
3)Uint8神經網絡推理快2倍左右(基于設備),然后是float32推理
添加回答
舉報