axinc-ai / ailia-models

The collection of pre-trained, state-of-the-art AI models for ailia SDK
2.02k stars 319 forks source link

ADD face-detection-adas-0001 #996

Closed kyakuno closed 1 year ago

kyakuno commented 1 year ago

https://github.com/openvinotoolkit/open_model_zoo/blob/master/models/intel/face-detection-adas-0001/README.md

kyakuno commented 1 year ago

openvinoのage genderの精度を上げるために顔検出のモデルを合わせ込むのが目的。 https://github.com/axinc-ai/ailia-models/issues/560

kyakuno commented 1 year ago

openvino公式のデモの構成。 https://docs.openvino.ai/latest/omz_demos_interactive_face_detection_demo_cpp.html#doxid-omz-demos-interactive-face-detection-demo-cpp

kyakuno commented 1 year ago

@ooe1123 他のチケットが落ち着いたタイミングで、こちらを検討いただけると嬉しいです。

kyakuno commented 1 year ago

face_detectionカテゴリに追加するとともに、age_gender_detection_retailの方に、既存のblazefaceとface_detection_adasを選択できるようにしたいと考えています。

kyakuno commented 1 year ago

face detectionからage genderへの投げ方は下記を参考にして頂ければと思います。 https://github.com/openvinotoolkit/open_model_zoo/tree/master/demos/interactive_face_detection_demo/cpp

kyakuno commented 1 year ago

実装的には1.2倍して正方形化しているようです。 https://github.com/openvinotoolkit/open_model_zoo/blob/master/demos/interactive_face_detection_demo/cpp/detectors.cpp

ooe1123 commented 1 year ago

○ face-detection-adas-0001 のonnxエクスポート

こちらの convert_script.txt のスクリプトを参考に実行したが、 The DetectionOutput layer is not yet implemented. のエラーが発生する。 [参考] https://github.com/PINTO0309/openvino2tensorflow/issues/89#issuecomment-1010491478

openvino2tensorflow/openvino2tensorflow/openvino2tensorflow.py の部分を以下のように修正し、

    # layers
    for idx, layer in enumerate(layers):
        if idx >= 476:   # <- 追記
            break            # <- 追記

以下のコマンドでエクスポートできた。

python ~/openvino2tensorflow/openvino2tensorflow/openvino2tensorflow.py \
    --model_path face-detection-adas-0001.xml \
    --output_saved_model --output_pb --output_onnx --onnx_opset 11 \
    --layerids_of_the_terminating_output 256,383,475 \
    --weight_replacement_config replace.json

以下のファイルが作成される。 saved_model/0.npy saved_model/model_float32.onnx

0.npyはPriorBoxのパラメータであるが、値が適切ではないように見える。 ほとんどの値が0となっている。

>>> np.load("saved_model/0.npy")
array([[[0.9796773, 0.9497039, 0.9965132, ..., 0.       , 0.       ,
         0.       ],
        [0.1      , 0.1      , 0.2      , ..., 0.1      , 0.2      ,
         0.2      ]]], dtype=float32)
>>> np.load("saved_model/0.npy")[0][0][:20]
array([0.9796773, 0.9497039, 0.9965132, 1.0086294, 0.       , 0.       ,
       0.       , 0.       , 0.       , 0.       , 0.       , 0.       ,
       0.       , 0.       , 0.       , 0.       , 0.       , 0.       ,
       0.       , 0.       ], dtype=float32)
ooe1123 commented 1 year ago

○ open_model_zooのサンプルコードの実行結果

python ./demos/object_detection_demo/python/object_detection_demo.py -i input.png -m intel/face-detection-adas-0001/FP32/face-detection-adas-0001.xml -at ssd -o output.png

image

○ PINTO_model_zooのサンプルコードの実行結果  (videoモードにしか対応していないので、画像ファイルを読めるように少し修正が必要)

python ~/PINTO_model_zoo/179_person-detection-0202/demo/demo_person-detection-0202_onnx.py \
    --input_size 384,672 \
    --model ~/open_model_zoo/intel/face-detection-adas-0001/FP32/saved_model/model_float32.onnx \
    --npy ~/open_model_zoo/intel/face-detection-adas-0001/FP32/saved_model/0.npy

kekka

PriorBoxのパラメータ以外にも問題がありそう。 https://github.com/PINTO0309/PINTO_model_zoo/blob/main/179_person-detection-0202/demo/demo_person-detection-0202_onnx.py#L71 常にclass_id=0のscoreを取っているところを、id=1に変更すると正しい結果が得られた。 (id=0だと、背景領域を拾ってしまっている)

detection_outの処理は、こちらの実装が参考になる。 https://qiita.com/GushiSnow/items/8c946208de0d6a4e31e7#ssd%E3%81%A7%E5%BF%85%E8%A6%81%E3%81%AA%E5%87%A6%E7%90%86%E3%81%AE%E8%A8%98%E8%BF%B0

ooe1123 commented 1 year ago

PriorBoxのパラメータはOpenVINOモデルから直接取得する。

○ face-detection-adas-0001.xml 以下のように修正して、モデルのoutputからPriorBoxを得ることができる。

    <layers>
                ...
        <layer id="477" name="" type="Result" version="opset1">
            <input>
                <port id="0" precision="FP32">
                    <dim>1</dim>
                    <dim>2</dim>
                    <dim>40448</dim>
                </port>
            </input>
        </layer>
    </layers>
    <edges>
                ...
        <edge from-layer="475" from-port="7" to-layer="477" to-port="0"/>  <-- 修正 (476→477)
        <edge from-layer="476" from-port="3" to-layer="477" to-port="0"/>  <-- 削除
    </edges>