본 포스팅은 아래 게시물을 참고했습니다.
- https://tutorials.pytorch.kr/beginner/introyt/captumyt.html
- https://tutorials.pytorch.kr/recipes/recipes/Captum_Recipe.html
- https://captum.ai/docs/algorithms
pytorch 튜토리얼을 보다가 Captum을 알게 돼서 정리해보았습니다.
Captum
Captum으로 데이터 특징(features)이 모델의 예측 또는 뉴런 활성화에 미치는 영향을 이해하고, 모델의 동작 방식을 알 수 있습니다. 그리고 Integrated Gradients와 Guided GradCam과 같은 feature attribution 알고리즘를 쉽게 적용할 수도 있습니다.
Captum은 다음과 같은 많은 알고리즘을 제공합니다.
- Occlusion : grey-box로 가린 후 output의 차이를 보는 perturbation based approach
- Integrated Gradients : input에 대한 output의 gradient의 적분을 근사화하는 방식
- Deconvolution, GuidedBackprop : input에 대한 output의 기울기를 구하는 방식
- Guided GradCam : upsampled (layer) GradCAM attributions과 guided backpropagation를 element-wise하게 하는 방식, 여기서 GradCAM attributions은 layer 단위로 계산된 후 input size에 맞추기 위해 upsampled된다.
- DeepLift : back-propagation based approach, input과 reference의 차이로 input을 변화시키는 것?
- GradientShap : SHAP values를 계산해서 Gradient를 구하는 것. 각 입력 샘플에 가우스 노이즈를 여러 번 추가하고 기준선과 입력 사이의 경로를 따라 임의의 점을 선택하고 선택한 임의의 점에 대한 출력의 기울기를 계산합니다.
더 자세한 설명은 아래 링크를 참고해주세요.
https://captum.ai/docs/algorithms
이 포스팅에서는 튜토리얼에 있는 Integrated Gradients와 Occlusion과 GradCam을 사용해보겠습니다.
오늘의 테스트는 아래 고양이 사진으로 하겠습니다.
Feature Attribution with Integrated Gradients
input에 대한 output의 gradient의 적분을 근사화 해서 input feature에 importance score를 부여하는 방법, gradient를 적분하기 때문에 integrated gradients이다.
integrated_gradients = captum.attr.IntegratedGradients(model)
attributions_ig = integrated_gradients.attribute(input_img, target=pred_label_idx, n_steps=200)
Feature Attribution with Occlusion
occlusion = Occlusion(model)
attributions_occ = occlusion.attribute(input_img, target=pred_label_idx, strides=(3, 8, 8), sliding_window_shapes=(3,15, 15), baselines=0)
아래와 같은 결과를 얻었습니다.
positive attribute는 target output에 positive한 영향을 주는 것, negative attribute는 negative한 영향을 주는 것으로 이해했습니다.
Masked는 negative한 영향을 주는 입력을 masked한 이미지 입니다.
Layer Attribution with Layer GradCAM
layer_gradcam = LayerGradCam(model, model.layer3[1].conv2)
attributions_lgc = layer_gradcam.attribute(input_img, target=pred_label_idx)
upsamp_attr_lgc = LayerAttribution.interpolate(attributions_lgc, input_img.shape[2:])
아래 이미지는 layer3에서 target output에 영향을 주는 부분을 표현한 이미지 입니다.
원본 이미지에 붙여넣으면 아래와 같습니다.