axinc-ai / ailia-models-tflite

Quantized version of model library
21 stars 1 forks source link

ADD yolox_s #41

Closed kyakuno closed 1 year ago

kyakuno commented 1 year ago

yolox_sのint8版を追加する。

kyakuno commented 1 year ago

9

kyakuno commented 1 year ago

OpenVinoのインストール(2021.4.2LTS) https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit/download.html

TensorFlowDatasetsとgdownのインストール

python -m pip install tensorflow_datasets gdown

OpenVino2TensorFlowのインストール、pipだとうまく入らなかった(site_packagesにコピーされなかった)ので、githubからopenvino2tensorflowフォルダの中身を作業フォルダにコピー https://github.com/PINTO0309/openvino2tensorflow

ONNXからOpenVINOへの変換

python "C:/Program Files (x86)/Intel/openvino_2021.4.752/deployment_tools/model_optimizer/mo.py"  --input_model yolox_s.opt.onnx  --input_shape [1,3,640,640]  --output_dir openvino/640x640/FP32  --data_type FP32

numpyは1.23が必要(1.24だとnp.boolが見つからないエラーになる)

OpenVinoからtfliteへの変換

python openvino2tensorflow.py  --model_path openvino/640x640/FP32/yolox_s.opt.xml  --model_output_path saved_model_640x640 --output_saved_model --output_h5  --output_pb   --output_no_quant_float32_tflite --output_weight_quant_tflite --output_float16_quant_tflite --output_full_integer_quant_tflite

下記のエラーが出る

alueError: Dimension 1 in both shapes must be equal, but are 1600 and 400. Shapes are [1,1600] and [1,400]. for '{{node tf.concat_17/concat}} = ConcatV2[N=3, T=DT_FLOAT, Tidx=DT_INT32](Placeholder, Placeholder_1, Placeholder_2, tf.concat_17/concat/axis)' with input shapes: [1,6400,85], [1,1600,85], [1,400,85], [] and with computed input tensors: input[3] = <2>.
ERROR: Please refer to 6-7 in the README first. https://github.com/PINTO0309/openvino2tensorflow

下記を参考にweight_replacement_configを指定する必要がある。ConcatのレイヤーIDはyolox_s.opt.xmlを見て、500と501に書き換える。 https://github.com/PINTO0309/PINTO_model_zoo/tree/main/132_YOLOX

python openvino2tensorflow.py  --model_path openvino/640x640/FP32/yolox_s.opt.xml  --model_output_path saved_model_640x640 --output_saved_model  --output_no_quant_float32_tflite --weight_replacement_config replace_s.json

この段階でfloatのtfliteと量子化用のsaved_modelができる。

kyakuno commented 1 year ago

量子化

import numpy as np
import sys
import cv2
import glob

import tensorflow as tf

# settings
input_model = "saved_model_640x640"
output_model = "./output_quant.tflite"
image_folder = "E:/git/ailia-models-measurement/object_detection/data/coco2017/images"

# load validation set
img_path = glob.glob(image_folder+"/*")
if len(img_path)==0:
    print("image not found")
    sys.exit(1)

#quantize
def representative_dataset_gen():
  for i in range(len(img_path)):
    print(img_path[i])
    img = cv2.imread(img_path[i]) #BGR
    img = cv2.resize(img,(640, 640))
    ary = np.asarray(img, dtype=np.float32)
    ary = np.expand_dims(ary, axis=0)
    yield [ary]

converter = tf.lite.TFLiteConverter.from_saved_model(input_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
tflite_quant_model = converter.convert()

with open(output_model, 'wb') as o_:
    o_.write(tflite_quant_model)
kyakuno commented 1 year ago

tensorflow2.6.2だと下記のエラー

error: 'tfl.concatenation' op quantization parameters violate the same scale constraint: !quant.uniform<i8:f32, 0.028454883024096489:-118> vs. !quant.uniform<i8:f32, 0.028690401464700699:-118>
kyakuno commented 1 year ago

tensorflow2.10まで上げると変換に成功。

kyakuno commented 1 year ago

MaxPoolでNNAPI非対応のMirrorPadが挿入されるので、flatcで書き換え。

./flatc -t --strict-json --defaults-json -o . schema.fbs -- ./yolox_s_opt.tflite
./flatc -o . -b schema.fbs yolox_s_opt_opt.json
kyakuno commented 1 year ago

"opcode_index": 7を"opcode_index": 2に、MirrorPadOptionsをPadOptionsに書き換え。

kyakuno commented 1 year ago

MirrorPadはPadではなくMaxPoolのpadding=sameに置き換える方が良い。