チュートリアル:Python および TensorFlow を使用して Azure Functions で機械学習モデルを適用する

この記事では、機械学習モデルと共に Python、TensorFlow、Azure Functions を使用して、内容に基づいて画像を分類する方法について学習します。 すべての作業をローカルで行い、クラウドで Azure リソースを作成しないため、このチュートリアルを完了するのにコストは一切かかりません。

  • Python で Azure Functions を開発するためにローカル環境を初期化する。
  • カスタムの TensorFlow 機械学習モデルを関数アプリにインポートする。
  • 犬または猫が含まれる画像を分類するためのサーバーレス HTTP API を構築する。
  • Web アプリから API を使用する。

前提条件

前提条件のチェック

  1. ターミナルまたはコマンド ウィンドウで func --version を実行して、Azure Functions Core Tools のバージョンが 2.7.1846 以降であることを確認します。
  2. python --version (Linux と macOS の場合) または py --version (Windows の場合) を実行して、Python のバージョンが 3.7. x であることを確認します。

チュートリアル リポジトリをクローンする

  1. ターミナルまたはコマンド ウィンドウで、Git を使用して次のリポジトリをクローンします。

    git clone https://github.com/Azure-Samples/functions-python-tensorflow-tutorial.git
    
  2. フォルダーに移動し、その内容を確認します。

    cd functions-python-tensorflow-tutorial
    
    • start はチュートリアル用の作業フォルダーです。
    • end は、参照用の最終結果と完全な実装です。
    • resources には、機械学習モデルとヘルパー ライブラリが含まれています。
    • frontend は、関数アプリを呼び出す Web サイトです。

Python 仮想環境を作成してアクティブ化する

start フォルダーに移動して、次のコマンドを実行し、.venv という名前の仮想環境を作成してアクティブにします。 必ず、Azure Functions でサポートされている Python 3.7 を使用してください。

cd start
python -m venv .venv
source .venv/bin/activate

お使いの Linux ディストリビューションに Python の venv パッケージがインストールされていなかった場合は、次のコマンドを実行します。

sudo apt-get install python3-venv

以降のコマンドはすべて、このアクティブ化された仮想環境で実行します (仮想環境を終了するには、deactivate を実行します)。

ローカル関数プロジェクトを作成する

Azure Functions における関数プロジェクトとは、それぞれが特定のトリガーに応答する個別の関数を 1 つまたは複数含んだコンテナーです。 プロジェクト内のすべての関数は、同じローカル構成とホスティング構成を共有します。 このセクションでは、HTTP エンドポイントを提供する classify という名前の 1 つの定型関数が含まれる関数プロジェクトを作成します。 後のセクションで、より具体的なコードを追加します。

  1. start フォルダーで、Azure Functions Core Tools を使用して Python 関数アプリを初期化します。

    func init --worker-runtime python
    

    初期化後、start フォルダーにはプロジェクト用の各種ファイルが格納されます。たとえば、local.settings.jsonhost.json といった名前の構成ファイルです。 local.settings.json には Azure からダウンロードしたシークレットを含めることができるため、このファイルは既定で .gitignore ファイルによってソース管理から除外されます。

    ヒント

    関数プロジェクトは特定のランタイムに関連付けられているので、プロジェクト内の関数はすべて同じ言語で記述する必要があります。

  2. 次のコマンドを使用して、関数を自分のプロジェクトに追加します。ここで、--name 引数は関数の一意の名前で、--template 引数は関数のトリガーを指定するものです。 func new によって、関数と同じ名前のサブフォルダーが作成されます。ここには、プロジェクト用に選択した言語に適したコード ファイルと、function.json という名前の構成ファイルが含まれます。

    func new --name classify --template "HTTP trigger"
    

    このコマンドによって、関数の名前 (classify) と同じ名前のフォルダーが作成されます。 このフォルダーには 2 つのファイルが格納されています。1 つは関数コードが含まれている __init__.py で、もう 1 つは関数のトリガーとその入出力バインドを記述した function.json です。 これらのファイルの内容の詳細については、Python 開発者ガイドの「プログラミング モデル」を参照してください。

