OpenVINO™ ランタイム API チュートリアル¶
この Jupyter ノートブックはオンラインで起動でき、ブラウザーのウィンドウで対話型環境を開きます。ローカルにインストールすることもできます。次のオプションのいずれかを選択します。
このノートブックでは、OpenVINO ランタイム API の基本について説明します。
ノートブックはヘッダーとセクションに分かれています。次のセルには、インストールとインポートのグローバル要件が含まれています。各セクションはスタンドアロンであり、前のセクションに依存しません。このチュートリアルで使用されるすべてのモデルは、あくまで例として提供されています。これらのモデルファイルは独自のモデルに置き換えることができます。正確な出力は異なりますが、プロセスは同一です
目次¶
# Required imports. Please execute this cell first.
%pip install -q "openvino>=2023.1.0"
%pip install requests tqdm ipywidgets
# Fetch `notebook_utils` module
import urllib.request
urllib.request.urlretrieve(
url='https://raw.githubusercontent.com/openvinotoolkit/openvino_notebooks/main/notebooks/utils/notebook_utils.py',
filename='notebook_utils.py'
)
from notebook_utils import download_file
Note: you may need to restart the kernel to use updated packages.
Requirement already satisfied: requests in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (2.31.0)
Requirement already satisfied: tqdm in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (4.66.1)
Requirement already satisfied: ipywidgets in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (8.1.2)
Requirement already satisfied: charset-normalizer<4,>=2 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from requests) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from requests) (3.6)
Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from requests) (2.2.0)
Requirement already satisfied: certifi>=2017.4.17 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from requests) (2024.2.2)
Requirement already satisfied: comm>=0.1.3 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipywidgets) (0.2.1)
Requirement already satisfied: ipython>=6.1.0 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipywidgets) (8.12.3)
Requirement already satisfied: traitlets>=4.3.1 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipywidgets) (5.14.1)
Requirement already satisfied: widgetsnbextension~=4.0.10 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipywidgets) (4.0.10)
Requirement already satisfied: jupyterlab-widgets~=3.0.10 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipywidgets) (3.0.10)
Requirement already satisfied: backcall in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (0.2.0)
Requirement already satisfied: decorator in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (5.1.1)
Requirement already satisfied: jedi>=0.16 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (0.19.1)
Requirement already satisfied: matplotlib-inline in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (0.1.6)
Requirement already satisfied: pickleshare in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (0.7.5)
Requirement already satisfied: prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (3.0.43)
Requirement already satisfied: pygments>=2.4.0 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (2.17.2)
Requirement already satisfied: stack-data in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (0.6.3)
Requirement already satisfied: typing-extensions in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (4.9.0)
Requirement already satisfied: pexpect>4.3 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from ipython>=6.1.0->ipywidgets) (4.9.0)
Requirement already satisfied: parso<0.9.0,>=0.8.3 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets) (0.8.3)
Requirement already satisfied: ptyprocess>=0.5 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from pexpect>4.3->ipython>=6.1.0->ipywidgets) (0.7.0)
Requirement already satisfied: wcwidth in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30->ipython>=6.1.0->ipywidgets) (0.2.13)
Requirement already satisfied: executing>=1.2.0 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from stack-data->ipython>=6.1.0->ipywidgets) (2.0.1)
Requirement already satisfied: asttokens>=2.1.0 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from stack-data->ipython>=6.1.0->ipywidgets) (2.4.1)
Requirement already satisfied: pure-eval in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from stack-data->ipython>=6.1.0->ipywidgets) (0.2.2)
Requirement already satisfied: six>=1.12.0 in /opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages (from asttokens>=2.1.0->stack-data->ipython>=6.1.0->ipywidgets) (1.16.0)
Note: you may need to restart the kernel to use updated packages.
OpenVINO ランタイムのロードと情報の表示¶
ov.Core()
で OpenVINO ランタイムを初期化します。
import openvino as ov
core = ov.Core()
OpenVINO ランタイムは、デバイスにネットワークをロードできます。ここでデバイスとは、CPU、インテル® GPU、ニューラル・コンピュート・スティック 2 などを意味します。 available_devices
プロパティーは、システムで使用可能なデバイスを示します。core.get_property()
の “FULL_DEVICE_NAME” オプションはデバイスの名前を表示します。
このノートブックでは、CPU デバイスが使用されます。統合 GPU を使用する場合、代わりに device_name="GPU"
を指定します。GPU でのネットワークのロードは CPU ネットワークのロードよりも遅くなりますが、推論は高速になる可能性があることに留意してください。
devices = core.available_devices
for device in devices:
device_name = core.get_property(device, "FULL_DEVICE_NAME")
print(f"{device}: {device_name}")
CPU: Intel(R) Core(TM) i9-10920X CPU @ 3.50GHz
モデルのロード¶
OpenVINO ランタイムを初期化した後、まず read_model()
でモデルファイルを読み取り、次に compile_model()
メソッドで指定したデバイスにコンパイルします。
OpenVINO™ はいくつかのモデル形式をサポートしており、開発者はこのタスク専用のツールを使用してモデル形式を独自の OpenVINO IR 形式に変換できます。
OpenVINO IR モデル¶
OpenVINO IR (中間表現) モデルは、ネットワーク・トポロジーに関する情報を含む .xml
ファイルと、重みとバイアスのバイナリ ーデータを含む .bin
ファイルで構成されます。OpenVINO IR 形式のモデルは、モデル変換 API を使用して取得されます。read_model()
関数は、重みファイル .bin
が同じファイル名を持ち、.xml
ファイルと同じディレクトリーに配置されていることを想定しています: model_weights_file == Path(model_xml).with_suffix(".bin")
。この場合、重みファイルの指定はオプションです。重みファイルのファイル名が異なる場合は、read_model()
の weights
パラメーターで指定できます。
OpenVINO モデル変換 API ツールは、モデルを OpenVINO IR 形式に変換するために使用されます。モデル変換 API は元のモデルを読み取り、OpenVINO IR モデル (.xml
および .bin
) 作成のため、形式変換による遅延なく推論を実行できます。オプションで、モデル変換 API は、入力形状を交互に変更したり、前処理を埋め込んだり、トレーニング部分を切り取ったりすることで、モデルを推論により適したものに調整できます。モデル変換 API を使用して既存の TensorFlow、PyTorch、または ONNX モデルを OpenVINO IR 形式に変換する方法は、tensorflow-to-openvino および pytorch-onnx-to-openvino のノートブックを参照してください。
ir_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/'
ir_model_name_xml = 'classification.xml'
ir_model_name_bin = 'classification.bin'
download_file(ir_model_url + ir_model_name_xml, filename=ir_model_name_xml, directory='model')
download_file(ir_model_url + ir_model_name_bin, filename=ir_model_name_bin, directory='model')
model/classification.xml: 0%| | 0.00/179k [00:00<?, ?B/s]
model/classification.bin: 0%| | 0.00/4.84M [00:00<?, ?B/s]
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/classification.bin')
import openvino as ov
core = ov.Core()
classification_model_xml = "model/classification.xml"
model = core.read_model(model=classification_model_xml)
compiled_model = core.compile_model(model=model, device_name="CPU")
ONNX モデル¶
ONNX は、マシンラーニング・モデルを表現するために構築されたオープン形式です。ONNX は、マシンラーニングおよびディープラーニング・モデルの構成要素であるオペレーターの共通セットと、AI 開発者がさまざまなフレームワーク、ツール、ランタイム、コンパイラーでモデルを使用できるようにする共通のファイル形式を定義します。OpenVINO は、ONNX 形式のモデルの直接読み取りをサポートしています。つまり、事前に変換することなく OpenVINO ランタイムで使用できます。
単一の .onnx
ファイルである ONNX モデルの読み取りとロードは、OpenVINO IR モデルと同じように機能します。model
引数は、ONNX モデルのファイル名を指します。
onnx_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/segmentation.onnx'
onnx_model_name = 'segmentation.onnx'
download_file(onnx_model_url, filename=onnx_model_name, directory='model')
model/segmentation.onnx: 0%| | 0.00/4.41M [00:00<?, ?B/s]
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/segmentation.onnx')
import openvino as ov
core = ov.Core()
onnx_model_path = "model/segmentation.onnx"
model_onnx = core.read_model(model=onnx_model_path)
compiled_model_onnx = core.compile_model(model=model_onnx, device_name="CPU")
ONNX モデルは、save_model()
を使用して OpenVINO IR にエクスポートできます。
ov.save_model(model_onnx, output_model="model/exported_onnx_model.xml")
PaddlePaddle モデル¶
推論用に保存された PaddlePaddle モデルは、変換なしで OpenVINO ランタイムに渡すこともできます。拡張子付きのファイル名を read_model
に渡し、save_model
で OpenVINO IR をエクスポートしました。
paddle_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/'
paddle_model_name = 'inference.pdmodel'
paddle_params_name = 'inference.pdiparams'
download_file(paddle_model_url + paddle_model_name, filename=paddle_model_name, directory='model')
download_file(paddle_model_url + paddle_params_name, filename=paddle_params_name, directory='model')
model/inference.pdmodel: 0%| | 0.00/1.03M [00:00<?, ?B/s]
model/inference.pdiparams: 0%| | 0.00/21.0M [00:00<?, ?B/s]
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/inference.pdiparams')
import openvino as ov
core = ov.Core()
paddle_model_path = 'model/inference.pdmodel'
model_paddle = core.read_model(model=paddle_model_path)
compiled_model_paddle = core.compile_model(model=model_paddle, device_name="CPU")
ov.save_model(model_paddle, output_model="model/exported_paddle_model.xml")
TensorFlow モデル¶
凍結グラフ形式で保存された TensorFlow モデルも read_model
に渡すことができます。
pb_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/classification.pb'
pb_model_name = 'classification.pb'
download_file(pb_model_url, filename=pb_model_name, directory='model')
model/classification.pb: 0%| | 0.00/9.88M [00:00<?, ?B/s]
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/classification.pb')
import openvino as ov
core = ov.Core()
tf_model_path = "model/classification.pb"
model_tf = core.read_model(model=tf_model_path)
compiled_model_tf = core.compile_model(model=model_tf, device_name="CPU")
ov.save_model(model_tf, output_model="model/exported_tf_model.xml")
TensorFlow Lite モデル¶
推論用に保存された TFLite モデルを OpenVINO ランタイムに渡すこともできます。拡張子 .tflite
が付いたファイル名を read_model
に渡し、save_model
で OpenVINO IR をエクスポートしました。
このチュートリアルでは、画像分類モデル inception_v4_quant を使用しています。これは、TensorFlow Lite で動作するように最適化された事前トレーニング済みモデルです。
from pathlib import Path
tflite_model_url = 'https://www.kaggle.com/models/tensorflow/inception/frameworks/tfLite/variations/v4-quant/versions/1?lite-format=tflite'
tflite_model_path = Path('model/classification.tflite')
download_file(tflite_model_url, filename=tflite_model_path.name, directory=tflite_model_path.parent)
model/classification.tflite: 0%| | 0.00/40.9M [00:00<?, ?B/s]
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/classification.tflite')
import openvino as ov
core = ov.Core()
model_tflite = core.read_model(tflite_model_path)
compiled_model_tflite = core.compile_model(model=model_tflite, device_name="CPU")
ov.save_model(model_tflite, output_model="model/exported_tflite_model.xml")
PyTorch モデル¶
PyTorch モデルを core.read_model
に直接渡すことはできません。このフレームワークのモデル・オブジェクトの ov.Model
は、ov.convert_model
を使用して取得できます。詳細については、pytorch-to-openvino ノートブックを参照してください。このチュートリアルでは、torchvision ライブラリーの resnet18 モデルを使用します。ov.convert_model
を使用してモデルを変換した後、core.compile_model
を使用してデバイス上でコンパイルするか、ov.save_model
を使用して次回の使用に備えてディスクに保存できます。
import openvino as ov
import torch
from torchvision.models import resnet18, ResNet18_Weights
core = ov.Core()
pt_model = resnet18(weights=ResNet18_Weights.IMAGENET1K_V1)
example_input = torch.zeros((1, 3, 224, 224))
ov_model_pytorch = ov.convert_model(pt_model, example_input=example_input)
compiled_model_pytorch = core.compile_model(ov_model_pytorch, device_name="CPU")
ov.save_model(ov_model_pytorch, "model/exported_pytorch_model.xml")
モデルに関する情報の取得¶
OpenVINO Model インスタンスには、モデルに関する情報が保存されます。モデルの入力と出力に関する情報は、model.inputs
と model.outputs
にあります。これらは CompiledModel
インスタンスのプロパティーでもあります。以下のセルで model.inputs
と model.outputs
を使用しているときに、compiled_model.inputs
と compiled_model.outputs
を使用することもできます。
ir_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/'
ir_model_name_xml = 'classification.xml'
ir_model_name_bin = 'classification.bin'
download_file(ir_model_url + ir_model_name_xml, filename=ir_model_name_xml, directory='model')
download_file(ir_model_url + ir_model_name_bin, filename=ir_model_name_bin, directory='model')
'model/classification.xml' already exists.
'model/classification.bin' already exists.
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/classification.bin')
モデルの入力¶
すべての入力レイヤーに関する情報は、inputs
辞書に保存されます。
import openvino as ov
core = ov.Core()
classification_model_xml = "model/classification.xml"
model = core.read_model(model=classification_model_xml)
model.inputs
[<Output: names[input, input:0] shape[1,3,224,224] type: f32>]
上のセルは、ロードされたモデルが input という名前の 1 つの入力を受け入れることを示しています。別のモデルをロードした場合、別の入力レイヤー名が表示され、さらに多くの入力が表示される場合があります。また、model.input(index)
を使用して各入力レイヤーに関する情報を取得することもできます。ここで、index はモデル内の入力レイヤーの数値インデックスです。モデルの入力が 1 つだけの場合は、index を省略できます。
input_layer = model.input(0)
多くの場合、最初の入力レイヤー名への参照があると便利です。入力が 1 つのモデルの場合、model.input(0).any_name
がこの名前を取得します。
input_layer.any_name
'input'
次のセルには、入力レイアウト、精度、形状が出力されます。
print(f"input precision: {input_layer.element_type}")
print(f"input shape: {input_layer.shape}")
input precision: <Type: 'float32'>
input shape: [1,3,224,224]
このセルは、モデルが [1,3,224,224] の形状の入力を予期していること、および NCHW
レイアウトであることを示しています。これは、モデルがバッチサイズ 1 (N
)、3 チャネル (C
) の入力データ、および高さ (H
) と幅 (W
) が 224 に等しい画像を期待することを意味します。入力データは FP32
(浮動小数点) 精度であることが期待されます。
モデルの出力¶
import openvino as ov
core = ov.Core()
classification_model_xml = "model/classification.xml"
model = core.read_model(model=classification_model_xml)
model.outputs
[<Output: names[MobilenetV3/Predictions/Softmax] shape[1,1001] type: f32>]
モデルの出力情報は、model.outputs
に保存されます。上のセルは、モデルが MobilenetV3/Predictions/Softmax
という名前の 1 つの出力を返すことを示しています。別のモデルをロードすると、出力レイヤー名が異なり、さらに多くの出力が返される可能性があります。入力と同様に、model.output(index)
を使用して各出力に関する情報を個別に取得することもできます。
このモデルの出力は 1 つであるため、入力レイヤーの場合と同じ方法に従って名前を取得します。
output_layer = model.output(0)
output_layer.any_name
'MobilenetV3/Predictions/Softmax'
出力の精度と形状の取得は、入力の精度と形状の取得と似ています。
print(f"output precision: {output_layer.element_type}")
print(f"output shape: {output_layer.shape}")
output precision: <Type: 'float32'>
output shape: [1,1001]
このセルは、モデルが [1, 1001] の形状の出力を返すことを示しています。ここで、1 はバッチサイズ (N
)、1001 はクラス数 (C
) です。出力は 32 ビット浮動小数点として返されます。
モデルの推論実行¶
注: このノートブックでは、基本的な同期推論 API のみを説明します。非同期推論の例については、非同期 API ノートブックを参照してください。
以下の図は、OpenVINO を使用した一般的な推論パイプラインを示しています。
OpenVINO コアの作成とモデルのコンパイルについては、前のステップで説明しています。次のステップは入力の準備です。サポートされる形式のいずれかで入力を指定できます。キーとして入力の名前を含む辞書と、値として入力テンソルを表す np.arrays
、入力テンソルを表す np.arrays
のリストまたはタプル (順序はモデル入力の順序と一致する必要があります) を指定します。モデルに単一の入力がある場合、辞書またはリストへのラップを省略できます。モデルで推論を行うには、core.compile_model
を使用して取得したコンパイル済みモデル・オブジェクトに、準備された入力を渡します。推論結果は辞書として表され、キーはモデル出力であり、np.arrays
は生成されたデータ値を表します。
# Install opencv package for image handling
%pip install -q opencv-python
Note: you may need to restart the kernel to use updated packages.
ネットワークのロード
ir_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/'
ir_model_name_xml = 'classification.xml'
ir_model_name_bin = 'classification.bin'
download_file(ir_model_url + ir_model_name_xml, filename=ir_model_name_xml, directory='model')
download_file(ir_model_url + ir_model_name_bin, filename=ir_model_name_bin, directory='model')
'model/classification.xml' already exists.
'model/classification.bin' already exists.
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/classification.bin')
import openvino as ov
core = ov.Core()
classification_model_xml = "model/classification.xml"
model = core.read_model(model=classification_model_xml)
compiled_model = core.compile_model(model=model, device_name="CPU")
input_layer = compiled_model.input(0)
output_layer = compiled_model.output(0)
画像ロードして入力形状に変換
ネットワークを介して画像を伝播するには、画像を配列にロードし、ネットワークが期待する形状にサイズ変更して、ネットワークの入力レイアウトに変換する必要があります。
import cv2
image_filename = download_file(
"https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/image/coco_hollywood.jpg",
directory="data"
)
image = cv2.imread(str(image_filename))
image.shape
data/coco_hollywood.jpg: 0%| | 0.00/485k [00:00<?, ?B/s]
(663, 994, 3)
画像の形状は (663,994,3) です。高さは 663 ピクセル、幅は 994 ピクセルで、3 つのカラーチャネルがあります。ネットワークによって期待される高さと幅への参照が取得され、画像のサイズがこれらの次元に変更されます。
# N,C,H,W = batch size, number of channels, height, width.
N, C, H, W = input_layer.shape
# OpenCV resize expects the destination size as (width, height).
resized_image = cv2.resize(src=image, dsize=(W, H))
resized_image.shape
(224, 224, 3)
これで、画像はネットワークが期待する幅と高さになりました。これはまだ HWC
形式であるため、NCHW
形式に変更する必要があります。まず、np.transpose()
メソッドを呼び出して CHW
に変更し、次に np.expand_dims()
メソッドを呼び出して N
次元 (N
= 1) を追加します。次に np.astype()
メソッドで FP32
に変換します。
import numpy as np
input_data = np.expand_dims(np.transpose(resized_image, (2, 0, 1)), 0).astype(np.float32)
input_data.shape
(1, 3, 224, 224)
推論を行います
入力データが正しい形式になったので、推論を実行します。CompiledModel
の推論結果は、キーが Output クラスのインスタンス (compiled_model.output(index)
でも取得できる、compiled_model.outputs
の同じキー) と、値は np.array
形式で予測された結果である辞書になります。
# for single input models only
result = compiled_model(input_data)[output_layer]
# for multiple inputs in a list
result = compiled_model([input_data])[output_layer]
# or using a dictionary, where the key is input tensor name or index
result = compiled_model({input_layer.any_name: input_data})[output_layer]
InferRequest
を作成し、要求に応じて infer
メソッドを実行することもできます。
request = compiled_model.create_infer_request()
request.infer(inputs={input_layer.any_name: input_data})
result = request.get_output_tensor(output_layer.index).data
.infer()
関数は、get_output_tensor()
を使用して到達可能な出力テンソルを設定します。このネットワークは 1 つの出力を返し、出力レイヤーへの参照は output_layer.index
パラメーターにあるため、request.get_output_tensor(output_layer.index)
でデータを取得できます。出力から numpy 配列を取得するには、.data
パラメーターを使用します。
result.shape
(1, 1001)
出力形状は (1,1001) で、これは予想される出力形状です。この形状は、ネットワークが 1001 クラスの確率を返すことを示しています。この概念の詳細は、hello world ノートブックを参照してください。
形状変更とサイズ変更¶
画像サイズの変更¶
モデルに合わせて画像を再形成する代わりに、画像に合わせてモデルを再形成することもできます。すべてのモデルが再形成をサポートしているわけではなく、サポートしているモデルでもすべての入力形状をサポートしているわけではないことに注意してください。モデルの入力形状を変更すると、モデルの精度が低下する可能性があります。
まずモデルの入力形状を確認し、それを新しい入力形状に再形状します。
ir_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/'
ir_model_name_xml = 'segmentation.xml'
ir_model_name_bin = 'segmentation.bin'
download_file(ir_model_url + ir_model_name_xml, filename=ir_model_name_xml, directory='model')
download_file(ir_model_url + ir_model_name_bin, filename=ir_model_name_bin, directory='model')
model/segmentation.xml: 0%| | 0.00/1.38M [00:00<?, ?B/s]
model/segmentation.bin: 0%| | 0.00/1.09M [00:00<?, ?B/s]
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/segmentation.bin')
import openvino as ov
core = ov.Core()
segmentation_model_xml = "model/segmentation.xml"
segmentation_model = core.read_model(model=segmentation_model_xml)
segmentation_input_layer = segmentation_model.input(0)
segmentation_output_layer = segmentation_model.output(0)
print("~~~~ ORIGINAL MODEL ~~~~")
print(f"input shape: {segmentation_input_layer.shape}")
print(f"output shape: {segmentation_output_layer.shape}")
new_shape = ov.PartialShape([1, 3, 544, 544])
segmentation_model.reshape({segmentation_input_layer.any_name: new_shape})
segmentation_compiled_model = core.compile_model(model=segmentation_model, device_name="CPU")
# help(segmentation_compiled_model)
print("~~~~ RESHAPED MODEL ~~~~")
print(f"model input shape: {segmentation_input_layer.shape}")
print(
f"compiled_model input shape: "
f"{segmentation_compiled_model.input(index=0).shape}"
)
print(f"compiled_model output shape: {segmentation_output_layer.shape}")
~~~~ ORIGINAL MODEL ~~~~
input shape: [1,3,512,512]
output shape: [1,1,512,512]
~~~~ RESHAPED MODEL ~~~~
model input shape: [1,3,544,544]
compiled_model input shape: [1,3,544,544]
compiled_model output shape: [1,1,544,544]
セグメント化ネットワークの入力形状は、NCHW
レイアウトの [1,3,512,512] です。ネットワークは、幅と高さが 512、バッチサイズが 1 の 3 チャネル画像を想定しています。IENetwork
の .reshape()
メソッドを使用してネットワークを再形成し、幅と高さが 544 の入力イメージを受け入れるようにします。このセグメント化ネットワークは常に、入力の幅と高さが等しい値の配列を返します。したがって、入力次元を 544x544 に設定すると、出力次元も変更されます。再形成後、ネットワークを再コンパイルします。
バッチサイズの変更¶
.reshape()
メソッドを使用して、new_shape
の最初の要素を増やしてバッチサイズを設定します。例えば、バッチサイズを 2 に設定するには、上のセルに new_shape = (2,3,544,544)
を設定します。
import openvino as ov
segmentation_model_xml = "model/segmentation.xml"
segmentation_model = core.read_model(model=segmentation_model_xml)
segmentation_input_layer = segmentation_model.input(0)
segmentation_output_layer = segmentation_model.output(0)
new_shape = ov.PartialShape([2, 3, 544, 544])
segmentation_model.reshape({segmentation_input_layer.any_name: new_shape})
segmentation_compiled_model = core.compile_model(model=segmentation_model, device_name="CPU")
print(f"input shape: {segmentation_input_layer.shape}")
print(f"output shape: {segmentation_output_layer.shape}")
input shape: [2,3,544,544]
output shape: [2,1,544,544]
出力は、バッチサイズを 2 に設定することにより、入力および出力形状の最初の要素 (N
) の値が 2 になることを示しています。入力画像をネットワーク経由で伝播して、結果を確認します。
import numpy as np
import openvino as ov
core = ov.Core()
segmentation_model_xml = "model/segmentation.xml"
segmentation_model = core.read_model(model=segmentation_model_xml)
segmentation_input_layer = segmentation_model.input(0)
segmentation_output_layer = segmentation_model.output(0)
new_shape = ov.PartialShape([2, 3, 544, 544])
segmentation_model.reshape({segmentation_input_layer.any_name: new_shape})
segmentation_compiled_model = core.compile_model(model=segmentation_model, device_name="CPU")
input_data = np.random.rand(2, 3, 544, 544)
output = segmentation_compiled_model([input_data])
print(f"input data shape: {input_data.shape}")
print(f"result data data shape: {segmentation_output_layer.shape}")
input data shape: (2, 3, 544, 544)
result data data shape: [2,1,544,544]
モデルのキャッシュ¶
GPU などの一部のデバイスでは、モデルのロードに時間がかかる場合があります。モデルキャッシュは、モデルをキャッシュ・ディレクトリーにキャッシュすることでこの問題を解決します。core.compile_model(model=net, device_name=device_name, config=config_dict)
が設定されているとキャッシュが使用されます。このオプションは、モデルがキャッシュに存在するかどうかを確認します。存在する場合は、キャッシュからロードします。存在しない場合は、モデルを定期的にロードしてキャッシュに保存します。そのため、このオプションが設定され次回モデルがロードされるとき、モデルはキャッシュからロードされます。
以下のセルで、model_cache ディレクトリーを model のサブディレクトリーとして作成します。ここに、指定されたデバイスのモデルがキャッシュされます。モデルは GPU にロードされます。このセルを 1 度実行するとモデルがキャッシュされるため、このセルをその後実行するとモデルがキャッシュから読み込まれます。
注: モデルキャッシュは CPU デバイスでも利用できます
ir_model_url = 'https://storage.openvinotoolkit.org/repositories/openvino_notebooks/models/002-example-models/'
ir_model_name_xml = 'classification.xml'
ir_model_name_bin = 'classification.bin'
download_file(ir_model_url + ir_model_name_xml, filename=ir_model_name_xml, directory='model')
download_file(ir_model_url + ir_model_name_bin, filename=ir_model_name_bin, directory='model')
'model/classification.xml' already exists.
'model/classification.bin' already exists.
PosixPath('/opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-609/.workspace/scm/ov-notebook/notebooks/002-openvino-api/model/classification.bin')
import time
from pathlib import Path
import openvino as ov
core = ov.Core()
device_name = "GPU"
if device_name in core.available_devices:
cache_path = Path("model/model_cache")
cache_path.mkdir(exist_ok=True)
# Enable caching for OpenVINO Runtime. To disable caching set enable_caching = False
enable_caching = True
config_dict = {"CACHE_DIR": str(cache_path)} if enable_caching else {}
classification_model_xml = "model/classification.xml"
model = core.read_model(model=classification_model_xml)
start_time = time.perf_counter()
compiled_model = core.compile_model(model=model, device_name=device_name, config=config_dict)
end_time = time.perf_counter()
print(f"Loading the network to the {device_name} device took {end_time-start_time:.2f} seconds.")
前のセルを実行した後、モデルがキャッシュ・ディレクトリーに存在することが分かります。次に、コンパイルされたモデルを削除し、再度ロードします。では、現在かかる時間を計測します。
if device_name in core.available_devices:
del compiled_model
start_time = time.perf_counter()
compiled_model = core.compile_model(model=model, device_name=device_name, config=config_dict)
end_time = time.perf_counter()
print(f"Loading the network to the {device_name} device took {end_time-start_time:.2f} seconds.")