チュートリアル: PyTorch を使用して事前トレーニング済みの画像分類モデルを Azure Functions にデプロイする
この記事では、Python、PyTorch、および Azure Functions を使用して、内容に基づいて画像を分類するための事前トレーニング済みのモデルを読み込む方法を学習します。 すべての作業をローカルで行い、Azure リソースをクラウドに作成することはないため、このチュートリアルを完了するのにコストは一切かかりません。
- Python で Azure Functions を開発するためにローカル環境を初期化する。
- 事前トレーニング済みの PyTorch 機械学習モデルを関数アプリにインポートする。
- 1,000 個の ImageNet クラスの 1 つとして画像を分類するためのサーバーレス HTTP API を構築する。
- Web アプリから API を使用する。
前提条件
- アクティブなサブスクリプションが含まれる Azure アカウント。 無料でアカウントを作成できます。
- Python 3.7.4 以降。 (Python 3.8.x および Python 3.6.x も Azure Functions で検証されています)。
- Azure Functions Core Tools
- コード エディター (Visual Studio Code など)
前提条件のチェック
- ターミナルまたはコマンド ウィンドウで
func --version
を実行して、Azure Functions Core Tools のバージョンが 2.7.1846 以降であることを確認します。 -
python --version
(Linux と macOS の場合) またはpy --version
(Windows の場合) を実行して、Python のバージョンが 3.7. x であることを確認します。
チュートリアル リポジトリをクローンする
ターミナルまたはコマンド ウィンドウで、Git を使用して次のリポジトリをクローンします。
git clone https://github.com/Azure-Samples/functions-python-pytorch-tutorial.git
フォルダーに移動し、その内容を確認します。
cd functions-python-pytorch-tutorial
- start はチュートリアル用の作業フォルダーです。
- end は、参照用の最終結果と完全な実装です。
- resources には、機械学習モデルとヘルパー ライブラリが含まれています。
- frontend は、関数アプリを呼び出す Web サイトです。
Python 仮想環境を作成してアクティブ化する
start フォルダーに移動して、次のコマンドを実行し、.venv
という名前の仮想環境を作成してアクティブにします。
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 つの定型関数が含まれる関数プロジェクトを作成します。 後のセクションで、より具体的なコードを追加します。
start フォルダーで、Azure Functions Core Tools を使用して Python 関数アプリを初期化します。
func init --worker-runtime python
初期化後、start フォルダーにはプロジェクト用の各種ファイルが格納されます。たとえば、local.settings.json や host.json といった名前の構成ファイルです。 local.settings.json には Azure からダウンロードしたシークレットを含めることができるため、このファイルは既定で .gitignore ファイルによってソース管理から除外されます。
ヒント
関数プロジェクトは特定のランタイムに関連付けられているので、プロジェクト内の関数はすべて同じ言語で記述する必要があります。
次のコマンドを使用して、関数を自分のプロジェクトに追加します。ここで、
--name
引数は関数の一意の名前で、--template
引数は関数のトリガーを指定するものです。func new
によって、関数と同じ名前のサブフォルダーが作成されます。ここには、プロジェクト用に選択した言語に適したコード ファイルと、function.json という名前の構成ファイルが含まれます。func new --name classify --template "HTTP trigger"
このコマンドによって、関数の名前 (classify) と同じ名前のフォルダーが作成されます。 このフォルダーには 2 つのファイルが格納されています。1 つは関数コードが含まれている __init__.py で、もう 1 つは関数のトリガーとその入出力バインドを記述した function.json です。 これらのファイルの内容の詳細については、Python 開発者ガイドの「プログラミング モデル」を参照してください。
関数をローカルで実行する
start フォルダーで、ローカルの Azure Functions ランタイム ホストを起動して、関数を開始します。
func start
出力に
classify
エンドポイントが表示されるのを確認したら、URLhttp://localhost:7071/api/classify?name=Azure
に移動します。 "Hello Azure!" というメッセージが出力に表示されます。Ctrl-C キーを使用してホストを停止します。
PyTorch モデルをインポートしてヘルパー コードを追加する
画像をその内容に基づいて分類するように classify
関数を変更するには、事前トレーニング済みの ResNet モデルを使用します。
PyTorch から提供される事前トレーニング済みのモデルでは、画像は 1,000 個の ImageNet クラスのうちの 1 つに分類されます。 次に、いくつかのヘルパー コードと依存関係を自分のプロジェクトに追加します。
start フォルダーで次のコマンドを実行して、予測コードとラベルを classify フォルダーにコピーします。
cp ../resources/predict.py classify cp ../resources/labels.txt classify
classify フォルダーに predict.py と labels.txt という名前のファイルが含まれていることを確認します。 含まれていない場合は、start フォルダーでコマンドを実行したことを確認してください。
テキスト エディターで「start/requirements.txt」を開き、次のように、ヘルパー コードで必要とされる依存関係を追加します。
azure-functions requests -f https://download.pytorch.org/whl/torch_stable.html torch==1.13.0+cpu torchvision==0.14.0+cpu
ヒント
torch と torchvision のバージョンは、PyTorch ビジョン リポジトリのバージョン テーブルに記載されている値と一致している必要があります。
requirements.txt を保存し、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@LongPathsEnabled
を1
に設定して、長いパスを有効にします。 または、Python インタープリターがインストールされている場所を確認します。 その場所へのパスが長い場合は、短いパスのフォルダーに再インストールしてみてください。
予測を実行するよう関数を更新する
テキスト エディターで 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
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
を呼び出し、PyTorch モデルを使用して画像をダウンロードし、分類します。 次に、この関数は、結果と共に HTTP 応答を返します。重要
この HTTP エンドポイントは、別のドメインでホストされている Web ページによって呼び出されるため、応答には、ブラウザーのクロス オリジン リソース共有 (CORS) 要件を満たすための
Access-Control-Allow-Origin
ヘッダーが含まれます。実稼働アプリケーションでは、セキュリティを強化するために、
*
を Web ページの特定のオリジンに変更します。変更内容を保存し、依存関係のインストールが完了していることを前提に、
func start
を使用してローカル関数ホストを再度起動します。 必ず、仮想環境をアクティブにして start フォルダーでホストを実行します。 そうしないと、ホストは起動しますが、関数の呼び出し時にエラーが発生します。func start
ブラウザーで次の URL を開き、バーニーズ マウンテン ドッグの画像の URL を使用して関数を呼び出して、返された JSON で画像がバーニーズ マウンテン ドッグとして分類されていることを確認します。
http://localhost:7071/api/classify?img=https://raw.githubusercontent.com/Azure-Samples/functions-python-pytorch-tutorial/master/resources/assets/Bernese-Mountain-Dog-Temperament-long.jpg
次の手順で使用するので、ホストは実行したままにしておいてください。
ローカル Web アプリのフロントエンドを実行して関数をテストする
別の Web アプリから関数エンドポイントの呼び出しをテストするために、リポジトリの frontend フォルダーに簡単なアプリが用意されています。
新しいターミナルまたはコマンド プロンプトを開き、仮想環境をアクティブにします (前の「Python 仮想環境を作成してアクティブ化する」にある説明を参照)。
リポジトリの frontend フォルダーに移動します。
Python で HTTP サーバーを起動します。
python -m http.server
ブラウザーで
localhost:8000
に移動し、次の写真の URL のいずれかをテキスト ボックスに入力するか、パブリックにアクセスできる画像の URL を使用します。https://raw.githubusercontent.com/Azure-Samples/functions-python-pytorch-tutorial/master/resources/assets/Bernese-Mountain-Dog-Temperament-long.jpg
https://github.com/Azure-Samples/functions-python-pytorch-tutorial/blob/master/resources/assets/bald-eagle.jpg?raw=true
https://raw.githubusercontent.com/Azure-Samples/functions-python-pytorch-tutorial/master/resources/assets/penguin.jpg
[Submit](送信) を選択して関数エンドポイントを呼び出し、画像を分類します。
画像の URL を送信したときにブラウザーからエラーがレポートされる場合は、関数アプリを実行しているターミナルを確認します。 "No module found 'PIL' (モジュールが見つかりません 'PIL')" のようなエラーが表示される場合は、前に作成した仮想環境をアクティブにする前に、start フォルダーで関数アプリを起動した可能性があります。 引き続きエラーが発生する場合は、仮想環境をアクティブにして
pip install -r requirements.txt
を再度実行し、エラーを探します。
リソースをクリーンアップする
このチュートリアルの全作業は、お使いのマシン上でローカルに実行されるため、クリーンアップする Azure リソースやサービスはありません。
次のステップ
このチュートリアルでは、Azure Functions を使用して HTTP API エンドポイントをビルドしてカスタマイズし、PyTorch モデルを使用して画像を分類する方法について学習しました。 また、Web アプリから API を呼び出す方法についても学習しました。 このチュートリアルの手法を使用することで、Azure Functions のサーバーレス コンピューティング モデルで API を実行しながら、複雑な API もビルドできます。
関連項目: