入力形状の変更#

OpenVINO™ を使用すると、アプリケーションの実行中にモデルの入力形状を変更できます。これは、モデルの入力形状と異なるサイズの入力をモデルに供給する際に便利です。次に、モデルの入力形状を繰り返し変更する必要がある場合の手順を説明します。

これを 1 度だけ行う場合は、モデル・トランスフォーメーション API を使用して更新された形状を含むモデルを準備します。詳細については、入力形状の設定を参照してください。

reshape メソッド#

reshape メソッドは、C++ では ov::Model::reshape、Python では Model.reshape として使用されます。このメソッドは入力形状を更新し、それをすべての中間レイヤーを介してモデルの出力に伝達します。以下のコードは、reshape メソッドを使用して新しいバッチサイズを設定する例です:

model.reshape([8, 3, 448, 448])
 model->reshape({8, 3, 448, 448});

以下の図は、このメソッドを使用してモデル入力のサイズが画像入力によって変更される結果を示しています:

../../_images/original_vs_reshaped_model.svg

reshape メソッドを使用する場合、次のいずれかのアプローチを実行できます:

  1. 単一の入力でモデルの入力形状を変更するため、新しい形状をメソッドに渡すことができます。以下に、入力画像に空間次元を適合する例を示します:

    image = get_image() 
    model.reshape([1, 3, image.shape[0], image.shape[1]])
     // 画像を読み取り、画像に合わせてモデルを単一入力で調整 
    cv::Mat image = cv::imread("path/to/image"); 
    model->reshape({1, 3, image.rows, image.cols});

    逆に、モデルの入力形状に合わせて入力画像のサイズを変更するには、前処理 API を使用します。

  2. ポート、インデックス、テンソル名による入力を指定して、再形状を表現できます。

    openvino.runtime.Output 辞書キーは、実際の入力オブジェクトを渡して入力を指定します。新しい形状を表す辞書値は PartialShape になります:

    port_to_shape = dict() 
    for input_obj in model.inputs: 
        shape = input_obj.get_partial_shape() 
        # ニーズに合わせて形状を変更 
        # ... 
        port_to_shape[input_obj] = shape 
    model.reshape(port_to_shape)

    map<ov::Output<ov::Node>ov::PartialShape で実際の入力ポートを渡して入力を指定します:

     std::map<ov::Output<ov::Node>, ov::PartialShape> port_to_shape; 
    for (const ov::Output<ov::Node>& input : model->inputs()) { 
        ov::PartialShape shape = input.get_partial_shape(); 
        // ニーズに合わせて形状を変更 
        // ... 
        port_to_shape[input] = shape; 
    } 
    model->reshape(port_to_shape);

    int 辞書キーは、そのインデックスで入力を指定します。新しい形状を表す辞書値は tuple になります:

    idx_to_shape = dict() 
    i = 0 
    for input_obj in model.inputs: 
        shape = input_obj.get_partial_shape() 
        # ニーズに合わせて形状を変更 
        # ... 
        idx_to_shape[i] = shape 
        i += 1 
    model.reshape(idx_to_shape)

    map<size_t, ov::PartialShape> は、インデックスで入力を指定します:

     size_t i = 0; 
    std::map<size_t, ov::PartialShape> idx_to_shape; 
    for (const ov::Output<ov::Node>& input : model->inputs()) { 
        ov::PartialShape shape = input.get_partial_shape(); 
        // ニーズに合わせて形状を変更 
        // ... 
        idx_to_shape[i++] = shape; 
    } 
    model->reshape(idx_to_shape);

    str 辞書キーは、名前で入力を指定します。新しい形状を表す辞書値は str になります:

    name_to_shape = dict() 
    for input_obj in model.inputs: 
        shape = input_obj.get_partial_shape() 
        # 入力には名前がない場合、代わりに入力インデックスまたはポートに基づくマップを使用 
        if len(input_obj.get_names()) != 0: # ニーズに合わせて形状を変更 
            # ... 
            name_to_shape[input_obj.get_any_name()] = shape 
    model.reshape(name_to_shape)

    map<string, ov::PartialShape> は、名前で入力を指定します:

     std::map<std::string, ov::PartialShape> name_to_shape; 
    for (const ov::Output<ov::Node>& input : model->inputs()) { 
        ov::PartialShape shape = input.get_partial_shape(); 
        // 入力には名前がない場合、代わりに入力インデックスまたはポートに基づくマップを使用 
        if (!input.get_names().empty()) { 
        // ニーズに合わせて形状を変更 
        // ... 
            name_to_shape[input.get_any_name()] = shape; 
        } 
    } 
    model->reshape(name_to_shape);

reshape メソッドの使用シナリオは、Hello Reshape SSD サンプルにあります。

状況によっては、モデルを再形成する準備ができていないことがあります。その場合、モデル・トランスフォーメーション APIreshape メソッドを使用して新しい入力形状を設定することはできません。

set_batch メソッド#

モデルバッチの意味はモデルの設計によって異なる場合があります。モデルのバッチ次元を変更するには、レイアウトを設定し、set_batch メソッドを呼び出します。

model.get_parameters()[0].set_layout(ov.Layout("N..."))
 // 入力のレイアウトでバッチをマークアップし、バッチを新しい値にリセット 
model->get_parameters()[0]->set_layout("N...");

set_batch メソッドは reshape 機能の高レベル API であるため、reshape メソッドの影響に関するすべての情報は set_batch にも当てはまります。

モデルの入力形状を設定したら、compile_model メソッドを呼び出して、更新された形状で推論するため CompiledModel オブジェクトを取得します。

OpenVINO ランタイムの IR 生成またはモデル表現のステージで、モデル入力形状を変更するアプローチもあります。

重要

形状変更機能を使用することで、動的モデル入力を静的モデル入力に変換したり、その逆を行うことができます。データの形状が推論ごとに変化しない場合、常に静的形状を設定します。静的形状を設定すると、使用するハードウェア・プラグインとモデルによって異なることがある動的形状のメモリーとランタイムのオーバーヘッドを回避できます。詳細は、動的形状を参照してください。

関連情報#