Windows11+WSL2で、MMCV、MMDetectionを使って画像から物体検出するまで

# 前フリ

画像から物体が検出できると聞いて動かしてみた。
* python 3.11.1
* venv
* pip
* PyTorch
* CUDA
* MMCV
* MMDetection
* MMEngine

以下はvenvの中に、できるだけpipとmimを使って入れる方向で動かせた際のメモです。

結論としては、pipを使う場合はmmcv公式で確認されているバージョンの組み合わせに従い、後日安定してきたらアップデートするのがよさそう。

各モジュールバージョンの組み合わせは、[MMCVのドキュメント](https://mmcv.readthedocs.io/en/latest/get_started/installation.html#install-with-pip)から
cuda、touch、mmcvそれぞれ一番新しいものを選ぶ。

mmcvのインストールが失敗しているときは、以下のエラーが出ていた。
（公式FAQにもmmcvが原因であると指摘あり）
`ModuleNotFoundError: No module named 'mmcv._ext'`

### 何が書いてあるか
WSL2へののMMCV環境構築時の参考情報

### 何が書いてないか
venvのインストール方法

## 前提環境
* 作業日時 2024.2.16 3時頃
* CPU: Intel(R) Core(TM) i7-11800H
* RAM: 32.0 GB
* GPU: NVIDIA GeForce RTX 3050 Laptop GPU(4GB)
* Windows11 22H2 ビルド22621.3155
* WSL2 / Ubuntu 22.04
* Python 3.11.1

以下はWSL2上内で作業しています。

## インストール
各引用解説はChat-GPT4によるものです。

### venv環境
```
mkdir mmcv-test
cd mmcv-test
python -m venv .venv
source .venv/bin/activate
```

### torch

> PyTorchは、FacebookのAI Research lab（FAIR）によって開発されたオープンソースの機械学習ライブラリです。Pythonを主要なインターフェースとして使用し、テンソル計算（NumPyのような操作がGPU上で可能）や自動微分を提供しています。これにより、ディープラーニングのモデルを柔軟かつ直感的に構築、訓練、デプロイすることができます。

公式
https://pytorch.org/blog/pytorch-2-1/

インストール
```shell
pip install torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 --index-url https://download.pytorch.org/whl/cu121
```
バージョン確認
```shell
python -c 'import torch;print("tourch: v"+torch.__version__)'
```
> tourch: v2.1.2+cu121  

### cuda (NVIDIAのGPUの場合/任意)

>CUDA（Compute Unified Device Architecture）は、NVIDIAによって開発された、GPUを使用して並列計算を行うためのプログラミングモデルおよびコンピューティングプラットフォームです。CUDAを利用することで、ディープラーニング、科学計算、画像処理などの計算集約的なタスクを高速に実行できます。

ドライバ探し  
https://developer.nvidia.com/cuda-12-1-0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=WSL-Ubuntu&target_version=2.0&target_type=deb_network

インストール
```shell
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.0-1_all.deb
sudo dpkg -i cuda-keyring_1.0-1_all.deb
sudo apt-get update
sudo apt-get -y install cuda-12.1 # ここでバージョンを指定しないと最新が入ってしまう
```
バージョン確認
```shell
python -c 'import torch;print("cuda: v"+torch.version.cuda)'
```
> cuda: v12.1

### cudaのPATH 追加

```shell
export PATH=/usr/local/cuda-12.1/bin${PATH:+:${PATH}}
```

## mmcv

> MMCV（MultiMedia CV）は、コンピュータビジョンのためのオープンソースのツールボックスであり、OpenMMLabプロジェクトの一部です。画像やビデオの前処理、モデルトレーニング、推論フレームワークなど、様々なコンピュータビジョンタスクをサポートするための基本的なコンポーネントとユーティリティを提供します。MMCVは、PyTorch上に構築されており、より効率的な実験と開発を可能にします。

pipを使ってインストールする方法
https://mmcv.readthedocs.io/en/latest/get_started/installation.html#install-with-pip

画面中にあるプルダウンに、調べたtorchとcudaのバージョンを指定してインストールコマンドをコピーする

インストール
```shell
pip install mmcv==2.1.0 -f https://download.openmmlab.com/mmcv/dist/cu121/torch2.1/index.html
```
バージョン確認  
（pip listでも確認できるが、以下がエラーになることで、**うまくいっていない**ことが確認できるのでimportを使う）
```shell
python -c 'import mmcv;print("mmcv: v"+mmcv.__version__);'
```
> mmcv: v2.1.0

## mmengine / mmdet

>MMEngineは、OpenMMLabによって開発された新しいオープンソースのディープラーニングトレーニングエンジンです。これは、研究者や開発者が独自のアルゴリズムや複雑なモデルを容易に実装し、実験を効率的に行うための柔軟性と拡張性を提供します。MMEngineは、モデルトレーニングのプロセスを抽象化し、様々な機械学習タスクに対してカスタマイズ可能なコンポーネントを提供します。

>MMDetectionは、オブジェクト検出、インスタンスセグメンテーション、ポーズ推定など、コンピュータビジョンのためのオープンソースの検出ツールボックスです。これもOpenMMLabプロジェクトの一部であり、PyTorchとMMCV上に構築されています。MMDetectionは、多数の検出アルゴリズムとモデルを提供し、これらを組み合わせて使用することで、研究や開発の効率を大幅に向上させることができます。

こちらに詳しく：https://qiita.com/Ikwus/items/3d1167952db9791484a5

mimでインストール
```shell
pip install -U openmim
mim install mmengine
mim install mmdet
```

## 最終的なバージョン確認

```shell
pip list | grep -e "mm" -e "torch"
```
> mmcv                     2.1.0  
> mmdet                    3.3.0  
> mmengine                 0.10.3  
> torch                    2.1.2  
> torchaudio               2.1.2+cu121  
> torchvision              0.16.2+cu121


# 試験
ここから先は、公式のチュートリアルを参考に。
https://mmdetection.readthedocs.io/en/latest/get_started.html

```shell
# mmdetectionのdemoを使いたいのでclone
git clone https://github.com/open-mmlab/mmdetection.git

# ここから先はmmdetectionの中で作業
cd mmdetection

# チェックポイントをダウンロード
mim download mmdet --config rtmdet_tiny_8xb32-300e_coco --dest .

# デモ画像への処理
python demo/image_demo.py demo/demo.jpg rtmdet_tiny_8xb32-300e_coco.py --weights rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth --device cuda:0
```
CUDAなし環境では `--device cpu` を使うらしい

## 結果
mmdetect/outputディレクトリに成果物(検出結果画像/json)が出力された
```shell
Loads checkpoint by local backend from path: rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth
The model and loaded state dict do not match exactly

unexpected key in source state_dict: data_preprocessor.mean, data_preprocessor.std

02/16 04:56:50 - mmengine - WARNING - Failed to search registry with scope "mmdet" in the "function" registry tree. As a workaround, the current "function" registry in "mmengine" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether "mmdet" is a correct scope, or whether the registry is initialized.
/home/***/mmcv-test/.venv/lib/python3.11/site-packages/mmengine/visualization/visualizer.py:196: UserWarning: Failed to add <class 'mmengine.visualization.vis_backend.LocalVisBackend'>, please provide the `save_dir` argument.
  warnings.warn(f'Failed to add {vis_backend.__class__}, '
/home/***/mmcv-test/.venv/lib/python3.11/site-packages/torch/functional.py:504: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at 
../aten/src/ATen/native/TensorShape.cpp:3526.)
  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]
Inference ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   
results have been saved at outputs
```

![demo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49852/3a0ea9f5-9d28-e0cd-4dfd-03e710b3c00e.jpeg)