torchvision(Mask R-CNN)のインストールと動作確認(特定クラスのインスタンス・セグメンテーション)(PyTorch,Python 3.12 を使用)

【草稿・未検証について】 本ページは,既存記事「PixelLib のインストールと動作確認(Mask R-CNN,TensorFlow 2.0.4,Python 3.7)」を,Python 3.12 と PyTorch を用いた構成に置き換える検討のために作成した草稿である.掲載しているコードは,Windows 上での実機動作確認を行っていない.実際の利用にあたっては,動作確認と検証が別途必要である.

事前学習済みの Mask R-CNN で,特定クラスのオブジェクトのセグメンテーションを行う.

【置き換えの理由】 既存記事で使用している PixelLib は,内部で TensorFlow の実装に依存している.本ページでは,PyTorch 公式のモデル集である torchvision に含まれる Mask R-CNN(maskrcnn_resnet50_fpn)を使用する.COCO データセットで学習済みの重みが,pip でのインストール後,初回実行時に自動的にダウンロードされる.

【目次】

  1. 前準備
  2. 画像のインスタンスセグメンテーション(torchvision, Mask R-CNN モデル)

【関連する外部ページ】

利用条件等は,利用者で確認すること.

前準備

Python 3.12 のインストール(Windows 上) [クリックして展開]

以下のいずれかの方法で Python 3.12 をインストールする.Python がインストール済みの場合,この手順は不要である.

方法1:winget によるインストール

管理者権限のコマンドプロンプトで以下を実行する.管理者権限のコマンドプロンプトを起動するには,Windows キーまたはスタートメニューから「cmd」と入力し,表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する.

winget install -e --id Python.Python.3.12 --scope machine --silent --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 AssociateFiles=1 InstallLauncherAllUsers=1"

--scope machine を指定することで,システム全体(全ユーザー向け)にインストールされる.このオプションの実行には管理者権限が必要である.インストール完了後,コマンドプロンプトを再起動すると PATH が自動的に設定される.

