LoginSignup
19
4

More than 1 year has passed since last update.

【Python】あれ? dnnモジュールのONNX推論遅くねえ? ※2021/12/14時点

Last updated at Posted at 2021-12-15

この記事はOpenCV Advent Calendar 2021の16日目の記事です。

結論

遅いです(ONNXランタイムと比較して)
※デフォルトバックエンド & CPU推論

でも、バージョンアップ毎にどんどん早くなり、対応レイヤーも増えているので、今後に期待です🦔
また、readNet() シリーズは、統一された処理で整備されているため使いやすいです。今後に期待です🦔
そして、readNet() シリーズは、OpenCVをインストールすれば使用できるため使い勝手が良く、今後に期待です🦔 ※環境による

readNet() シリーズ

  • readNet()
    ※readNet()はモデルの拡張子や引数から以下のAPIを呼び分ける
  • readNetFromCaffe()
  • readNetFromDarknet()
  • readNetFromModelOptimizer()
  • readNetFromONNX()
  • readNetFromTensorflow()
  • readNetFromTorch()

バージョン

以下のバージョンで確認しました。

pip show opencv-python

Name: opencv-python
Version: 4.5.4.60
(省略)
pip show onnxruntime

Name: onnxruntime
Version: 1.9.0
(省略)

計測環境

