亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

理解 tf.contrib.lite.TFLiteConverter 量化參數

理解 tf.contrib.lite.TFLiteConverter 量化參數

神不在的星期二 2021-11-16 16:40:17
我正在嘗試使用 UINT8 量化,同時將 tensorflow 模型轉換為 tflite 模型:如果使用post_training_quantize = True,模型大小比原始 fp32 模型低 x4,所以我假設模型權重是 uint8,但是當我加載模型并通過interpreter_aligner.get_input_details()[0]['dtype']它的 float32獲取輸入類型時。量化模型的輸出與原始模型大致相同。converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(        graph_def_file='tflite-models/tf_model.pb',        input_arrays=input_node_names,        output_arrays=output_node_names)converter.post_training_quantize = Truetflite_model = converter.convert()轉換模型的輸入/輸出:print(interpreter_aligner.get_input_details())print(interpreter_aligner.get_output_details())[{'name': 'input_1_1', 'index': 47, 'shape': array([  1, 128, 128,   3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}][{'name': 'global_average_pooling2d_1_1/Mean', 'index': 45, 'shape': array([  1, 156], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}]另一種選擇是明確指定更多參數:模型大小比原始 fp32 模型低 x4,模型輸入類型為 uint8,但模型輸出更像是垃圾。converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(        graph_def_file='tflite-models/tf_model.pb',        input_arrays=input_node_names,        output_arrays=output_node_names)converter.post_training_quantize = Trueconverter.inference_type = tf.contrib.lite.constants.QUANTIZED_UINT8converter.quantized_input_stats = {input_node_names[0]: (0.0, 255.0)}  # (mean, stddev)converter.default_ranges_stats = (-100, +100)tflite_model = converter.convert()所以我的問題是:當 onlypost_training_quantize = True被設置時會發生什么?即為什么第一種情況可以正常工作,但第二種情況則不能。如何估計第二種情況的均值、標準差和范圍參數?看起來在第二種情況下模型推理更快,是否取決于模型輸入是 uint8 的事實?什么手段'quantization': (0.0, 0)在第一種情況下和'quantization': (0.003921568859368563, 0),'quantization': (0.7843137383460999, 128)在第二種情況?什么是converter.default_ranges_stats?
查看完整描述

2 回答

?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

當僅設置 post_training_quantize = True 時會發生什么?即為什么第一種情況可以正常工作,但第二種情況則不能。

在 TF 1.14 中,這似乎只是在 .tflite 文件中量化存儲在磁盤上的權重。這本身不會將推理模式設置為量化推理。

即,您可以擁有一個具有推理類型的 tflite 模型,float32post_training_quantize=True為了減小磁盤大小并在運行時更快地加載模型,模型權重被量化(使用)。

如何估計第二種情況的均值、標準差和范圍參數?

文檔讓很多人感到困惑。讓我解釋一下我經過一些研究得出的結論:

  1. 不幸的是,量化參數/統計數據在整個 TF 庫和文檔中有 3 種等效的形式/表示:

    • 一種) (mean, std_dev)

    • 乙) (zero_point, scale)

    • C) (min,max)

  2. 從 B) 和 A) 轉換:

    • std_dev = 1.0 / scale

    • mean = zero_point

  3. 從 C) 到 A) 的轉換:

    • mean = 255.0*min / (min - max)

    • std_dev = 255.0 / (max - min)

    • 說明:quantization stats 是用于將范圍 (0,255) 映射到任意范圍的參數,您可以從 2 個方程開始:min / std_dev + mean = 0max / std_dev + mean = 255,然后按照數學計算得出上述轉換公式

  4. 從 A) 到 C) 的轉換:

    • min = - mean * std_dev

    • max = (255 - mean) * std_dev

  5. 命名“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


查看完整回答
反對 回復 2021-11-16
?
九州編程

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推理


查看完整回答
反對 回復 2021-11-16
  • 2 回答
  • 0 關注
  • 344 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號