TensorFlow Hub モデルの OpenVINO 中間表現 (IR) への変換

この Jupyter ノートブックはオンラインで起動でき、ブラウザーのウィンドウで対話型環境を開きます。ローカルにインストールすることもできます。次のオプションのいずれかを選択します。

Binder Google Colab GitHub

このチュートリアルでは、OpenVINO ランタイムを使用して TensorFlow ハブからロードされたモデルを変換する方法を段階的に説明します。

TensorFlow ハブは、マシンラーニング・モデルの再利用と共有を簡素化する、Google が開発したライブラリーおよびオンライン・プラットフォームです。これは、事前トレーニング済みのモデル、埋め込み、再利用可能なコンポーネントのリポジトリーとして機能し、研究者や開発者が最先端のマシンラーニング・モデルに簡単にアクセスして独自のプロジェクトに統合できるようにします。TensorFlow ハブは、画像分類、テキスト埋め込みなどさまざまなタスクに対応する多様なモデルを提供します。これにより、これらのモデルを TensorFlow ワークフローに組み込むプロセスが合理化され、コラボレーションが促進され、AI アプリケーションの開発が加速されます。この集中型ハブは、モデルのアクセシビリティーを向上させ、コミュニティー全体でマシンラーニング機能の急速な進歩を促進します。

各セクションは独立して動作するため、このチュートリアルのノートブック全体を実行したり、特定のセクションを選択的に実行することができます。

目次

画像分類

TensorFlow ハブMobileNet_v2 画像分類モデルを使用します。

MobileNetV2 は、Google の研究者によって開発された、モバイルデバイスと組み込みデバイス向けに設計されたコンパクトで効率的なディープラーニング・アーキテクチャーです。オリジナルの MobileNet の成功を基に、速度と精度の両方を改善しました。MobileNetV2 は、逆残差ブロックを備えた合理化されたアーキテクチャーを採用しており、計算リソースを最小限に抑えながらリアルタイム・アプリケーションでは非常に効率的です。このネットワークは、画像分類、オブジェクト検出、画像セグメント化などのタスクに優れており、モデルのサイズとパフォーマンスのバランスを実現します。MobileNetV2 は、スマートフォンやエッジデバイス上でより高速かつ効率的なディープラーニング推論を可能にするため、デバイス上の AI アプリケーションで人気のある選択肢となっています。

モデルの詳細については、TensorFlow ハブのモデルページをご覧ください。

必要なパッケージをインストール

%pip install -q tensorflow_hub tensorflow pillow numpy matplotlib
%pip install -q "openvino>=2023.2.0"
Note: you may need to restart the kernel to use updated packages.
Note: you may need to restart the kernel to use updated packages.

ライブラリーをインポート

from pathlib import Path
import os
from urllib.request import urlretrieve
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

import tensorflow_hub as hub
import tensorflow as tf
import PIL
import numpy as np
import matplotlib.pyplot as plt

import openvino as ov

tf.get_logger().setLevel("ERROR")
IMAGE_SHAPE = (224, 224)
IMAGE_URL, IMAGE_PATH = "https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg", "data/grace_hopper.jpg"
MODEL_URL, MODEL_PATH = "https://www.kaggle.com/models/google/mobilenet-v1/frameworks/tensorFlow2/variations/100-224-classification/versions/2", "models/mobilenet_v2_100_224.xml"

分類器をダウンロード

TensorFlow ハブから MobileNetV2 事前トレーニング済みモデルを選択し、hub.KerasLayer を使用して Keras レイヤーとしてラップします。

model = hub.KerasLayer(MODEL_URL, input_shape=IMAGE_SHAPE + (3,))
2024-02-09 23:12:03.569013: E tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:266] failed call to cuInit: CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE: forward compatibility was attempted on non supported HW
2024-02-09 23:12:03.569190: E tensorflow/compiler/xla/stream_executor/cuda/cuda_diagnostics.cc:312] kernel version 470.182.3 does not match DSO version 470.223.2 -- cannot find working devices in this configuration

