일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
- 데이터넥스트레벨챌린지
- 데이터리안
- Optimizer
- 데벨챌
- KeyBert
- BERTopic
- 개체명 인식
- Tableu
- 구글 스토어 리뷰
- 원신
- geocoding
- 조축회
- 옵티마이저
- CTM
- 트위치
- 코사인 유사도
- 클래스 분류
- 토픽 모델링
- 붕괴 스타레일
- Roberta
- 자연어 모델
- 다항분포
- 피파온라인 API
- 블루 아카이브
- NLP
- SBERT
- 블루아카이브 토픽모델링
- 포아송분포
- 문맥을 반영한 토픽모델링
- LDA
- Today
- Total
분석하고싶은코코
XAI - LIME(Local Intcrprctablc Model-agnostic Explanations) 본문
오늘 포스팅에서 다뤄볼 내용은 XAI(설명 가능한 AI)중 하나인 LIME(Local Intcrprctablc Model-agnostic Explanations)입니다.
LIME을 사용해보기 위해서 사용할 훈련된 모델은 이전 포스팅에서 만든 비속어 탐지 모델입니다. 그 중에서 LSTM으로 훈련시킨 모델을 통해서 LIME에 대해서 실습을 진행해보도록 하겠습니다.
!역시 비속어에 대한 모델을 통해 결과를 확인하기 때문에 욕설에 대한 내용이 담겨져 있습니다.
여러 모델을 활용한 비속어 문장 탐지
이번 포스팅에서는 여러 모델을 활용한 비속어(hate_speach)를 탐지하는 것에 대한 포스팅을 해보겠습니다. !이번 포스팅은 비속어(욕설) 텍스트에 대한 탐지를 다룬 프로젝트로 결과 예시에 욕설
coco0414.tistory.com
XAI(설명 가능한 AI)?
코드로 결과를 확인해보기 이전에 설명가능한 AI에 대해서 먼저 알아보도록 하겠습니다. 딥러닝에 대한 기본 개념을 이해하셨다면 딥러닝의 한계점 중 하나인 복잡한 모델에 대한 이해를 하기 어렵다라는 점을 알고 계실것이라 생각합니다. 그 이유는 딥러닝 모델에 쌓아 놓은 히든 유닛에 대한 가중치들이 각각 존재하는데 입력값이 들어가면 각 가중치를 받아 히든 유닛으로 값들이 보내지고 이게 다시 출력층으로 모아 지정한 라벨만큼의 결과를 만들어 주게 됩니다. 그런데 이 한계점을 극복하고자 나온 것이 설명 가능한 AI로 모델이 입력값에 대한 결과값을 도출해 내는 과정에 대해서 세분화하여 어떤 요소들이 이러한 결과값을 나오게 했는지에 대한 추론을 해줄 수 있게 해주는 또 다른 모델입니다.
쉽게 예를 들어보면 텍스트의 감성 분석을 진행한다고 가정해보겠습니다. 그러면 하나의 문장이 들어가고 이것을 딥러닝 모델은 훈련된 가중치들로 인해 긍정과 부정에 대한 분류 작업을 진행합니다. 작업이 완료되어 예를들어 부정에 대한 결과를 아웃풋을 주었다고 가정하겠습니다. 그런데 이런 딥러닝 모델에서 어떤 단어 때문에 부정이 되었는지 알 수 있을까요? 알지 못합니다. 단순하게 하나의 층으로만 되어 있고 히든 유닛이 적다면 노가다를 통해서 그 값을 찾아낼 수 있지만 층이 깊어 질수록, 히든 유닛이 많아질수록 이런 노가다 작업은 할 엄두조차 나지 않습니다. 그런데 이것을 설명해줄 수 있는 개념이 등장하였고 그게 XAI(설명 가능한 AI)입니다.
LIME(Local Intcrprctablc Model-agnostic Explanations)
그럼 이번에는 XAI의 대표적인 모델 중 하나인 LIME을 활용해서 그 결과를 확인해보겠습니다.
우선 LIME을 사용하기 위해서 패키지 설치가 필요합니다.
!pip install lime
LIME 패키지와 LIME패키지 안에서도 텍스트 모델에 대한 해석을 해줄 수 있는 lime_text 패키지를 불러오겠습니다. 그리고 이전에 만들었던 모델을 불러옵니다.
import lime
from lime import lime_text
# 훈련된 모델 불러오기
lstm_model = load_model('best_model.h5')
# LIME 설명 모델 초기화
explainer = lime_text.LimeTextExplainer()
그리고 LIME을 사용하기 위한 모델을 통한 예측 함수를 만들어줘야합니다. 이 함수를 만들어줘야하는 이유는 아래서 위에서 초기화한 explanier를 통해 결과를 받을때 자세하게 설명하도록 하겠습니다.
# 모델의 예측 함수 정의
def predict_function(texts):
# new_sentence = preprocessing(texts)
encodeds = [tokenizer.encode(text).ids for text in texts]
pad_new = [pad_sequences(encodeds, maxlen = max_len)]
predictions = lstm_model.predict(pad_new)
return predictions
모델을 통해서 비속어 문장인지에 대해서 탐지해볼 예시 두 개의 문장입니다. 위에서 선언해둔 예측 함수를 통해 결과 값을 확인해보았습니다. 이전 포스팅에서도 확인했듯 '시1발'과 같이 우회하는 텍스트로 비속어를 사용할 경우 해당 모델에서는 비속어로 탐지하지 못하고 있습니다. 그렇다면 어떻게 저런 확률이 나오게 됐는지 지금의 우리는 이해하기 어렵지만 LIME을 통해 그 결과를 확인해보겠습니다.
new_sentence = ['아니 시1발 ㅈ같네 진짜', '아니 시발 개짜증나네']
predict_function(new_sentence)
# 출력값
array([[0.24233653],
[0.9368914 ]], dtype=float32)
결과1
# 텍스트에 대한 설명 가능한 정보 만들기
explanation = explainer.explain_instance(new_sentence[0], predict_function, num_features=len(new_sentence[0].split()), labels=(0,))
# 설명 시각화
explanation.show_in_notebook()
결과2
# 텍스트에 대한 설명 가능한 정보 만들기
explanation = explainer.explain_instance(new_sentence[1], predict_function, num_features=len(new_sentence[1].split()), labels=(0,))
# 설명 시각화
explanation.show_in_notebook()
결과를 보면 비속어 인지 판단하는데 있어서 어떤 단어가 영향을 주었는지 자세히 알 수 있습니다. '시발'이라는 단어는 비속어로 크게 영향을 주고 있는 단어로 판단하고 있지만 '시1발'이라는 단어는 'ㅈ같네'라는 단어 보다 낮은 영향을 주고 있습니다. 'ㅈ같네'도 비속어로 들어가고 이 형태 역시 우회하고 있는 형태로 보아야하기 때문에 두 형태가 낮은 것으로보고 결과적으로 비속어로 판단하는 최종 확률이 0.24로 낮게 나온 것입니다. 그에 반해서 '아니'와 '진짜'의 경우에는 비속어로 판단하지 않은 결과도 알 수 있죠.
이처럼 LSTM이라는 복잡한 딥러닝 모델로 설계한 모델에서 어떤 요소들이 결과에 영향을 주었는지 확인을 할 수 있습니다. 이는 비속어에 대한 분류 작업 혹은 비속어에 대한 리스트를 올리고 우회 형태에 대한 탐지를 제대로 하고 있는지에 대한 보다 명확한 정보를 얻을 수 있고 이를 통해 모델을 더 개선할 수 있는데 도움을 줍니다.
LIME 사용 과정
그렇다면 이제 위에서 LIME을 사용해서 결과를 받아오는 과정에 대한 설명을 해보겠습니다. 우선 예측을 위한 함수를 만든 이유에 대해서 이야기 해보겠습니다. 아래의 코드는 설명에 대한 정보를 만들어 내는 함수입니다. 이를 위해서 들어가야하는 파라미터는 다음 과 같습니다.
- 첫 번째 : 원본 텍스트
- 두 번째 : 모델을 통한 예측 함수
explanation = explainer.explain_instance()
# explanation = explainer.explain_instance(new_sentence[0], lstm_model.predict)
위의 조건으로 본다면 주석 처리된 줄과 같이 쓰면 되는것이 아닌가? 라고 생각할 수 있습니다. 하지만 그렇지 않습니다. 그 이유는 LIME이 동작하는 과정에 대한 이해를 하면 쉽게 됩니다. LIME에서 결과를 만들어내기 위해 원본 텍스트가 필요한 이유는 LIME에서 텍스트를 분해 하여 모델에 넣어서 그 결과를 가져옵니다. 그런데 주석된 상태에서 들어간다면 '아니 시1발 ㅈ같네 진짜', '아니', '시1발', '아니 시1발'....의 형태로 N-gram과 같은 형태로 문장을 분해하여 모델을 통해 값을 가져오게 됩니다. 그런데 해당 상태로 넣으면 우리가 모델을 훈련시켰던 형태와 다르게 됩니다. 그래서 인코딩 과정이 필요하게 됩니다. LIME모듈에서는 제가 인코딩한 과정에 대해서까지 지원을 해주지 않기 떄문에 이 부분을 인코딩하게 해줘야하고 LIME에서 문장을 분해하여 만들어낸 데이터를 인코딩하게끔 함수를 만들어 줘야하는 것입니다. 그래서 위에서 선언한 예측을 위한 함수가 필요했던 것입니다.
실제로 위에서 정의한 함수에서 어떤 값들이 들어오는지 직접 확인해보겠습니다. 출력값은 explanier.explain_instance를 호출하여 얻은 출력값입니다. 굉장히 많은 텍스트 들이 들어오게되고 형태는 리스트 안에 텍스트가 들어가 있는 형태로 들어오는 것을 확인할 수 있습니다. 이 형태를 인코딩해주고 모델에 넣어서 결과값을 받아오게끔 함수를 설계해야합니다.
def predict_function(texts):
print(texts)
...
# 출력값
['아니 시1발 ㅈ같네 진짜', ' ', ' ㅈ같네 진짜', ' 진짜', ' 진짜', ' 시1발 진짜', ' ', ' ', ' ㅈ같네 진짜', '아니 ㅈ같네 진짜', '아니 시1발 ', '아니 시1발 ', '아니 시1발 진짜', ' 시1발 ㅈ같네 진짜', ' ....]
그런데 여기서 또 중요한 점은 모델을 어떻게 설계했는지가 중요합니다. 저는 비속어 문장인지 아닌지 판단하기 위해서 모델에서 하나의 값을 결과값을 받아옵니다. 그래서 아래와 같이 labels옵션으로 (0,)의 옵션을 주게 된 것이죠. 모델을 어떻게 설계했는지에 따라 라벨이 달라지고 이를 설정해줘야 시각화 정보를 만들어주게 됩니다. 또 num_features라는게 있는데 이 부분은 코드를 통해서 유추하셨겠지만 띄어쓰기를 기준으로 단어가 몇개인지에 대해서 설정하는 부분입니다. 만약 원래 문장을 띄어쓰기로 분리해 수를 정하지 않고 2개로 임의 설정했을때 어떻게 나올지 확인해보겠습니다.
explanation = explainer.explain_instance(new_sentence[0], predict_function, num_features=len(new_sentence[0].split()), labels=(0,))
explanation = explainer.explain_instance(new_sentence[0], predict_function, num_features=2, labels=(0,))
explanation.show_in_notebook()
단번에 이해가 되시겠죠? 상위 2개에 대한 피처에 대한 정보만을 보여줍니다. 이를 통해 확인할 수 있는 부분은 문장의 길이가 너무 길면 피처 수를 지정해서 시각화를 간단하게 만들어줄 수 있습니다.
LIME을 통해서 자연어(텍스트) 모델을 통해 나온 결과가 어떻게 나온 것인지에 대한 이해를 해보는 과정을 확인해보았습니다. LIME을 통해서는 텍스트 뿐 아니라 다양한 모델에 대한 설명 정보 시각화가 가능합니다. 이 부분은 LIME 패키지를 직접 찾아보시기를 권장드립니다.
'머신러닝&딥러닝 > NLP' 카테고리의 다른 글
RLHF(Reinforcement Learning from Human Feedback)_(2) - RM(Reward Model) (2) | 2023.12.28 |
---|---|
RLHF(Reinforcement Learning from Human Feedback)구현해보기_(1) - STF(Supervised Fine-tuning) (0) | 2023.12.25 |
여러 모델을 활용한 비속어 문장 탐지 (0) | 2023.12.18 |
간단한 텍스트 생성(Text Generation) 모델 구현해보기 (0) | 2023.12.16 |
NLP - Pytorch Finetune LightningModule (1) | 2023.10.24 |