Google Colaboratory上でCPU推論を行い「%%time」や「%%timeit」を使用して推論時間を計測しています。
(本来はもっと厳密な方法と環境で計測すべきでしょうが、、、ご容赦を。。。🙇

参考:CPU情報
!cat /proc/cpuinfo

processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 79
model name  : Intel(R) Xeon(R) CPU @ 2.20GHz
stepping    : 0
microcode   : 0x1
cpu MHz     : 2199.998
cache size  : 56320 KB
physical id : 0
siblings    : 2
core id     : 0
cpu cores   : 1
apicid      : 0
initial apicid  : 0
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat md_clear arch_capabilities
bugs        : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa
bogomips    : 4399.99
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

processor   : 1
vendor_id   : GenuineIntel
cpu family  : 6
model       : 79
model name  : Intel(R) Xeon(R) CPU @ 2.20GHz
stepping    : 0
microcode   : 0x1
cpu MHz     : 2199.998
cache size  : 56320 KB
physical id : 0
siblings    : 2
core id     : 0
cpu cores   : 1
apicid      : 1
initial apicid  : 1
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat md_clear arch_capabilities
bugs        : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa
bogomips    : 4399.99
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

ONNXランタイム VS OpenCV DNNモジュール VGG16推論時間比較

CPUで推論した場合、ぼちぼち推論時間がかかるVGG16で比較してみます。
VGG16のONNXモデルは、ONNX Model Zoovgg16-7.onnx を使用しました👀

蜂(Bee)の画像で推論してみます。
image.png
ぱくたその画像を使用

以降のスクリプトは、Qiita-AdventCalendar-20211216-01-OpenCV.ipynbでも公開しています。

ONNXランタイム

モデルをロードして

import onnxruntime
onnx_session = onnxruntime.InferenceSession('vgg16-7.onnx')

画像の前処理をして

import cv2 as cv
import numpy as np

# 前処理
input_image = cv.resize(image, dsize=(224, 224))
input_image = cv.cvtColor(input_image, cv.COLOR_BGR2RGB)

mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
input_image = (input_image / 255 - mean) / std

input_image = input_image.transpose(2, 0, 1).astype('float32')
input_image = input_image.reshape(-1, 3, 224, 224)

# 入力名・出力名取得
input_name = onnx_session.get_inputs()[0].name
output_name = onnx_session.get_outputs()[0].name

推論時間計測します。

%%time

# 推論
result = onnx_session.run([output_name], {input_name: input_image})

451msと出ました👀
image.png

上位5クラスの推論結果を出してみます。

result = np.array(result).squeeze()
print(np.argsort(result)[::-1][:5])

image.png
あっていそうですね👀
309:Bee(蜂)
94:hummingbird(ハチドリ)
308:fly(蝿)
95:jacamar(キツツキ目の鳥(キリハシ))
946:cardoon(菊科の植物(カルドン))

OpenCV dnnモジュール

モデルをロードして

import cv2 as cv
net = cv.dnn.readNet('vgg16-7.onnx')

画像の前処理をして

import numpy as np

# 前処理
input_image = cv.resize(image, dsize=(224, 224))
input_image = cv.cvtColor(input_image, cv.COLOR_BGR2RGB)

mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
input_image = (input_image / 255 - mean) / std
input_image = input_image.astype('float32')

input_blob = cv.dnn.blobFromImage(input_image)

# 入力BLOB設定
net.setInput(input_blob, 'data')

推論時間計測します。

%%time

# 推論
result = net.forward('vgg0_dense2_fwd')

574msと出ました👀
image.png

上位5クラスの推論結果を出してみます。

result = np.array(result).squeeze()
print(np.argsort(result)[::-1][:5])

image.png
あっていそうですね👀
309:Bee(蜂)
94:hummingbird(ハチドリ)
308:fly(蝿)
95:jacamar(キツツキ目の鳥(キリハシ))
946:cardoon(菊科の植物(カルドン))

ONNXランタイム VS OpenCV dnnモジュール

dnnモジュールでの推論のほうが、若干遅いですね、、、👀

モデル ONNXランタイム dnnモジュール
VGG16 451ms 574ms(+27.2%)

ONNXランタイム VS OpenCV DNNモジュール その他いくつかのモデルの推論時間比較

さきほどは推論結果も確認する都合上「%%time」で計測していましたが、
今回はいくつかのモデルに対して「%%timeit -n 10」で計測します。
MobileNetV2がかなり遅いですね、、、👀

モデル ONNXランタイム dnnモジュール
VGG16 488ms 616ms(+26.2%)
MobileNetV2 14.7ms 36.1ms(+145.5%)
ResNet50V1 124ms 167ms(+34.6%)

上記の計測に使用したスクリプトは、Qiita-AdventCalendar-20211216-02-OpenCV.ipynbで公開しています。

ONNXランタイム VS OpenCV DNNモジュール 古いOpenCV(4.1.2.30)

比較するとdnnモジュールの推論のほうが遅いのですが、
昔はもっともっと遅かった記憶があります、、、🤔

というわけで若干古め(4.1.2.30)のOpenCVで試してみます。
明らかに4.5.4.60のほうが早くなっていますね👾

モデル ONNXランタイム dnn(4.5.4.60) dnn(4.1.2.30)
VGG16 488ms 616ms(+26.2%) 867ms(+77.7%)
MobileNetV2 14.7ms 36.1ms(+145.5%) ロード失敗
ResNet50V1 124ms 167ms(+34.6%) 244ms(+96.8%)

上記の計測時に使用したスクリプトは、Qiita-AdventCalendar-20211216-03-OpenCV.ipynbで公開しています。

4.1.2.30時点のdnnモジュールではONNX Model zooのMobileNetV2は、
以下のエラーが出て読み込みが出来ませんでした。

error: OpenCV(4.1.2) /io/opencv/modules/dnn/src/layers/reshape_layer.cpp:141: 
error: (-215:Assertion failed) dstTotal != 0 in function 'computeShapeByReshapeMask'

試したかったけど OpenCV 4.5.4.60 のdnnモジュールで読みこめなかったモデルたち

yolov3-10.onnx

以下のエラーが発生して読み込めず。

error: OpenCV(4.5.4) /tmp/pip-req-build-3129w7z7/opencv/modules/dnn/src/onnx/onnx_graph_simplifier.cpp:692: 
error: (-210:Unsupported format or combination of formats) Unsupported data type: BOOL in function 'getMatFromTensor'

yolov4.onnx

以下のエラーが発生して読み込めず。

error: OpenCV(4.5.4) /tmp/pip-req-build-3129w7z7/opencv/modules/dnn/src/onnx/onnx_importer.cpp:739: 
error: (-2:Unspecified error) in function 'handleNode'

MaskRCNN-10.onnx

以下のエラーが発生して読み込めず。

error: OpenCV(4.5.4) /tmp/pip-req-build-3129w7z7/opencv/modules/dnn/src/onnx/onnx_importer.cpp:739: 
error: (-2:Unspecified error) in function 'handleNode'

以上。

19
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
4