Closed kyakuno closed 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ができる。
量子化
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)
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>
tensorflow2.10まで上げると変換に成功。
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
"opcode_index": 7を"opcode_index": 2に、MirrorPadOptionsをPadOptionsに書き換え。
MirrorPadはPadではなくMaxPoolのpadding=sameに置き換える方が良い。
yolox_sのint8版を追加する。