Segmentation Models on Pytorchを動かしてみる：②テストコードの実行

# セマンティックセグメンテーション
画像解析による物体認識の一手法として，セマンティックセグメンテーションというものがあります．これは，画像において物体にラベルを付けて，元画像とラベル化画像を使ってモデルを学習させ，ピクセル単位で画像からラベル（つまり物体）を予測しようとするAI手法です（たぶん）．

これを使って河川に浮遊する物質動態を把握しようと考え，Python環境のPytorchで動く[Segmentation Models](https://github.com/qubvel/segmentation_models.pytorch)を動かした際の注意点について忘備録的にまとめてみます．

なお，著者は画像解析については素人同然なのでそのつもりでお読みください．

今回試したPC環境については以下です．

OS：Windows 10
GPU：NVIDIA RTX A6000

また，Pythonについては，Anaconda 3のJupyternotebookで動かします．さらに，CUDA-CPU環境についても[前回記事](https://qiita.com/champon487/items/e833d2281296ac6a8127)で行っていますのでそちらも参照ください．

# サンプルコード

Segmentation Modelsにある自動車を分類する[テストコード](https://github.com/qubvel/segmentation_models.pytorch/blob/master/examples/cars%20segmentation%20(camvid).ipynb)を実行してみます．

構築した環境ではいくつかうまくいかないところがあったので，そこを中心に説明していきます．

# いろいろインストール

モデル本体であるsegmentation modelsをインストール．Anaconda promptで下記実行．

```
pip install segmentation_models_pytorch
```

OpenCVも必要．

```
pip install opencv-python
```
以下の部分においてはgithubのリポジトリから画像とラベルデータを引っ張ってきています．

```python:
DATA_DIR = './data/CamVid/'

# load repo with data if it is not exists
if not os.path.exists(DATA_DIR):
    print('Loading data...')
    os.system('git clone https://github.com/alexgkendall/SegNet-Tutorial ./data')
    print('Done!')
```

これにはgitのインストールが必要みたいです．

https://gitforwindows.org/

ダウンロード→デフォルトでインストールで問題ないと思いますが，PCを再起動しないといけないかもしれません．

# kernelが落ちる

ここで試している環境では下記部分でkernel appears to have diedになり，jupyterがクラッシュしました．コマンドから実行すると，

```
Initializing libiomp5md.dll, but found libiomp5md.dll already initialized
```

とエラーが返ってくる．どうやらanaconda3のフォルダに複数のlibiomp5md.dllがあるのが問題みたい．なので1つを残して削除する．

デフォルトだと，anaconda3は以下のフォルダにインストールされている．

```
C:/Users/(ユーザー名）/AppData/Local/anaconda3
```

ただ，Appdataは隠しフォルダになっているので，フォルダオプションから隠しフォルダを表示にする．anaconda3フォルダでlibiomp5md.dllを1つ残して削除．どれを残してもうごく（他への影響は不明ですが．．）．

# データ拡張ライブラリalbumentationsのインストール

このコードでは，データ数をかさましするために，学習毎に動的に画像に回転や縮小などを施していて，その処理にライブラリalbumentationsを使っています．
このインストールはanaconda promptで

```
pip install -U albumentations --user
```

で可能ですが，Jupyternotebookで使う場合，以下にあるように予期せぬ場所にインストールされていて読み込めないバグがある様子．

https://github.com/albumentations-team/albumentations/issues/895

なので想定しているフォルダにファイルをコピーする．ここでの環境だと，

```
C:/Users/(ユーザー名)/AppData/Roaming/Python/PythonXXX/site-packages
```

にあるフォルダをすべてコピーしてanaconda3のインストールフォルダである以下に張り付けます．
※XXXはpythonのバージョンで変わります．

```
C:/Users/(ユーザー名)/AppData/Local/anaconda3/Lib/site-packages
```

また，get_training_augumentation内の以下の関数は最新のalbumentaitonsでは動かないので書き換えるととりあえず動きます．

```
albu.IAAAdditiveGaussianNoise(p=0.2)
albu.IAAPerspective(p=0.5)

albu.IAASharpen(p=1)
```

↓
```
albu.GaussNoise(p=0.2)
albu.Perspective(p=0.5)

albu.Sharpen(p=1)
```

※albumentations version 1.4ではrandombrightnessとrandomcontrastが動かない．とりあえず，両方ともRandomBrightnessContrastに変更すると動く．

# num workerの値

デフォルトではtrain_loaderでnum_worker=12，valid_loaderでnum_worker=4になっているが動かない場合，これらは0にするとよい．

# 結果

最後まで動くとこんな感じの結果が得られます．左が元画像，中央が正解データ，右が学習モデルによる予測値ですね．

![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1260410/3cb4bd2f-6864-839e-c836-9f336320c742.png)

モデルやエンコーダ部分は[一覧](https://github.com/qubvel/segmentation_models.pytorch)のものから簡単に変更できます．今回は以下で動かしています．

```python:
ENCODER = 'resnext50_32x4d'
ENCODER_WEIGHTS = 'imagenet'
CLASSES = ['car']
ACTIVATION = 'sigmoid' # could be None for logits or 'softmax2d' for multiclass segmentation
DEVICE = 'cuda'
#DEVICE = 'cpu'

# create segmentation model with pretrained encoder
model = smp.FPN(
    encoder_name=ENCODER, 
    encoder_weights=ENCODER_WEIGHTS, 
    classes=len(CLASSES), 
    activation=ACTIVATION,
)

preprocessing_fn = smp.encoders.get_preprocessing_fn(ENCODER, ENCODER_WEIGHTS)
```

例えば，モデルをUnetに変更したければ，FPN → Unetとすれば動きます．

ただ，モデルやエンコーダは組み合わせによっては動かないものもあるので，いろいろと試してみる必要があります．

# おわりに

とりあえずサンプルコードを動かすところまでまとめてみました．[次は別のデータセットを使ってみるところもやってみます](https://qiita.com/champon487/items/ba062b86ec9918bf6bc5)．