Captumを試す

PyTorch Developer Conference 2019 で発表されたものの中に、 [Captum](https://captum.ai/) というライブラリがあります。
解説記事が見当たらなかったので、実際に動かして記事を書いてみました。
まだ beta であり、かつ積極的に開発されているようなので、今後動作が変わる可能性は十分にあると思います。  

# Captum とは？
Captum とは、機械学習モデルを解釈し、理解するための手法をまとめたライブラリです。
ラテン語で、"理解する" という意味らしいです。  

実装されている手法は以下のとおりです。
https://captum.ai/docs/algorithms

## 入力が出力に及ぼす影響を評価
- Integrated Gradients
- Gradient SHAP
- DeepLIFT
- DeepLIFT SHAP
- Saliency
- Input X Gradient
- * Guided Backpropagation
- * Guided GradCAM

## 特定のレイヤーのニューロンが出力に及ぼす影響を評価
- Layer Conductance
- Internal Influence
- Layer Activation
- Layer Gradient X Activation
- * GradCAM

## 隠れ層の活性が出力に与える入力の影響を評価
- Neuron Attribution
- Neuron Conductance
- Neuron Gradient
- Neuron Integrated Gradients
- * Neuron Guided Backpropagation

※ は2019/12/01 時点でmaster ブランチのみでしか実装されていないものとドキュメントに書かれていました。

# 実際に動かす
それでは実際に試してみます。
今回は、CIFAR10 のTutorial に沿って動かしてみます。
説明の大部分は端折るので、こちらを御覧ください。  
とても丁寧に書かれています。
https://captum.ai/tutorials/CIFAR_TorchVision_Interpret

## インストール
PyTorch >= 1.2 が必要です。
conda や pip で普通にインストールできます。  
ただし、 pip で入るのは、 0.1.0 なので、 0.2.0 を試してみたい場合はgithub からソースを落としてくる必要があります。
その際に、README.md のやり方だと[うまくいかない](https://github.com/pytorch/captum/issues/192)ので、

```
git clone https://github.com/pytorch/captum.git
cd captum
pip install -e .
```
の手順でインストールを実行しなくてはなりません。
自分は、最新版で試しました。

## 学習の実行
チュートリアルに書いてあるので割愛します。
GPU のある環境で動かすときは、
`net = Net().to('cuda:0')`
のような書き方に変更する必要がありますが、基本的に問題なく動くと思います。  

## 評価手法を試してみる

チュートリアルには、
- Gradient Magnitudes
- Integrated Gradients
- Integrated Gradients with SmoothGrad Squared
- DeepLift

の4つの手法が紹介されています。
今回はせっかくなので、GuidedGradCAM を試してみようと思います。

とはいえ、周りとほぼ変わらず、  

``` python
from captum.attr import GuidedGradCam
ggc = GuidedGradCam(net.to('cpu'), net.eval().conv1)
attr_ggc = attribute_image_features(ggc, input)
attr_ggc = np.transpose(attr_ggc.squeeze(0).cpu().detach().numpy(), (1, 2, 0))

_ = viz.visualize_image_attr(attr_ggc, original_image, method="blended_heat_map",sign="all",show_colorbar=True, 
                          title="GuidedGradCam")
```

と書くだけです。

以前、[Keras で実装](https://github.com/gorogoroyasu/mnist-Grad-CAM) したことがあったのですが、
とてもめちゃくちゃ便利になったなと感じましたｗ

あと、せっかくなので、ヒートマップだけ出す方法も調べてみました。
これもとても簡単で、visualize_image_attr の引数の method を heat_map に変えるだけ。
https://captum.ai/api/utilities.html?highlight=visualize_image_attr


こんな画像から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115634/a32307b8-61a3-fc28-408e-383abca4ec18.png)


こんな画像

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115634/3ceb0dfb-4b1b-3526-af20-519d54ac2fe7.png)

になります。

# 各々の評価手法の意味について
自分がちゃんと調査できていないので、追々記事を書こうと思います。
特に、Integrated Gradients は、一番最初に出てくるしめちゃくちゃ大事そうだなと感じました。
が、あまり日本語記事が出てないように思います。

また、画像が出てきたのはわかったけど、この色が濃いところ(1.0に近いところ)の意味が、
それぞれのアルゴリズムによって違いそうだなと思いました。
それらの意味を正確に知らないと正しく使えないと思うので、
その辺もきっちり調べていこうと思います。


最後になりますが、Issue に興味深いDiscussion があるのでご紹介します。

- BERT に適用: https://github.com/pytorch/captum/issues/150
- Semantic Segmentation に適用: https://github.com/pytorch/captum/issues/119
- SageMakerで動かす: https://github.com/pytorch/captum/issues/138
- Google Colabで動かす: https://github.com/pytorch/captum/issues/116

などです。
解決策が提案されるものもあれば、PR お願い みたいなやつもあります。
ぜひ覗いてみてください。