본문 바로가기

Python

[Python][Pytorch] SHAP 라이브러리 Error 공유

[Task] 시계열 연속형 데이터를 입력변수로 한 머신러닝/딥러닝 기반 예측 (Regression)

[Language] Python 3.6.12

[Framework] Pytorch 1.7.0

[Library] SHAP 0.35.0

 

이 글에서는, 파이썬의 shap 라이브러리를 사용하던 중 겪은 error와 나름의(?) 해결 방법을 공유합니다.

해당 에러는 torch에서 DNN모델을 구축한 후, shap를 적용한 상황에서 겪은 오류들로 주로, 구글링을 해도 잘 나오지 않는 정보에 대해 공유하려 합니다. 

 

1) shap summary plot 사용시 grey color dot

 

 

 torch에서 DNN모델을 만들고, 해석을 위해 가장 먼저 summary plot을 뽑는데, 이제껏 잘 나오던 것이 회색 도트로 찍히면서 애를 먹였다. 오른쪽 그림(정상그림)처럼 컬러가 표시가 되어야 하는데 왼쪽 그림(회색컬러플롯)처럼 feature값이 반영이 안되는 문제가 발생했다.

구글링을 해보면, grey color로 뜨는 이유가 feature값에 'NaN'이 포함되어 있을거란 답변이 우세했는데 내 데이터에서는 눈씻고 찾아봐도 없었다. 여태 LightGBM, Sklearn의 MLP라이브러리 등에서 문제가 없었는데 torch에서 갑자기 이러니 당황스러웠다.

 

tensor to numpy

 여러 삽질을 하던 중, 굉장히 심플한 방법으로 해결해버렸다.

feature로 넣은 데이터가 아래와 같이 tensor로 들어가있는데, detach().cpu().numpy()를 사용해서 array로 바꿔주고 나니 정상적으로 컬러가 나타났다. 

 

 

2) 런타임 에러

(뾰족한 방법은 아니지만 일단은 해결되었으니 공유해봅니다. )

 

RuntimeError: The size of tensor a (64) must match the size of tensor b (32) at non-singleton dimension 1

Explainer까지는 만들어 졌으나, shap value 계산 단계에서 runtime error가 발생했다. 

대충 tensor 사이즈가 안 맞다는 얘기인 듯 한데, 

파일럿을 위해 무식하게 일단 세운 모델은 다음과 같다.

 

hidden layer 3개와, 입력층과 출력층이 있다. 

처음에 hidden layer 1층일 때는 문제없이 돌아갔는데, 3층으로 바꾸고나서 이런 에러를 만났다. 무슨 이유일까.. 

여기 에 소개된 내용에 의하면 층이 여러개라도 연산이 가능해야 하는데 비교를 해봐도 무슨 차이인지 도무지 알 수 없었다. 무작정 해본 방법은 코드를 공유된 예시처럼 바꿨더니 에러가 해결되었다.

 

위 아래 둘다 흔한 example코드를 따온건데.. 무슨차이가 있어서 에러가 해결되고, 에러가 발생하는지는 찾지못했다.

아시는 분 계시면 댓글로 공유 부탁드립니다 :)

 

3) SHAP CUDA Error - 데이터 형식 오류

RuntimeError: CUDA error: device-side assert triggered

종종 torch를 사용하다보면 이런 에러를 접하게되는데, batch size를 줄이면 해결되는 경우가 다반수라고 한다.

하지만 shap 에서 waterfall plot 함수를 사용하는데 CUDA Error가 났다.

 

waterfall plot에서 CUDA Error

summary plot이나 dependence plot에서는 문제가 없었다. 그래서 함수 코드를 보니, 아래 첨부된 사진처럼 features 자리에 array형식의 데이터가 들어가야 한다고 설명되어있다.

 

shap waterfall plot 함수 코드

다른 플롯 찍을땐 array로 넣어둬서 에러가 안났었다. 아마 업데이트된 라이브러리에서는 해결이 되어있겠지..?

DeepExplainer는 keras, pytorch, tensorflow 환경에서 구축된 모델에 적용할 수 있는 설명모델인데, 데이터형식을 tensor로 안받고 array로 받는데, 에러 정보는 완전 다른 얘기를 하니 적잖이 삽질을 하기 좋다.

 

tensor를 array로 바꿔서 넣어주니 정상 작동한다.

그리고 이 CUDA 에러가 한번 나면 그대로 잘 작동되던 코드도 breakdown되어서, Kernel Restart 하니 정상작동 되었다.

 

구글링해도 잘 나오지 않는 에러가 발생하면 꾸준히 공유하도록 하겠습니다.