MODEL UNDERSTANDING WITH CAPTUM
CAPTUM이란?
- facebook이 개발한 오픈소스 라이브러리
- Pytorch 기반
- NLP모델이나 컴퓨터 비전 모델의 예측 결과를 이해하도록 도움
- 입력이미지의 어떤 부분을 바라보고 예측을 내놓는 지 활성화 되는 부분을 시각화 해줌
1
2
3
강아지 예측 시 입력 이미지의 오른쪽 부분이 활성화가 되고 고양이 예측 시 입력 이미지의 왼쪽 부분이 활성화 되는 것을 확인 할 수 있다.
샘플 이미지의 어떤 부분이 특정한 예측에 도움을 주는지 보여주는 셈이다.
Attribution of CAPTUM
- Feature Attribution : 특정 출력을 생성한 input의 특성 측면에서 설명하려고 합니다. 영화 리뷰가 긍정적이거나 부정적인 이유를 리뷰의 특정 단어로 설명하는 것은 Feature Attribution의 한 예다.
- Layer Attribution : 특정 input에 이어 모델의 hidden layer 활동을 검토합니다. 입력 이미지에 대한 응답으로 convolutional layer의 공간적으로 매핑된 출력을 검사하는 것이 Layer Attribution의 예다.
- Neuron Attribution : Layer Attribution과 유사하지만 단일 뉴런의 활동에 초점을 맞춘다.
attribution algorithms associated with it
- Gradient-based algorithms : 입력에 대한 모델 출력, 레이어 출력 또는 뉴런 활성화의 역방향 그래디언트를 계산한다. 통합 그래디언트(Integrated Gradients, 특성에 대해), 레이어 그래디언트 * 활성화(Layer Gradient * Activation), 뉴런 전도도(Neuron Conductance)는 모두 그래디언트 기반 알고리즘이다.
- Perturbation-based algorithms : 입력의 변화에 대한 모델, 레이어, 또는 뉴런의 출력 변화를 조사한다. 입력 교란은 방향성이 있거나 무작위일 수 있다. 가리기(Occlusion), 피처 소거(Feature Ablation), 피처 순열(Feature Permutation)은 모두 Perturbation-based 알고리즘이다.
설치 환경
시작하기 전에 다음을 갖춘 Python 환경이 필요함
- Python 버전 3.6 이상
- Captum Insights 예시의 경우 Flask 1.1 이상 및 Flask-Compress(최신 버전 권장)
- PyTorch 버전 1.2 이상(최신 버전 권장)
- TorchVision 버전 0.6 이상(최신 버전 권장)
- Captum (최신 버전 권장)
- Matplotlib 버전 3.3.4(Captum은 현재 이후 버전에서 인수 이름이 변경된 Matplotlib 함수를 사용하므로)
with conda:
1
conda install pytorch torchvision captum flask-compress matplotlib=3.3.4 -c pytorch
with pip:
1
pip install torch torchvision captum matplotlib==3.3.4 Flask-Compress
colab에서는 !pip install captum 사용
First Example
예제는 torchvision에서 ImageNet에서 pretrained된 resnet18 모델을 사용해서 예측 결과를 내놓을 때, 해당 예측이 입력 이미지의 어떤 부분으로부터 추론되었는 지를 보여줌.
라이브러리 import 및 이미지 전처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import torchvision
from torchvision import transforms
from PIL import Image
import requests
from io import BytesIO
model = torchvision.models.resnet18(pretrained=True).eval()
response = requests.get("https://image.freepik.com/free-photo/two-beautiful-puppies-cat-dog_58409-6024.jpg")
img = Image.open(BytesIO(response.content))
center_crop = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
])
normalize = transforms.Compose([
transforms.ToTensor(), # 이미지를 0에서 1사이의 값을 가진 Tensor로 변환
transforms.Normalize( # 0을 중심으로 하는 imagenet 픽셀의 rgb 분포를 따르는 정규화
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])
input_img = normalize(center_crop(img)).unsqueeze(0)
속성(attribution) 계산하기
모델의 top-3 예측 중에는 개와 고양이에 해당하는 클래스 208과 283이 있다.
Captum의 \ Occlusion
\ 알고리즘을 사용하여 각 예측을 입력의 해당 부분에 표시한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from captum.attr import Occlusion
occlusion = Occlusion(model)
strides = (3, 9, 9) # 작을수록 = 세부적인 속성이지만 느림
target=208, # ImageNet에서 Labrador의 인덱스
sliding_window_shapes=(3,45, 45) # 객체의 모양을 변화시키기에 충분한 크기를 선택
baselines = 0 # 이미지를 가릴 값, 0은 회색
attribution_dog = occlusion.attribute(input_img,
strides = strides,
target=target,
sliding_window_shapes=sliding_window_shapes,
baselines=baselines)
target=283, # ImageNet에서 Persian cat의 인덱스
attribution_cat = occlusion.attribute(input_img,
strides = strides,
target=target,
sliding_window_shapes=sliding_window_shapes,
baselines=0)
Captum은 Occlusion
외에도 \ Integrated Gradients
\ , \ Deconvolution
\ , \ GuidedBackprop
\ , \ Guided GradCam
\ , \ DeepLift
\ , 그리고 \ GradientShap
\과 같은 많은 알고리즘을 제공한다. 이러한 모든 알고리즘은 초기화할 때 모델을 호출 가능한 \ forward_func
\ 으로 기대하며 속성(attribution) 결과를 통합해서 반환하는 attribute(...)
메소드를 가지는 Attribution
의 서브클래스이다.
이미지인 경우 속성(attribution) 결과를 시각화 해보자.
결과 시각화하기
Captum의 \ visualization
\ 유틸리티는 그림과 텍스트 입력 모두에 대한 속성(attribution) 결과를 시각화 할 수 있는 즉시 사용가능한 방법을 제공한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np
from captum.attr import visualization as viz
# 계산 속성 Tensor를 이미지 같은 numpy 배열로 변환합니다.
attribution_dog = np.transpose(attribution_dog.squeeze().cpu().detach().numpy(), (1,2,0))
vis_types = ["heat_map", "original_image"]
vis_signs = ["all", "all"] # "positive", "negative", 또는 모두 표시하는 "all"
# positive 속성은 해당 영역의 존재가 예측 점수를 증가시킨다는 것을 의미합니다.
# negative 속성은 해당 영역의 존재가 예측 점수를 낮추는 오답 영역을 의미합니다.
_ = viz.visualize_image_attr_multiple(attribution_dog,
np.array(center_crop(img)),
vis_types,
vis_signs,
["attribution for dog", "image"],
show_colorbar = True
)
attribution_cat = np.transpose(attribution_cat.squeeze().cpu().detach().numpy(), (1,2,0))
_ = viz.visualize_image_attr_multiple(attribution_cat,
np.array(center_crop(img)),
["heat_map", "original_image"],
["all", "all"], # positive/negative 속성 또는 all
["attribution for cat", "image"],
show_colorbar = True
)
만약 데이터가 텍스트인 경우 visualization.visualize_text()
는 입력 텍스트 위에 속성(attribution)을 탐색할 수 있는 전용 뷰(view)를 제공한다. http://captum.ai/tutorials/IMDB_TorchText_Interpret 에서 자세한 내용을 확인할 수 있음.
Captum 마지막 정리
Captum은 이미지, 텍스트 등을 포함하여 다양한 방식으로 PyTorch에서 대부분의 모델 타입을 처리할 수 있다. Captum을 사용하면 다음을 수행할 수 있다. 위에서 설명한 것처럼 특정한 출력을 모델 입력에 표시하기 특정한 출력을 은닉층의 뉴런에 표시하기 (Captum API reference를 참고). 모델 입력에 대한 은닉층 뉴런의 반응을 표시하기 (Captum API reference를 참고).
지원되는 메소드의 전체 API와 튜토리얼의 목록은 http://captum.ai 를 참조.
Gilbert Tanner의 또 다른 유용한 게시물 : https://gilberttanner.com/blog/interpreting-pytorch-models-with-captum
참고 코드
https://colab.research.google.com/github/PyTorchKorea/tutorials-kr/blob/master/docs/_downloads/642248c95070825e7ac912504a919140/Captum_Recipe.ipynb
참고 사이트 : https://velog.io/@hottogi/pytorch-CAPTUM-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%AA%A8%EB%8D%B8-%ED%95%B4%EC%84%9D