モデルを試すために 1 枚の画像をダウンロード

入力画像には、一般的な画像入力規則に従って、[0,1] の範囲のカラー値があることが想定されます。このモデルでは、入力画像のサイズは高さ x = 224 x 224 ピクセルに固定されます。

Path(IMAGE_PATH).parent.mkdir(parents=True, exist_ok=True)
grace_hopper, _ = urlretrieve(IMAGE_URL, IMAGE_PATH)
grace_hopper = PIL.Image.open(grace_hopper).resize(IMAGE_SHAPE)
grace_hopper
../_images/126-tensorflow-hub-with-output_11_0.png

画像を [0,1] の範囲に正規化します。

grace_hopper = np.array(grace_hopper) / 255.0
grace_hopper.shape
(224, 224, 3)

モデルを OpenVINO IR に変換

ov.convert_model 関数を使用して、ロードされたモデルを OpenVINO IR に変換します。モデル・オブジェクトを渡します。追加の引数は必要ありません。次に、ov.save_model 関数を使用してモデルをディスクに保存します。

if not Path(MODEL_PATH).exists():
    converted_model = ov.convert_model(model)
    ov.save_model(converted_model, MODEL_PATH)

推論デバイスの選択

OpenVINO を使用して推論を実行するためにドロップダウン・リストからデバイスを選択します。

import ipywidgets as widgets

core = ov.Core()

device = widgets.Dropdown(
    options=core.available_devices + ["AUTO"],
    value='AUTO',
    description='Device:',
    disabled=False,
)

device
Dropdown(description='Device:', index=1, options=('CPU', 'AUTO'), value='AUTO')
compiled_model = core.compile_model(MODEL_PATH, device_name=device.value)

推論

バッチ次元 (np.newaxis を使用) を追加し、画像をモデルに渡します。

output = compiled_model(grace_hopper[np.newaxis, ...])[0]
output.shape
(1, 1001)

結果は、画像の各クラスの確率を評価する 1001 要素のロジットベクトルです。

最上位クラス ID は np.argmax で見つかります。

predicted_class = np.argmax(output[0], axis=-1)
predicted_class
653

predicted_class ID (653 など) を取得し、ImageNet データセット・ラベルを取得して予測をデコードします。

labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
plt.imshow(grace_hopper)
plt.axis('off')
predicted_class_name = imagenet_labels[predicted_class]
_ = plt.title("Prediction: " + predicted_class_name.title())
../_images/126-tensorflow-hub-with-output_26_0.png

画像スタイルの転送

TensorFlow ハブ任意の画像スタイル設定モデルを使用します。

モデルには条件付きインスタンス正規化 (CIN) レイヤーが含まれています

CIN ネットワークは、特徴抽出器と様式化モジュールという 2 つの主要コンポーネントで構成されています。特徴抽出器は、コンテンツ画像から一連の特徴を抽出します。次に、スタイル化モジュールはこれらの機能を使用して、スタイル化された画像を生成します。

スタイル化モジュールは畳み込みレイヤーのスタックです。各畳み込みレイヤーの後には CIN レイヤーが続きます。CIN レイヤーは、前のレイヤーからの特徴とスタイルイメージからの CIN パラメーターを入力として受け取り、新しい特徴セットを出力として生成します。

スタイル化モジュールの出力は、スタイル化された画像です。スタイル化された画像は、元のコンテンツ画像と同じ内容ですが、スタイルはスタイル画像から転送されています。

CIN ネットワークは非常に効率的であるため、画像をリアルタイムで様式化することができます。

詳細なモデル情報については、TensorFlow ハブのモデルページをご覧ください。

必要なパッケージをインストール

