この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
CX事業本部の平内(SIN)です。
OpenVINO ツールキットでは、モデルをIRと呼ばれる中間表現フォーマットにして利用します。そして、同ツールキットには、各種のフレームワークで作成したモデルを、IRに変換するツールが含まれています。
今回は、Amazon SageMaker(以下、SageMaker)の組み込みアルゴリズム(画像分類)で作成したモデルを変換して使用してみました。
IRは、以下の3種類が生成可能ですが、今回の試した作業は、FP16及びFP32となっています。
- FP16 16ビット浮動小数点演算 (NCS)
- FP32 32ビット浮動小数点演算 (CPU)
- INT8 8ビット整数演算
2 モデル
変換に使用したモデルは、下記で作成したものです。
出力先に格納されている、model.tar.gzを解凍すると、3つのファイルが格納されています。
こちらは、MXNet形式のモデルです。
3 Model Optimizer
Model Optimizerは、OpenVINOツールキットをインストールする手順の中で展開されるようになっています。
参考:Model Optimizer Developer Guide
変換作業は、Model Optimizerがインストールされてたディレクトリで、mo_mxnet.py(MXNet用)を実行するだけです。
最初に、FP16用とFP32用を作成するためディレクトリを作成しておきます。
以下は、FP16で作成している例です。
$ cd /opt/intel/openvino/deployment_tools/model_optimizer
$ export WORK_DIR=/tmp/model
$ export FP_TYPE=FP16
$ python3 mo_mxnet.py --input_model $WORK_DIR/image-classification-0012.params --input_shape \[1,3,224,224\] --output_dir $WORK_DIR/$FP_TYPE --data_type $FP_TYPE
Model Optimizer arguments:
Common parameters:
- Path to the Input Model: /tmp/model/image-classification-0012.params
- Path for generated IR: /tmp/model/FP16
- IR output name: image-classification-0012
- Log level: ERROR
- Batch: Not specified, inherited from the model
- Input layers: Not specified, inherited from the model
- Output layers: Not specified, inherited from the model
- Input shapes: [1,3,224,224]
- Mean values: Not specified
- Scale values: Not specified
- Scale factor: Not specified
- Precision of IR: FP16
- Enable fusing: True
- Enable grouped convolutions fusing: True
- Move mean values to preprocess section: False
- Reverse input channels: False
MXNet specific parameters:
- Deploy-ready symbol file: None
- Enable MXNet loader for models trained with MXNet version lower than 1.0.0: False
- Prefix name for args.nd and argx.nd files: None
- Pretrained model to be merged with the .nd files: None
- Enable saving built parameters file from .nd files: False
- Use the config file: None
Model Optimizer version:
[ SUCCESS ] Generated IR version 10 model.
[ SUCCESS ] XML file: /tmp/model/FP16/image-classification-0012.xml
[ SUCCESS ] BIN file: /tmp/model/FP16/image-classification-0012.bin
[ SUCCESS ] Total execution time: 38.71 seconds.
[ SUCCESS ] Memory consumed: 944 MB.
FP32及び、FP16を作成すると、指定した出力先に、.xmlと .bin が作成されます。これが、IRフォーマットのモデルです。
4 コード
以下は、生成したIRを使用して、MacOS上で推論しているコードです。
Syohin40クラスは、商品検出のモデルをラップしたクラスで、カメラから取得した画像を、モデルの入力形式に変換して推論しています。
CPUで実行して、推論にかかった時間は、0.1〜0.3秒程度でした。
index.py
import numpy as np
import time
import cv2
import time
from openvino.inference_engine import IECore
from PIL import ImageFont, ImageDraw, Image
from model import Model
class Syohin40(Model):
def __init__(self, ie, device, model):
super().__init__(ie, device, model)
_, _, h, w = self.input_size
self.__input_height = h
self.__input_width = w
def __prepare_frame(self, frame):
initial_h, initial_w = frame.shape[:2]
scale_h, scale_w = initial_h / float(self.__input_height), initial_w / float(self.__input_width)
in_frame = cv2.resize(frame, (self.__input_width, self.__input_height))
in_frame = in_frame.transpose((2, 0, 1))
in_frame = in_frame.reshape(self.input_size)
return in_frame, scale_h, scale_w
def infer(self, frame):
in_frame, _, _ = self.__prepare_frame(frame)
result = super().infer(in_frame)
# [1, 41] => [41]
return result.squeeze()
# MacOS
ie = IECore()
device = "CPU"
syohin40 = Syohin40(ie, device, "image-classification-0012")
CLASSES = ["ポリッピー(GREEN)","OREO","カントリーマム","ポリッピー(RED)","柿の種(わさび)"
,"通のとうもろこし","CHEDDER_CHEESE","ピーナッツ","ストーンチョコ","PRETZEL(YELLOW)"
,"海味鮮","柿の種","カラフルチョコ","フルグラ(BROWN)","NOIR"
,"BANANA(BLOWN)","チーズあられ","俺のおやつ","PRIME","CRATZ(RED)"
,"CRATZ(GREEN)","揚一番","ポリッピー(YELLOW)","こつぶっこ","アスパラガス"
,"海苔ピーパック","いちご","梅しそチーズあられ","通のえだ豆","柿の種(梅しそ)"
,"PRETZEL(BLACK)","辛子明太子","CRATZ(ORANGE)","チョコメリゼ","フライドポテト(じゃがバター味)"
,"BANANA(BLUE)","でん六豆","パズル","フルグラ(RED)","PRETZEL(GREEN)"
,"フライドポテト(しお味)",]
def putText(image, text, point, size, color):
font = ImageFont.truetype("./GenShinGothic-Bold.ttf", size)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = Image.fromarray(image)
draw = ImageDraw.Draw(image)
draw.text(point, text, color, font)
image = np.asarray(image)
return cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
def main():
# OpenCV
WIDTH = 640
HEIGHT = 480
FPS = 24
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT)
cap.set(cv2.CAP_PROP_FPS, FPS)
while(True):
_, frame = cap.read()
start = time.time() # 時間計測
out = syohin40.infer(frame)
processing_time = time.time() - start
print("processing_time {}sec".format(processing_time))
# 表示
prob = np.max(out)
index = np.argmax(out)
print("Class: %s, probability: %f" % (CLASSES[index], prob))
if(0.4<prob):
text = "{} {}".format(CLASSES[index], prob)
frame = putText(frame, text, (20, int(HEIGHT) - 120), 60, (255, 255, 255))
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
main()
LD_LIBRARY_PATHに設定されているはずなのですが、何故か、IECore() からモデル生成すると、libmyriadPlugin.dylibが読み込めないというエラーとなってしまたので、ctypes.cdll.LoadLibraryで一旦読み込んでいます。
model.py
import ctypes
class Model:
def __init__(self, ie, device, model):
modelPath = "./FP32/{}".format(model)
if(device=="MYRIAD"):
modelPath = "./FP16/{}".format(model)
net = ie.read_network(modelPath + ".xml", modelPath + ".bin")
# LD_LIBRARY_PATHは、遠ているはずなのに、なぜか読み込みに失敗するので、一回読み込んでおく
ctypes.cdll.LoadLibrary('/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64/libinference_engine_lp_transformations.dylib')
ctypes.cdll.LoadLibrary('/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64/libmyriadPlugin.dylib')
self.exec_net = ie.load_network(network=net, device_name=device, num_requests=2)
self.input_name = next(iter(net.input_info))
self.output_name = next(iter(net.outputs))
self.input_size = net.input_info[self.input_name].input_data.shape
self.output_size = net.outputs[self.output_name].shape
def infer(self, data):
input_data = {self.input_name: data}
infer_result = self.exec_net.infer(input_data)
return infer_result[self.output_name]
動画は、上記のコードを実行してる様子です。
5 最後に
今回は、SageMakerで作成したモデルをOpenVINOツールキットで利用してみました。
OpenVINOツールキットでは、モデルごとにCPU、GPUを振り分けて使用したり、USBで追加可能なNCSなどがあります。
SageMakerで作成したモデルも問題なく変換して利用可能ということで、一段と、利用範囲が広がるかも知れません。