axinc-ai / ailia-models-tflite

Quantized version of model library
23 stars 1 forks source link

ADD midas #31

Closed kyakuno closed 1 year ago

kyakuno commented 1 year ago

下記のONNXからtflite (float)とtflite (int8)を追加する。 https://github.com/axinc-ai/ailia-models/tree/master/depth_estimation/midas

kyakuno commented 1 year ago

30 と同じ手順で進めていただければと思います。

craft-c commented 1 year ago

入出力画像のリサイズについてメモ

画像のアスペクト比を "維持せずに" リサイズを行っています。 アスペクト比を維持したままだと、パディング部分も推論されてしまい、良好な結果が得られません。

image image

craft-c commented 1 year ago

学習モデル .tflite(int8) 版について [03/10 14:45 現在]

COCO2017データセット 5000枚で 学習した (int8)版の学習モデルの精度が良くありません。

ADD U2Net #47 こちらのissueの内容を参考に、再度学習モデルの生成を行ってみます。

image

craft-c commented 1 year ago

~~残りの作業 ・推論フレームワーク ailia-TF runtime を使えるようにする  (※なぜかailia_tflite.dll が見つからないエラーが出る) ・(int8)版 (float)版の .tflite 学習モデル 再生成

47 を参考に

  ↓ ・Readme等ドキュメントを作成し、GitHubへ~~

craft-c commented 1 year ago

(メモ) ・onnx2tfを用いて onnx → .tflite (float32)(int8) へ変換

 midas.onnx の入力は dynamic dimension になっているので、-ois input:1,3,384,384 オプションが必要。  また、saved_modelの出力のためには -dgcオプション も必要

 結果として、onnx2tf -i midas.onnx -ois input:1,3,384,384 -dgc のコマンドで、.tflite(float32) 及び saved_model が出力される

craft-c commented 1 year ago

しかし、onnx2tf を用いて 生成した .tflite(float32) モデルは、ailia-tf runtime で推論しようとするとエラーが出る。 公式のTFならエラーは出ない。

~”原因調査中"~

エラーの内容 raise AiliaTFLiteError(f"ailia tflite runtime error "+detail, status) ailia_tflite.AiliaTFLiteError: ailia tflite runtime error (operator is not supported. (idx.2 operator.PADV2)) code:-7

kyakuno commented 1 year ago

PADV2については、ailia TFLite Runtime側の更新で対応しようと思いますので、ailiaでは動かなくても問題ありません。

craft-c commented 1 year ago

[現状メモ] ・onnx2tf を用いて変換した .tflite(int8) のモデルで精度が出ない。 ・また、1枚の画像推論に要する時間が異様に長い(15分~)。 →再度 int8 版の モデル生成を見直してみる。

@kyakuno ・float32の精度は良好なので、いったんfloat32版のみでPRしても良いでしょうか?

image

kyakuno commented 1 year ago

@craft-c キャリブレーション画像にテスト用の入力画像を使った場合に、どのような出力が得られるか確認いただくことは可能でしょうか。キャリブレーション画像に入力画像を使うと精度が出る場合は、キャリブレーション用のデータセットを別のものにした方がいいかもしれません。tfliteは内部的に、floatで推論して、tensorのmin/maxを計算してそのレンジでint8に量子化しているため、テスト用の推論画像1枚を使って量子化して推論するのが、テスト用の画像では最も精度が出ると思います。ただし、汎化性能はなくなるので、あくまでテスト用になります。

kyakuno commented 1 year ago

@craft-c また、コードも確認したいため、一旦、現状でPRをいただければと思います。合わせて、convertというサブフォルダを作成し、変換に使用したスクリプトも同梱いただければと思います。

ailia-models-tflite/depth_estimation/midas/midas.py : サンプル ailia-models-tflite/depth_estimation/midas/convert/convert.sh : openvino2tensorflowの呼び出しスクリプト ailia-models-tflite/depth_estimation/midas/convert/quantize.py : 量子化スクリプト(キャリブレーションディレクトリは引数で与える)

kyakuno commented 1 year ago

処理時間については、Google公式のtensorflowがIntelに対応していないために重いだけですので、ailia tflite runtimeが対応すれば高速化される想定です。

craft-c commented 1 year ago

先ほど示した結果は "onnx2tf" を用いて変換したモデルなのですが、int8版の.tfliteモデルについて、僕が少し勘違いしていたかもしれません。

1枚目の図に示すように、onnx2tfを用いて midas.onnx を変換すると、saved_model内に 「midas_full_integer_quant.tffile」が生成されます。僕はこのファイルが int8版の.tfliteモデル だと思っていたのですが、これは間違いでしょうか?

