![](/img/trans.png)
[英]Masked object disapear when converting image from float32 into uint8
[英]Converting SSD object detection model to TFLite and quantize it from float to uint8 for EdgeTPU
我在將 SSD object 檢測 model 轉換為 EdgeTPU 的 uint8 TFLite 時遇到問題。
據我所知,我一直在不同的論壇、堆棧溢出線程和 github 問題中進行搜索,我認為我正在遵循正確的步驟。 我的 jupyter 筆記本上一定有問題,因為我無法實現我的建議。
我正在與您分享我在 Jupyter Notebook 上解釋的步驟。 我想會更清楚。
#!/usr/bin/env python
# coding: utf-8
import os
import pathlib
# Clone the tensorflow models repository if it doesn't already exist
if "models" in pathlib.Path.cwd().parts:
while "models" in pathlib.Path.cwd().parts:
os.chdir('..')
elif not pathlib.Path('models').exists():
!git clone --depth 1 https://github.com/tensorflow/models
import matplotlib
import matplotlib.pyplot as plt
import pathlib
import os
import random
import io
import imageio
import glob
import scipy.misc
import numpy as np
from six import BytesIO
from PIL import Image, ImageDraw, ImageFont
from IPython.display import display, Javascript
from IPython.display import Image as IPyImage
import tensorflow as tf
import tensorflow_datasets as tfds
from object_detection.utils import label_map_util
from object_detection.utils import config_util
from object_detection.utils import visualization_utils as viz_utils
#from object_detection.utils import colab_utils
from object_detection.utils import config_util
from object_detection.builders import model_builder
%matplotlib inline
!tflite_convert --saved_model_dir=/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/saved_model --output_file=/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model.tflite
PATH_TO_LABELS = '/home/jose/codeWorkspace-2.4.1/tf_2.4.1/models/research/object_detection/data/mscoco_label_map.pbtxt' category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)
.tflite_convert --saved_model_dir=/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/saved_model --output_file=/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model.tflite
def representative_dataset_gen(): folder = "/home/jose/codeWorkspace-2.4.1/tf_2.4.1/images_ssd_mb2_2" image_size = 320 raw_test_data = [] files = glob.glob(folder+'/*.jpeg') for file in files: image = Image.open(file) image = image.convert("RGB") image = image.resize((image_size, image_size)) #Quantizing the image between -1,1; image = (2.0 / 255.0) * np.float32(image) - 1.0 #image = np.asarray(image).astype(np.float32) image = image[np.newaxis,:,:,:] raw_test_data.append(image) for data in raw_test_data: yield [data]
####THIS IS A RANDOM-GENERATED DATASET#### def representative_dataset_gen(): for _ in range(320): data = np.random.rand(1, 320, 320, 3) yield [data.astype(np.float32)]
converter = tf.lite.TFLiteConverter.from_saved_model('/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/saved_model') converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8, tf.lite.OpsSet.SELECT_TF_OPS] converter.inference_input_type = tf.uint8 converter.inference_output_type = tf.uint8 converter.allow_custom_ops = True converter.representative_dataset = representative_dataset_gen tflite_model = converter.convert()
轉換步驟返回警告。
警告:absl:對於包含無法量化的不受支持的操作的 model 輸入,
inference_input_type
屬性將默認為原始類型。 警告:absl:對於包含無法量化的不受支持的操作的 model 輸出,inference_output_type
屬性將默認為原始類型。
這讓我覺得轉換是不正確的。
with open('/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model_full_integer_quant.tflite'.format('/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/saved_model'), 'wb') as w: w.write(tflite_model) print("tflite convert complete. - {}/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model_full_integer_quant.tflite".format('/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/saved_model'))
我讀到建議為此使用 nightly 。 所以就我而言,版本是 2.6.0
print(tf.version.VERSION)
interpreter = tf.lite.Interpreter(model_path="/home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model_full_integer_quant.tflite") interpreter.allocate_tensors() print(interpreter.get_input_details()) print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") print(interpreter.get_output_details())
我得到以下信息:
[{'name': 'serving_default_input:0', 'index': 0, 'shape': array([ 1, 320, 320, 3], dtype=int32), 'shape_signature': array([ 1, 320, 320, 3], dtype=int32), 'dtype': <class 'numpy.uint8'>, 'quantization': (0.007843137718737125, 127), 'quantization_parameters': {'scales': array([0.00784314], dtype= float32), 'zero_points': 數組([127], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}] @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@
[{'name': 'StatefulPartitionedCall:31', 'index': 377, 'shape': array([ 1, 10, 4], dtype=int32), 'shape_signature': array([ 1, 10, 4] , dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points ': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}, {'name': 'StatefulPartitionedCall:32', 'index': 378, 'shape': array( [ 1, 10], dtype=int32), 'shape_signature': array([ 1, 10], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0) , 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}, { 'name': 'StatefulPartitionedCall:33', 'index': 379, 'shape': array([ 1, 10], dtype=int32), 'shape_signature': array([ 1, 10], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_poin ts': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}, {'name': 'StatefulPartitionedCall:34', 'index': 380, 'shape': array ([1], dtype=int32), 'shape_signature': array([1], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters ': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]
所以,我認為它沒有正確量化它
.edgetpu_compiler -s /home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model_full_integer_quant.tflite
jose@jose-VirtualBox:~/python-envs$ edgetpu_compiler -s /home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model_full_integer_quant.tflite Edge TPU 編譯器版本 15.0.340273435
Model 在 1136 毫秒內編譯成功。
Input model: /home/jose/codeWorkspace-2.4.1/tf_2.4.1/tflite/model_full_integer_quant.tflite Input size: 3.70MiB Output model: model_full_integer_quant_edgetpu.tflite Output size: 4.21MiB On-chip memory used for caching model parameters: 3.42 MiB On-chip memory remaining for caching model parameters: 4.31MiB Off-chip memory used for streaming uncached model parameters: 0.00B Number of Edge TPU subgraphs: 1 Total number of operations: 162 Operation log: model_full_integer_quant_edgetpu.log
Model 編譯成功,但 Edge TPU 並不支持所有操作。 model 的一部分將在 CPU 上運行,這會更慢。 如果可能,請考慮更新您的 model 以僅使用 Edge TPU 支持的操作。 有關詳細信息,請訪問 g.co/coral/model-reqs。 將在 Edge TPU 上運行的操作數:112 將在 CPU 上運行的操作數:50
操作員計數狀態
LOGISTIC 1 操作在其他方面受支持,但由於某些未指定的限制而未映射 DEPTHWISE_CONV_2D 14 不支持多個子圖 DEPTHWISE_CONV_2D 37 映射到邊緣 TPU QUANTIZE 1 映射到邊緣 TPU QUANTIZE 4 否則支持操作,但由於某些未指定而未映射限制 CONV_2D
58 映射到邊緣 TPU CONV_2D 14
不支持多個子圖 DEQUANTIZE
1 操作正在處理不受支持的數據類型 DEQUANTIZE 1 操作在其他方面受支持,但由於某些未指定的限制而未映射 CUSTOM 1
操作正在處理不受支持的數據類型 ADD
2 不支持多於一個子圖 ADD
10 映射到邊緣 TPU 連接 1
否則支持操作,但由於某些未指定的限制而未映射 CONCATENATION 1 不支持多個子圖 RESHAPE 2
否則支持操作,但由於某些未指定的限制而未映射 RESHAPE 6
映射到邊緣 TPU RESHAPE 4 不支持多個子圖 PACK 4
張量的等級不受支持(最多映射 3 個最內層維度)
我准備的jupyter notebook可以在以下鏈接找到: https://github.com/jagumiel/Artificial-Intelligence/blob/main/tensorflow-scripts/Step-by-step-explaining-problems.ipynb
有沒有我遺漏的步驟? 為什么沒有導致我的轉換?
非常感謝您提前。
正如@JaesungChung 回答的那樣,這個過程做得很好。
我的問題出在運行 .tflite model 的應用程序上。 我將我的 model output 量化為 uint8,因此我必須重新調整獲得的值以獲得正確的結果。
即我有 10 個對象,因為我要求所有檢測到的對象得分高於 0.5。 我的結果沒有按比例縮放,因此檢測到的對象分數可能是完美的 104。我必須重新縮放該數字除以 255。
繪制我的結果時也發生了同樣的情況。 所以我不得不把這個數字除以高度和寬度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.