関数をローカルで実行する

  1. start フォルダーで、ローカルの Azure Functions ランタイム ホストを起動して、関数を開始します。

    func start
    
  2. 出力に classify エンドポイントが表示されるのを確認したら、URL http://localhost:7071/api/classify?name=Azure に移動します。 "Hello Azure!" というメッセージが出力に表示されます。

  3. Ctrl-C キーを使用してホストを停止します。

TensorFlow モデルをインポートしてヘルパー コードを追加する

内容に基づいて画像を分類するように classify 関数を変更するには、Azure Custom Vision Service でトレーニングされ、このサービスからエクスポートされた、既製の TensorFlow モデルを使用します。 先ほどクローンしたサンプルの resources フォルダーに格納されているこのモデルは、犬と猫のどちらが含まれているのかに基づいて画像を分類します。 次に、いくつかのヘルパー コードと依存関係を自分のプロジェクトに追加します。

Free レベルの Custom Vision Service を使用して独自のモデルを作成する場合は、サンプル プロジェクト リポジトリの手順に従ってください。

ヒント

関数アプリには一切依存せずに TensorFlow モデルをホストしたい場合は、対象のモデルがあるファイル共有を Linux 関数アプリにマウントすることができます。 詳細については、「Azure CLI を使用してファイル共有を Python 関数アプリにマウントする」を参照してください。

  1. start フォルダーで次のコマンドを実行して、モデル ファイルを classify フォルダーにコピーします。 コマンドには、必ず \* を含めてください。

    cp ../resources/model/* classify
    
  2. classify フォルダーに model.pblabels.txt という名前のファイルが含まれていることを確認します。 含まれていない場合は、start フォルダーでコマンドを実行したことを確認してください。

  3. start フォルダーで次のコマンドを実行して、ヘルパー コードが含まれるファイルを classify フォルダーにコピーします。

    cp ../resources/predict.py classify
    
  4. classify フォルダーに predict.py という名前のファイルが含まれていることを確認します。

  5. テキスト エディターで start/requirements.txt を開き、ヘルパー コードで必要とされる次の依存関係を追加します。

    tensorflow==1.14
    Pillow
    requests
    
  6. requirements.txt を保存します。

  7. start フォルダーで次のコマンドを実行して、依存関係をインストールします。 インストールには数分かかる場合があります。その間に、次のセクションに進んで関数の変更を行うことができます。

    pip install --no-cache-dir -r requirements.txt
    

    Windows では、"Could not install packages due to an EnvironmentError: [Errno 2] No such file or directory: (EnvironmentError: [Errno 2] が原因でパッケージをインストールできませんでした。ファイルまたはディレクトリがありません:)" の後に、sharded_mutable_dense_hashtable.cpython-37.pyc のようなファイルへの長いパス名が続くエラーが表示されることがあります。 通常、このエラーはフォルダー パスが長くなりすぎることが原因で発生します。 この場合は、レジストリ キー HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled1 に設定して、長いパスを有効にします。 または、Python インタープリターがインストールされている場所を確認します。 その場所へのパスが長い場合は、短いパスのフォルダーに再インストールしてみてください。

ヒント

最初の予測を行うために predict.py を呼び出すと、_initialize という名前の関数によって TensorFlow モデルがディスクから読み込まれ、グローバル変数内にキャッシュされます。 このキャッシュにより、後続の予測が高速化されます。 グローバル変数の使用法の詳細については、Azure Functions の Python 開発者向けガイドを参照してください。

予測を実行するよう関数を更新する

  1. テキスト エディターで classify/__init__.py を開き、既存の import ステートメントの後に次の行を追加して、標準の JSON ライブラリと predict ヘルパーをインポートします。

    import logging
    import azure.functions as func
    import json
    
    # Import helper script
    from .predict import predict_image_from_url
    
  2. main 関数の内容全体を次のコードで置き換えます。

    def main(req: func.HttpRequest) -> func.HttpResponse:
        image_url = req.params.get('img')
        logging.info('Image URL received: ' + image_url)
    
        results = predict_image_from_url(image_url)
    
        headers = {
            "Content-type": "application/json",
            "Access-Control-Allow-Origin": "*"
        }
    
        return func.HttpResponse(json.dumps(results), headers = headers)
    

    この関数は、img という名前のクエリ文字列パラメーターで画像 URL を受け取ります。 次に、ヘルパー ライブラリにある predict_image_from_url を呼び出し、TensorFlow モデルを使用して画像をダウンロードし、分類します。 次に、この関数は、結果と共に HTTP 応答を返します。

    重要

    この HTTP エンドポイントは、別のドメインでホストされている Web ページによって呼び出されるため、応答には、ブラウザーのクロス オリジン リソース共有 (CORS) 要件を満たすための Access-Control-Allow-Origin ヘッダーが含まれます。

    実稼働アプリケーションでは、セキュリティを強化するために、* を Web ページの特定のオリジンに変更します。

  3. 変更内容を保存し、依存関係のインストールが完了していることを前提に、func start を使用してローカル関数ホストを再度起動します。 必ず、仮想環境をアクティブにして start フォルダーでホストを実行します。 そうしないと、ホストは起動しますが、関数の呼び出し時にエラーが発生します。

    func start
    
  4. ブラウザーで次の URL を開き、猫画像の URL を使用して関数を呼び出して、返された JSON で画像が猫として分類されることを確認します。

    http://localhost:7071/api/classify?img=https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/cat1.png
    
  5. 次の手順で使用するので、ホストは実行したままにしておいてください。

ローカル Web アプリのフロントエンドを実行して関数をテストする

別の Web アプリから関数エンドポイントの呼び出しをテストするために、リポジトリの frontend フォルダーに簡単なアプリが用意されています。

  1. 新しいターミナルまたはコマンド プロンプトを開き、仮想環境をアクティブにします (前の「Python 仮想環境を作成してアクティブ化する」にある説明を参照)。

  2. リポジトリの frontend フォルダーに移動します。

  3. Python で HTTP サーバーを起動します。

    python -m http.server
    
  4. ブラウザーで localhost:8000 に移動し、次の写真の URL のいずれかをテキスト ボックスに入力するか、パブリックにアクセスできる画像の URL を使用します。

    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/cat1.png
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/cat2.png
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/dog1.png
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/dog2.png
  5. [Submit](送信) を選択して関数エンドポイントを呼び出し、画像を分類します。

    Screenshot of finished project

    画像の URL を送信したときにブラウザーからエラーがレポートされる場合は、関数アプリを実行しているターミナルを確認します。 "No module found 'PIL' (モジュールが見つかりません 'PIL')" のようなエラーが表示される場合は、前に作成した仮想環境をアクティブにする前に、start フォルダーで関数アプリを起動した可能性があります。 引き続きエラーが発生する場合は、仮想環境をアクティブにして pip install -r requirements.txt を再度実行し、エラーを探します。

Note

このモデルでは、画像の内容が常に猫または犬に分類されます。画像に両方含まれている場合やどちらも含まれていない場合は、既定で犬に分類されます。 たとえば、虎や豹の画像であれば通常猫に分類されますが、象、人参、または飛行機の画像は犬に分類されます。

リソースをクリーンアップする

このチュートリアルの全作業は、お使いのマシン上でローカルに実行されるため、クリーンアップする Azure リソースやサービスはありません。

次のステップ

このチュートリアルでは、Azure Functions を使用して HTTP API エンドポイントをビルドしてカスタマイズし、TensorFlow モデルを使用して画像を分類する方法について学習しました。 また、Web アプリから API を呼び出す方法についても学習しました。 このチュートリアルの手法を使用することで、Azure Functions のサーバーレス コンピューティング モデルで API を実行しながら、複雑な API もビルドできます。

関連項目: