例: Azure Machine Learning デザイナーを使用してカスタム スキルを構築してデプロイする (アーカイブ済み)

この例はアーカイブされ、サポート対象外です。 Azure Machine Learning デザイナー 使用する方法について説明しました。これは、回帰や分類などのタスク用の機械学習モデルを作成する、使いやすい対話型キャンバスです。 Cognitive Search エンリッチメント パイプラインでデザイナーによって作成されたモデルを呼び出す場合は、いくつかの追加の手順が必要です。 この例では、自動車の価格を予測し、推論エンドポイントを AML スキルとして呼び出す単純な回帰モデルを作成します。

回帰 - 自動車価格予測 (高度) チュートリアルに従って、の例のパイプライン & データセット ドキュメント ページに従って、さまざまな特徴を持つ自動車の価格を予測するモデルを作成します。

大事な

リアルタイム推論プロセスに従ってモデルをデプロイすると、有効なエンドポイントになりますが、Cognitive Search の AML スキルで使用できるエンドポイントはありません。

モデルの登録と資産のダウンロード

モデルをトレーニングしたら、トレーニング済みのモデル を登録、手順に従って trained_model_outputs フォルダー内のすべてのファイルをダウンロードするか、モデル成果物ページから score.py ファイルと conda_env.yml ファイルのみをダウンロードします。 モデルがリアルタイム推論エンドポイントとしてデプロイされる前に、スコアリング スクリプトを編集します。

Cognitive Search エンリッチメント パイプラインは、1 つのドキュメントで動作し、1 つの予測の入力を含む要求を生成します。 ダウンロードした score.py は、レコードの一覧を受け取り、シリアル化された JSON 文字列として予測の一覧を返します。 score.py に 2 つの変更を加えます

  • スクリプトを編集して、リストではなく 1 つの入力レコードを操作する
  • スクリプトを編集して、予測価格の 1 つのプロパティを持つ JSON オブジェクトを返します。

ダウンロードした score.py を開き、run(data) 関数を編集します。 この関数は現在、モデルの _samples.json ファイルで説明されているように、次の入力を想定するように設定されています。

[
  {
    "symboling": 2,
    "make": "mitsubishi",
    "fuel-type": "gas",
    "aspiration": "std",
    "num-of-doors": "two",
    "body-style": "hatchback",
    "drive-wheels": "fwd",
    "engine-location": "front",
    "wheel-base": 93.7,
    "length": 157.3,
    "width": 64.4,
    "height": 50.8,
    "curb-weight": 1944,
    "engine-type": "ohc",
    "num-of-cylinders": "four",
    "engine-size": 92,
    "fuel-system": "2bbl",
    "bore": 2.97,
    "stroke": 3.23,
    "compression-ratio": 9.4,
    "horsepower": 68.0,
    "peak-rpm": 5500.0,
    "city-mpg": 31,
    "highway-mpg": 38,
    "price": 6189.0
  },
  {
    "symboling": 0,
    "make": "toyota",
    "fuel-type": "gas",
    "aspiration": "std",
    "num-of-doors": "four",
    "body-style": "wagon",
    "drive-wheels": "fwd",
    "engine-location": "front",
    "wheel-base": 95.7,
    "length": 169.7,
    "width": 63.6,
    "height": 59.1,
    "curb-weight": 2280,
    "engine-type": "ohc",
    "num-of-cylinders": "four",
    "engine-size": 92,
    "fuel-system": "2bbl",
    "bore": 3.05,
    "stroke": 3.03,
    "compression-ratio": 9.0,
    "horsepower": 62.0,
    "peak-rpm": 4800.0,
    "city-mpg": 31,
    "highway-mpg": 37,
    "price": 6918.0
  },
  {
    "symboling": 1,
    "make": "honda",
    "fuel-type": "gas",
    "aspiration": "std",
    "num-of-doors": "two",
    "body-style": "sedan",
    "drive-wheels": "fwd",
    "engine-location": "front",
    "wheel-base": 96.5,
    "length": 169.1,
    "width": 66.0,
    "height": 51.0,
    "curb-weight": 2293,
    "engine-type": "ohc",
    "num-of-cylinders": "four",
    "engine-size": 110,
    "fuel-system": "2bbl",
    "bore": 3.15,
    "stroke": 3.58,
    "compression-ratio": 9.1,
    "horsepower": 100.0,
    "peak-rpm": 5500.0,
    "city-mpg": 25,
    "highway-mpg": 31,
    "price": 10345.0
  }
]

変更により、インデックス作成中に Cognitive Search によって生成された入力 (単一のレコード) をモデルが受け入れることが保証されます。

{
    "symboling": 2,
    "make": "mitsubishi",
    "fuel-type": "gas",
    "aspiration": "std",
    "num-of-doors": "two",
    "body-style": "hatchback",
    "drive-wheels": "fwd",
    "engine-location": "front",
    "wheel-base": 93.7,
    "length": 157.3,
    "width": 64.4,
    "height": 50.8,
    "curb-weight": 1944,
    "engine-type": "ohc",
    "num-of-cylinders": "four",
    "engine-size": 92,
    "fuel-system": "2bbl",
    "bore": 2.97,
    "stroke": 3.23,
    "compression-ratio": 9.4,
    "horsepower": 68.0,
    "peak-rpm": 5500.0,
    "city-mpg": 31,
    "highway-mpg": 38,
    "price": 6189.0
}

27 行目から 30 行目を置き換えてください。


    for key, val in data.items():
        input_entry[key].append(decode_nan(val))

また、スクリプトが文字列から JSON オブジェクトに生成する出力を編集する必要もあります。 元のファイルの return ステートメント (37 行目) を次の内容に編集します。

    output = result.data_frame.values.tolist()
    return {
        "predicted_price": output[0][-1]
    }

入力形式の変更と、1 つのレコードを入力として受け入れ、予測価格の JSON オブジェクトを返す予測出力を含む更新された run 関数を次に示します。

def run(data):
    data = json.loads(data)
    input_entry = defaultdict(list)
    # data is now a JSON object not a list of JSON objects
    for key, val in data.items():
        input_entry[key].append(decode_nan(val))

    data_frame_directory = create_dfd_from_dict(input_entry, schema_data)
    score_module = ScoreModelModule()
    result, = score_module.run(
        learner=model,
        test_data=DataTable.from_dfd(data_frame_directory),
        append_or_result_only=True)
    #return json.dumps({"result": result.data_frame.values.tolist()})
    output = result.data_frame.values.tolist()
    # return the last column of the the first row of the dataframe
    return  {
        "predicted_price": output[0][-1]
    }

モデルを登録してデプロイする

変更内容を保存したら、ポータルでモデルを登録できるようになりました。 登録モデルを選択し、有効な名前を指定します。 モデル フレームワークの Other、フレームワーク名の Custom、フレームワーク バージョンの 1.0 を選択します。 Upload folder オプションを選択し、更新された score.py と conda_env.yamlを含むフォルダーを選択します。

モデルを選択し、Deploy アクションを選択します。 デプロイ手順では、AKS 推論クラスターがプロビジョニングされていることを前提としています。 現在、コンテナー インスタンスは Cognitive Search ではサポートされていません。

  1. 有効なエンドポイント名を指定します
  2. Azure Kubernetes Service のコンピューティングの種類を選択する
  3. 推論クラスターのコンピューティング名を選択する
  4. enable authentication をオンに切り替える
  5. 種類の Key-based authentication を選択します
  6. score.py の更新された entry script file を選択する
  7. conda_env.yaml を conda dependencies file に選択します
  8. [デプロイ] ボタンを選択して、新しいエンドポイントをデプロイします。

新しく作成されたエンドポイントを Cognitive Search と統合するには

  1. 1 つの自動車レコードを含む JSON ファイルを BLOB コンテナーに追加する
  2. データのインポート ウィザードを使用して AI エンリッチメント パイプラインを構成します。 必ず JSON を parsing mode として選択してください
  3. [Add Enrichments] タブで、プレースホルダーとして 1 つのスキル Extract people names を選択します。
  4. predicted_price型の Edm.Double という名前の新しいフィールドをインデックスに追加し、Retrievable プロパティを true に設定します。
  5. データのインポート プロセスを完了する

AML スキルをスキルセットに追加する

スキルセットの一覧から、作成したスキルセットを選択します。 ここで、スキルセットを編集して、ユーザー識別スキルを AML スキルに置き換えて価格を予測します。 [スキルセット定義 (JSON)] タブで、スキルドロップダウンから Azure Machine Learning (AML) を選択します。 ワークスペースを選択します。AML スキルがエンドポイントを検出するには、ワークスペースと検索サービスが同じ Azure サブスクリプション内にある必要があります。 チュートリアルで前に作成したエンドポイントを選択します。 エンドポイントのデプロイ時に構成された URI と認証情報がスキルに入力されていることを確認します。 スキル テンプレートをコピーし、スキルセット内のスキルを置き換えます。 スキルを次の内容に編集します。

  1. 名前を有効な名前に設定する
  2. 説明を追加する
  3. degreesOfParallelism を 1 に設定する
  4. コンテキストを /document に設定する
  5. 入力を必要なすべての入力に設定します。以下のサンプル スキル定義を参照してください
  6. 返される予測価格をキャプチャするように出力を設定します。
{
      "@odata.type": "#Microsoft.Skills.Custom.AmlSkill",
      "name": "AMLdemo",
      "description": "AML Designer demo",
      "context": "/document",
      "uri": "Your AML endpoint",
      "key": "Your AML endpoint key",
      "resourceId": null,
      "region": null,
      "timeout": "PT30S",
      "degreeOfParallelism": 1,
      "inputs": [
        {
          "name": "symboling",
          "source": "/document/symboling"
        },
        {
          "name": "make",
          "source": "/document/make"
        },
        {
          "name": "fuel-type",
          "source": "/document/fuel-type"
        },
        {
          "name": "aspiration",
          "source": "/document/aspiration"
        },
        {
          "name": "num-of-doors",
          "source": "/document/num-of-doors"
        },
        {
          "name": "body-style",
          "source": "/document/body-style"
        },
        {
          "name": "drive-wheels",
          "source": "/document/drive-wheels"
        },
        {
          "name": "engine-location",
          "source": "/document/engine-location"
        },
        {
          "name": "wheel-base",
          "source": "/document/wheel-base"
        },
        {
          "name": "length",
          "source": "/document/length"
        },
        {
          "name": "width",
          "source": "/document/width"
        },
        {
          "name": "height",
          "source": "/document/height"
        },
        {
          "name": "curb-weight",
          "source": "/document/curb-weight"
        },
        {
          "name": "engine-type",
          "source": "/document/engine-type"
        },
        {
          "name": "num-of-cylinders",
          "source": "/document/num-of-cylinders"
        },
        {
          "name": "engine-size",
          "source": "/document/engine-size"
        },
        {
          "name": "fuel-system",
          "source": "/document/fuel-system"
        },
        {
          "name": "bore",
          "source": "/document/bore"
        },
        {
          "name": "stroke",
          "source": "/document/stroke"
        },
        {
          "name": "compression-ratio",
          "source": "/document/compression-ratio"
        },
        {
          "name": "horsepower",
          "source": "/document/horsepower"
        },
        {
          "name": "peak-rpm",
          "source": "/document/peak-rpm"
        },
        {
          "name": "city-mpg",
          "source": "/document/city-mpg"
        },
        {
          "name": "highway-mpg",
          "source": "/document/highway-mpg"
        },
        {
          "name": "price",
          "source": "/document/price"
        }
      ],
      "outputs": [
        {
          "name": "predicted_price",
          "targetName": "predicted_price"
        }
      ]
    }

インデクサー出力フィールドのマッピングを更新する

インデクサーの出力フィールド マッピングによって、インデックスに保存されるエンリッチメントが決まります。 インデクサーの出力フィールド マッピング セクションを次のスニペットに置き換えます。

"outputFieldMappings": [
    {
      "sourceFieldName": "/document/predicted_price",
      "targetFieldName": "predicted_price"
    }
  ]

インデクサーを実行し、predicted_price プロパティがインデックスに AML スキル出力の結果と共に設定されていることを検証できるようになりました。