%pip install -q tensorflow tensorflow_hub "opencv-python" numpy matplotlib
%pip install -q "openvino>=2023.2.0"
Note: you may need to restart the kernel to use updated packages.
Note: you may need to restart the kernel to use updated packages.
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
from urllib.request import urlretrieve
from pathlib import Path

import openvino as ov

import tensorflow_hub as hub
import tensorflow as tf
import cv2
import numpy as np
import matplotlib.pyplot as plt
CONTENT_IMAGE_URL = "https://upload.wikimedia.org/wikipedia/commons/2/26/YellowLabradorLooking_new.jpg"
CONTENT_IMAGE_PATH = "./data/YellowLabradorLooking_new.jpg"

STYLE_IMAGE_URL = "https://upload.wikimedia.org/wikipedia/commons/b/b4/Vassily_Kandinsky%2C_1913_-_Composition_7.jpg"
STYLE_IMAGE_PATH = "./data/Vassily_Kandinsky%2C_1913_-_Composition_7.jpg"

MODEL_URL = "https://www.kaggle.com/models/google/arbitrary-image-stylization-v1/frameworks/tensorFlow1/variations/256/versions/2"
MODEL_PATH = "./models/arbitrary-image-stylization-v1-256.xml"

モデルのロード

hub.KerasLayer を使用して TensorFlow Hub からモデルを読み込みます。モデルには複数の入力 (コンテンツイメージとスタイルイメージ) があるため、プレースホルダーを呼び出してモデルを構築し、tf.keras.Model 関数でラップする必要があります。

inputs = {
    "placeholder": tf.keras.layers.Input(shape=(None, None, 3)),
    "placeholder_1": tf.keras.layers.Input(shape=(None, None, 3)),
}
model = hub.KerasLayer(MODEL_URL, signature="serving_default", signature_outputs_as_dict=True)  # define the signature to allow passing inputs as a dictionary
outputs = model(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

モデルを OpenVINO IR に変換

ov.convert_model 関数を使用して、ロードされたモデルを OpenVINO IR に変換します。モデルを関数に渡します。追加の引数は必要ありません。変換後、ov.save_model 関数を使用してモデルをディスクに保存します。

if not Path(MODEL_PATH).exists():
    Path(MODEL_PATH).parent.mkdir(parents=True, exist_ok=True)
    converted_model = ov.convert_model(model)
    ov.save_model(converted_model, MODEL_PATH)

推論デバイスの選択

OpenVINO を使用して推論を実行するためにドロップダウン・リストからデバイスを選択します。

import ipywidgets as widgets

core = ov.Core()

device = widgets.Dropdown(
    options=core.available_devices + ["AUTO"],
    value='AUTO',
    description='Device:',
    disabled=False,
)

device
Dropdown(description='Device:', index=1, options=('CPU', 'AUTO'), value='AUTO')
compiled_model = core.compile_model(MODEL_PATH, device_name=device.value)

推論

def download_image(src, dst):
    if not Path(dst).exists():
        Path(dst).parent.mkdir(parents=True, exist_ok=True)
        urlretrieve(src, dst)
    image = cv2.imread(dst)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # Convert image color to RGB space
    image = image / 255  # Normalize to [0, 1] interval
    image = image.astype(np.float32)
    return image
content_image = download_image(CONTENT_IMAGE_URL, CONTENT_IMAGE_PATH)
style_image = download_image(STYLE_IMAGE_URL, STYLE_IMAGE_PATH)
style_image = cv2.resize(style_image, (256,256))  # model was trained on 256x256 images
result = compiled_model([content_image[np.newaxis, ...], style_image[np.newaxis, ...]])[0]
title2img = {
    "Source image": content_image,
    "Reference style": style_image,
    "Result": result[0],
}
plt.figure(figsize=(12, 12))
for i, (title, img) in enumerate(title2img.items()):
    ax = plt.subplot(1, 3, i + 1)
    ax.set_title(title)
    plt.imshow(img)
    plt.axis("off")
../_images/126-tensorflow-hub-with-output_45_0.png