要するに2枚目の画像のように、この「saved_model」+「キャリブレーション画像」を用いて量子化したファイルが int8版の.tfliteモデルになるのでしょうか?

image image

craft-c commented 1 year ago

@kyakuno あと、確認なのですが、PRは main へ向けて行えば良いですか? それとも開発用の他のブランチですか?

一応、コードの確認だけでしたら、midasブランチをGitHubへPushしてあるので、そちらから確認できます。 https://github.com/axinc-ai/ailia-models-tflite/tree/midas

気になる部分がいくつか出てきたので、PRはもう少し待ってもらえますか?

kyakuno commented 1 year ago

onnx2tensorflowで出てくる量子化モデルは、乱数で量子化されたモデルであるため、精度が出ない可能性があります。 そのため、kerasのsaved_modelを出力した後、pythonで量子化を行なっていただければと思います。 PRはmainへ向けて行えば問題ありません。 PRの時期については了解しました。

craft-c commented 1 year ago

@kokuno1122

kokunoさんへ

初めまして。 先々週からaxellのインターンでお世話になっています。 tanikubo です。

midasサンプルにおいて、 .onnx ファイルを .tflite(int8) へ変換する作業で詰まっています。 kokunoさんが issue #47 [ADD U2Net] で同様の作業をされていたので質問があります。

・まず、私はsaved_modelの出力に onnx2tf を用いているのですが、コマンドを実行する際、引数の指定において注意する点はありますか?  私はmidas.onnx の変換に際して、onnx2tf -i midas.onnx -osd -ois input:1,3,384,384 -dgc のコマンドを実行しました。

・可能でしたら、出力されたsaved_modelを量子化する際に使用したpythonスクリプト を見せていただけませんか?

よろしくお願いします。

kokuno1122 commented 1 year ago

@craft-c はじめまして。ご連絡ありがとうございます! 私も量子化は今回のPRではじめて実施したため、知見があるわけではないので、 適切な回答できないかもしれません。 コマンドで色々試してみて、精度が出るものを採用したという感じです。

使用したコマンドは下記です。 onnx2tf -i ~.onnx -oiqt

量子化のサンプルは、こちらが参考になると思います!

kokuno1122 commented 1 year ago

@craft-c numpyでキャリブレーションのデータを作成しておいて、 それをコマンドで読み込ませる方法もあるようです。 下記のページで"-qcind"オプションを検索してみてください! https://github.com/PINTO0309/onnx2tf

データはこの方法でつくるようです https://github.com/PINTO0309/onnx2tf#6-calibration-data-creation-for-int8-quantization

kokuno1122 commented 1 year ago

@craft-c 自分も次のモデルの量子化がうまくできなくて試行錯誤してるので、 似た状況かもしれませんね。またなにか分かれば共有しますね!

craft-c commented 1 year ago

了解しました! ありがとうございます。

craft-c commented 1 year ago

@kokuno1122 .tflite(int8) midasサンプルにおいては、 「onnx2tf」を使う方法よりも「openvino2tensorflow」を使う方法の方が精度が出ているように思います。 image image

craft-c commented 1 year ago

@kokuno1122

また、"-qcind"オプション を使ってキャリブレーションする方法については、MEAN と STD に何を指定するのかよく理解できませんでした。

そもそも僕の場合、「onnx2tf」のやり方 + 量子化のPythonスクリプトを用いる方法こちら で精度が出ないので、saved_model の出力の時点で何か間違っているのかもしれません。

現状報告でしたm(__)m

kyakuno commented 1 year ago

meanとstdは画像の前処理の値だと思います。例えば、imagenetの前処理を行う場合、下記のような前処理で、値を-1.0 - 1.0に正規化します。

        mean = np.array([0.485, 0.456, 0.406])
        std = np.array([0.229, 0.224, 0.225])
        image = image / 255.0
        for i in range(3):
            image[:, :, i] = (image[:, :, i] - mean[i]) / std[i]
        return image
kyakuno commented 1 year ago

meanとstdの値は学習時にどういう設定を使ったによって決まり、meanとstdに合わせた乱数を作ってキャリブレーションしているのではないかと思います。

craft-c commented 1 year ago

現状メモ

int8モデルを用いる推論の際に、 dtype = float にすると、精度がよくなりました。

推論結果をまとめたpdfを添付します。

大きな問題点は無いように思います。 ~細かい部分を確認した後、PRを起票したいと思います。~

midas_result_0410.pdf