WinClipをcuda11.8の環境で動かす

https://github.com/caoyunkang/WinClip/tree/master

githubで公開されている[WinClip](https://github.com/caoyunkang/WinClip/tree/master)のコードを実行する際に環境構築やデータのダウンロードが必要だったため，まとめてみました．

# 環境構築
### git clone する
作業したいフォルダで[WinClip](https://github.com/caoyunkang/WinClip.git)をgit cloneします．
```shell
$ git clone https://github.com/caoyunkang/WinClip.git
```

### PyTorchのインストール
WinClipにはinstall.shが用意されていて，実行するだけで必要なモジュールがインストールされるようになっています．しかし，その中でインストールされるPyTorchのバージョンは1.10.0+cu113で今回の環境(cuda 11.8)には合っていません． この環境のまま実行すると`Segmentation fault`とエラーが吐かれてしまいます．


そこでPyTorchのみ手動でインストールします．

PyTorchの公式サイトにある[Previous PyTorch versions](https://pytorch.org/get-started/previous-versions/)とhttps://download.pytorch.org/whl/torch_stable.html を確認しましたが，cuda 11.8に対応しているtorch==1.10.0は見つかりませんでした．そこで今回はpyenvでPython3.11.1の環境を作成し，cuda 11.8に対応しているtorch==2.1.1をインストールします．
以下のコマンドから以上の環境を作成します.
```shell
$ pyenv install 3.11.1
$ pyenv global 3.11.1 # localでも良い
$ pip install torch==2.1.1 torchvision==0.16.1 torchaudio==2.1.1 --index-url https://download.pytorch.org/whl/cu118
```

### install.shの編集と実行
install.shを編集する内容は以下のとおりです．
- torchとtorchvisionは既にインストールしたのでPyTorchをインストールするコマンドはコメントアウトする
- `pip install logru`は間違いであるから`pip install loguru`に変更する
- 今回はvisaデータセットも使用するつもりはないのでコメントアウトする 

以下が編集後のinstall.shの内容です． 
```install.sh 
# PyTorch
# pip3 install torch==1.10.0+cu113 torchvision==0.11.1+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html

pip install setuptools==59.5.0
pip install --upgrade diffusers[torch]
pip install opencv-python pycocotools matplotlib onnxruntime onnx ipykernel
pip install transformers
pip install addict
pip install yapf
pip install timm
pip install loguru # ここ
pip install tqdm
pip install scikit-image
pip install scikit-learn
pip install pandas
pip install tensorboard
pip install seaborn
pip install open_clip_torch
pip install SciencePlots
pip install timm

# datasets
# cd ..
# python datasets/prepare_visa_public.py
```

これでinstall.shを実行します．
```shell
$ sh install.sh
```


# データセット用意
２種類のデータセットを利用できるみたいですが，今回はmvtecの方を選択しました．こちらの[サイト](https://www.mvtec.com/company/research/datasets/mvtec-ad/)で名前やメアドを登録した後, ダウンロードページに移動します．

ダウンロードページに移動したら "DOWNLOAD THE WHOLE DATASET"の上で右クリックをし， リンクのアドレスをコピーします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2473523/db6c83a6-c5ed-e4ce-2392-5aa4e32d8a87.png)

WinClip/datasetsに移動してデータを保存するフォルダ(mvtec_anomaly_detection)を作成します．　
```shell
$ cd datasets
$ mkdir mvtec_anomaly_detection
```

作成したフォルダ(mvtec_anomaly_detection)に移動して先ほどコピーしたリンクからデータセットをダウンロードします．
```shell
$ cd mvtec_anomaly_detection
$ wget コピーしたリンク
```

ダウンロードが終わるとmvtec_anomaly_detection.tar.xzがダウンロードされています．次に以下のコマンドでファイルを展開していきます．
```shell
$ xz -dc mvtec_anomaly_detection.tar.xz| tar xfv -
```
展開したファイルからは以下のようなフォルダやファイルが確認できました．
```
$ ls
bottle/ capsule/ grid/ leather/ metal_nut/ pill/ screw/	toothbrush/ wood/ 
cable/ carpet/ hazelnut/ license.txt mvtec_anomaly_detection.tar.xz readme.txt*	tile/ transistor/ zipper/
```

# run_winclip.pyを編集
今回はmvtecデータセットを使用するのでrun_winclip.pyのdatasets変数を以下のように`datasets = ['mvtec']`と変更します．
```Python
# datasets = ['mvtec','visa'] 
datasets = ['mvtec'] # ['visa']から['mvtec']に変更
```

# datasets/mvtec.pyを編集
次にdatasets/mvtec.pyのパスを以下のように変更します．

```Python
# MVTEC2D_DIR = '../datasets/mvtec_anomaly_detection'　を以下に変更　
MVTEC2D_DIR = './datasets/mvtec_anomaly_detection'
```

# run_winclip.pyを実行
これでようやく 実行できます．
```shell
$ python ./run_winclip.py
```
実行が終わるとresult_winclip/mvtec-k-0の中に以下のような画像が出力されます．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2473523/0750c1ba-43f7-7f61-6a29-6951d384c65f.jpeg" width="30%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2473523/9c76d17c-3ed9-0146-1043-4cffad6a5233.jpeg" width="30%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2473523/fc9f07ca-20fd-7850-aebd-205b87b23390.jpeg" width="30%">


以上がWinClipをcuda11.8の環境で動かしてみた結果です． 

https://github.com/caoyunkang/WinClip/tree/master
https://www.mvtec.com/company/research/datasets/mvtec-ad/