方法2:インストーラーによるインストール

  1. Python 公式サイト(https://www.python.org/downloads/)にアクセスし,「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする.
  2. ダウンロードしたインストーラーを実行する.
  3. 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する.このチェックを入れ忘れると,コマンドプロンプトから python コマンドを実行できない.
  4. 「Install Python 3.xx for all users」にチェックを入れ,「Install」をクリックする.

インストールの確認

コマンドプロンプトで以下を実行する.

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である.「'python' は,内部コマンドまたは外部コマンドとして認識されていません.」と表示される場合は,インストールが正常に完了していない.

NVIDIA ドライバのインストール(Windows 上)

NVIDIA ドライバは,NVIDIA製GPUをWindowsシステム上で動作させるためのソフトウェアである.グラフィックス処理や,CUDAを利用したAI関連アプリケーションの計算に必要となる.

【NVIDIA CUDA ツールキット・cuDNN の個別インストールについて】 PyTorch の GPU 対応パッケージには,動作に必要な CUDA・cuDNN のライブラリが同梱されている.そのため,本ページの手順では,NVIDIA CUDA ツールキットや cuDNN をシステムへ個別にインストールする必要はない.必要なのは,使用している GPU に対応した最新の NVIDIA ドライバのみである.

ドライバは,NVIDIA公式サイトからダウンロードするか,NVIDIA GeForce Experienceソフトウェアを通じてインストール・更新する.

公式サイト: https://www.nvidia.co.jp/Download/index.aspx?lang=jp

  1. NVIDIA グラフィックス・ボードの確認

    インストールするドライバを選択するために,使用しているPCに搭載されているNVIDIAグラフィックス・ボードの種類を確認する.(確認済みであれば,この手順は不要である.) Windows のコマンドプロンプトで次のコマンドを実行する.

    wmic path win32_VideoController get name
    
  2. NVIDIA ドライバのダウンロード

    確認したグラフィックス・ボードのモデル名と,使用しているWindowsのバージョン(例: Windows 11,Windows 10 64-bit)に対応するドライバを,以下のNVIDIA公式サイトからダウンロードする.

    https://www.nvidia.co.jp/Download/index.aspx?lang=jp

    サイトの指示に従い,製品タイプ,製品シリーズ,製品ファミリー,OS,言語などを選択して検索し,適切なドライバ(Game Ready ドライバまたはStudio ドライバ)をダウンロードする.

  3. ドライバのインストール

    ダウンロードしたインストーラー(.exeファイル)を実行し,画面の指示に従ってインストールを進める.「カスタムインストール」を選択すると,インストールするコンポーネント(ドライバ本体,GeForce Experience,PhysXなど)を選ぶことができる.「高速(推奨)」を選択してもよい.

    インストール完了後,システムの再起動を求められる場合がある.

PyTorch, torchvision のインストール

管理者権限のコマンドプロンプトで,次のコマンドを実行する.

python -m pip install -U torch torchvision --index-url https://download.pytorch.org/whl/cu126
python -m pip install -U pillow matplotlib numpy

【CUDA バージョンの選択について】 上記の cu126 は,CUDA 12.6 に対応した PyTorch パッケージを意味する.使用している GPU・ドライバに応じて,PyTorch 公式サイトのインストールページ(https://pytorch.org/get-started/locally/)で該当するコマンドを確認すること.GPU を使用しない場合は,--index-url のオプションを省略してよい.

インストール後,次のコマンドで GPU が認識されているか確認する.

python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"

True と表示されれば,GPU(CUDA)が利用可能である.

画像のインスタンスセグメンテーション(torchvision, Mask R-CNN モデル)

次のページを参考にした.

https://docs.pytorch.org/vision/stable/models/generated/torchvision.models.detection.maskrcnn_resnet50_fpn.html

  1. 画像ファイルの準備

    画像ファイルは,%HOMEPATH%に置くことにする.ここでは,sample2.jpg という名前の画像を使用する.

  2. 特定クラスのインスタンスセグメンテーションの実行

    次のコードを segment_target.py という名前で保存する.COCO データセットのクラス名一覧のうち,target_classes に指定したクラスのみを抽出して描画する.

    import argparse
    
    import numpy as np
    import torch
    from PIL import Image
    from torchvision.io import decode_image
    from torchvision.models.detection import (
        MaskRCNN_ResNet50_FPN_Weights,
        maskrcnn_resnet50_fpn,
    )
    from torchvision.utils import draw_segmentation_masks
    from torchvision.transforms.functional import to_pil_image
    
    
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument("--image_file", type=str, required=True)
        parser.add_argument(
            "--target_classes",
            type=str,
            nargs="+",
            default=["person"],
            help="抽出するクラス名(例: person car)",
        )
        parser.add_argument("--score_threshold", type=float, default=0.5)
        parser.add_argument("--output_image", type=str, default="segmented.png")
        args = parser.parse_args()
    
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
        weights = MaskRCNN_ResNet50_FPN_Weights.DEFAULT
        model = maskrcnn_resnet50_fpn(weights=weights, progress=True).to(device)
        model.eval()
    
        class_names = weights.meta["categories"]
        target_ids = [class_names.index(c) for c in args.target_classes]
    
        image = decode_image(args.image_file)
        preprocess = weights.transforms()
        x = preprocess(image).unsqueeze(0).to(device)
    
        with torch.no_grad():
            prediction = model(x)[0]
    
        masks = prediction["masks"]
        labels = prediction["labels"]
        scores = prediction["scores"]
    
        keep = [
            i
            for i in range(len(labels))
            if labels[i].item() in target_ids and scores[i].item() >= args.score_threshold
        ]
    
        print(f"検出された対象クラスのインスタンス数: {len(keep)}")
    
        if len(keep) == 0:
            print("指定したクラスは検出されなかった.")
            to_pil_image(image).save(args.output_image)
            return
    
        bool_masks = (masks[keep] > 0.5).squeeze(1)
    
        result = draw_segmentation_masks(
            image, bool_masks, alpha=0.6
        )
        to_pil_image(result).save(args.output_image)
        print(f"結果を保存した: {args.output_image}")
    
    
    if __name__ == "__main__":
        main()
    
  3. 実行(person クラスの抽出)

    コマンドプロンプトで,次のコマンドを実行する.

    cd /d c:%HOMEPATH%
    python segment_target.py --image_file sample2.jpg --target_classes person --output_image sample2_person.png
    
  4. 実行(car クラスの抽出)

    複数クラスを同時に指定することもできる.

    cd /d c:%HOMEPATH%
    python segment_target.py --image_file sample2.jpg --target_classes car --output_image sample2_car.png
    
  5. 結果画像の表示

    Python プログラムを実行する.Matplotlib を使うので,Jupyter QtConsole や Jupyter ノートブック (Jupyter Notebook) の利用が便利である.

    import matplotlib.pyplot as plt
    a = plt.imread("c:/data/sample2.jpg")
    plt.imshow(a)
    plt.show()
    b = plt.imread("c:/data/sample2_person.png")
    plt.imshow(b)
    plt.show()