この記事は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 Zoo の vgg16-7.onnx を使用しました👀
蜂(Bee)の画像で推論してみます。
※ぱくたその画像を使用
以降のスクリプトは、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})
上位5クラスの推論結果を出してみます。
result = np.array(result).squeeze()
print(np.argsort(result)[::-1][:5])
あっていそうですね👀
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')
上位5クラスの推論結果を出してみます。
result = np.array(result).squeeze()
print(np.argsort(result)[::-1][:5])
あっていそうですね👀
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'
以上。