1편에서 감성분석 처리절차, Bert 언어모델, Kobert, 네이버 영화펑 코퍼스 로드까지 살펴보았다. 이제 이어서 KobertTokenizer 환경 준비부터 모델 훈련 평가까지의 절차를 살펴보도록 하자.
KobertTokenizer 환경 준비
우선 아래와 같이 huggingface
transformers 와 google sentencepiece를 import 한다.
Huggingface 의 transformers 로부터 Kobert 를 사용하려면 여기 에 있는 tokenization_kobert.py 내용을 프로그램내로 복사해온 후에 KobertTokenizer 를 import 한다.
아래 그림 6의 ①은 senterpiece 의 unicode 형식의 ‘_’ 을 정의한 것. ②는
KobertTokenizer 가 sentencepiece를 필요로 함을 설명. ③은 사전 학습된 토크나이저 모델을 가져올 주소. Huggingface 의
모델 리포지토리에도 있다. ④는 관련 어휘사전. 8002개의 token을 가지고 있다. 역시 huggingface
리포지토리에도 있다. ⑤ 소문자 변환 구성을 False 해 주어야 한다. ⑤ 는 사전 학습 tokenizer 의 position embedding: 크기는 512 로 정의.
<그림 6.
Tokenization_kobert.py 의 KobertTokenizer class 변수
정의>
아래 그림 7과 같이 tokenize 함수를 보면 ①번에 Sentencepiece 토크나이즈를
사용하는 것을 알 수 있다. ②번은 분절된 토큰의 끝이 “,” 이고
길이가 1이상 경우에 그 토큰의 언더바“_“를 없애고 다시
sentencepiece 토큰화를 시도하여 cur_pieces에
대입한다. ③은 이러한 cur_pieces 의 처음이 언더바”_”인 경우, 하나의 컬럼 요소인 경우 전체를 cur_pieces 로 지정한다. ④는 컬럼 요소가 2인 경우에는 두번째 컬럼을 첫번행의 값으로 치환한다. 이렇게하여 각각
new_pieces 에 담긴 값을 리턴한다. 언더바(“_”)가 분절의 처음에 위치한 것을 이용하여 그 이후 분절에 활용하는 것을 알 수 있다.
<그림 7. KobertTokenizer 내의
tokenize 함수>
자 이제KobertToknizer 를
이전 그림 6에서 ‘monologg/kobert”로 정의하였던
구성을 통해 호출해보자.
Tokenizer.tokenize 를 통해 토큰화 된 결과를 확인한다. Encode 는 인코딩된 숫자로 나타나고 나중에 decode 를
하면 원문으로 복원된다.
지금까지 huggingface에서 제공하는
한글 형분석기에 기반한 사전 학습된 KobertTokenizer 에 대해 알아보았다.
Naver 문장들을Bert input
용 변환
자 이제 다음 일은 네이버 영화평 15만개의
train 데이터들을 Bert 에 입력되는 형식과 맞추어
주는 일을 해야 한다. 이렇게 하는 이유는 33억 어절로
사전 학습된 Bert base 모델의 전이 학습에 더해서 네이버 영화평 한글 데이터들을 입력으로 한
추가 layer 를 추가하여 파인 튜닝을 실시할 계획이어서 앞의 그림 3의 BERT 에 입력되는 토큰의 임베딩 형식과 같이 네이버 데이터를
변환해 주어야 한다.
Bert 형식의 토큰 임베딩 형식은 예를
들어 입력최대 길이를 64(max_length=64)로 정의할 경우,
아래와 같이 한글 문장에 해당하는 부분은 인코딩 숫자로 나머지는 1로 채워진다.
Bert 형식의 mask 임베딩 형식은 아래와 같이 한글 문장에 해당하는 부분은 1로, 나머지는 0으로 채워진다. 임베딩되는
형식은 ①과 같은 표현식으로 토큰 숫자만큼 1로 (valid_num
* [1]) 그리고 나머지는 0으로 (64 – valid_num)
* [0])으로 임베딩된다.
자 그럼 네이버 영화평 문장들을 Bert
input 용으로 하기위해 토큰 input, segment input, mask input 형식으로
데이터들을 변환해보자.
아래 그림 8을 보면 네이버 데이터프레임을
입력으로하는 convert_data 함수다. ① 네이버 테이블을
한 행의 문장씩 읽어 들여 ② 해당되는 네이버 문장의 컬럼(document)에 해당하는 문장을 global 로 선언된 KobertTokenizer 를 통해 인코딩한다. ③은 바로 전에 살펴본 mask 임베딩 형식과 같이 한글 토큰만큼
1을 나머지는 0을 넣어준다. ④ 네이버 영화평은 Bert처럼 두 개의 이어지는 문장이 아니라
단일 문장이어서 한 문장 최대길이 64 길이만큼 0으로 채운다. ⑤번은 ①번의 for 루프만큼 해당 문장의 타겟 즉 0 혹은 1의 레이블을 targets
리스트에 추가(append)한다. 그리고 ⑥에서
[토큰, 마스크, 세그먼트]와 함께 타겟을 리턴 한다.
<그림 8. 네이버 영화평 문장의 Bert input 형식으로의 변환>
그리고 아래의 load_data 함수는
네이버의 문장과 레이블 데이터프레임을 위의 convert_data를 통하여 변환한 변환된 문장 data_x 와 레이블 data_y 로 리턴 한다.
네이버 train, test 데이터를
load_data 를 통해 Bert input 에 맞게 변환한다.
<그림 9. Bert 입력 용으로 변환된
네이버 훈련 및 테스트 데이터>
Bert Model 구축
Huggingface 의 transformer 라이브러리는 다양한 Bert 분류 모델을 제공한다. Tensorflow 환경의
TFBert의 사전 훈련 모델을 사용하여 ①과 같이 정의한다. ②,③,④를 통해 토큰, 마스크
및 세그먼트 입력을 정의. ⑤ 인풋이 토큰, 마스크, 세그먼트 인 모델 정의
<그림 10. Bert 모델 정의>
다음으론 Rectified Adam Optimizer를
정의. 이를 위하여 ①과 같이Tensorflow addon을
설치하고 import, ② Rectified Adam
Optimizer 를 정의, ③ warmup 비율을
10% 로 하여 처음 learning rate 를 ④와 같은
1e-5 로 시작하여 전체 공정의 10%를 최대값인 5e-5가 될 때까지 점진적으로 올려준다.
<그림 11. Rectified Adam
Optimizer 정의>
파인 튜닝을 위해 Bert 사전 학습
모델위에 아래와 같은 layer 들을 모델에 추가한다. ①은
이전 그림 10의 ⑤인 bert_outputs 를 입력으로
0.5 값으로 dropout 층을 추가한다. ②번에서 긍정 부정을 판별할 sigmoid 이진 판별이 Dense 층을 추가한다. ③번에서 이전 모델을 입력으로하여 입력이 토큰, 마스크, 세그먼트인 모델 정의 ④에서 Rectified Adam Optimizer 와 BinaryCrossentropy loss 그리고 accuracy metrics
를 쓰는 모델 컴파일
<그림 12. 파인 튜닝 모델 정의>
아래 그림 13를 보면 ①번에 Bert 에 입력되기위한 토큰, 마스크, 세그먼트 입력이 bert_outputs
으로부터 만들어져 있고 ②번에 Bert base 모델이 ③번에 dropout ④에 dense layer 를 확인 할 수 있다. 92,187,649 파라미터 수를 확인한다.
<그림 13. 모델 summary>
아래 그림 14과 같이 모델 훈련을
시작한다. ①번에 이전 그림 9의 train_x, train_y를 입력으로, epoch는 2회 batch_size는 64 (메모리
부하를 염두에 두고 낮게 설정), validation_data 는 test_x
와 test_y를 입력.
<그림 14. 모델 훈련>
훈련 결과 2번의 epoch를 수행하였는데 google colab으로 1시간 20분 정도 소요되었고 ②번과 같이 accuracy 가 0.892, validated accuracy 가
0.883을 달성하였다.
결언
지금까지 2편에 걸쳐 딥러닝을 이용한 감성분석 모델 구축 방법을 살펴보았다. 네이버 영화평 코퍼스를 이용하여 한글 형분석기가 반영된 Kobert 사전
훈련 tokenizer를 활용하여 huggingface의 transformers 가 제공하는 Bert 사전 훈련 모델 베이스를
전이 학습으로 사용하였다. 이에 더하여 네이버를 Bert 입력용으로
변환한 데이터들을 입력으로 하여 긍정 부정을 판별하는 이진 분류기를 추가하는 파인 튜닝을 통하여 epoch 2회
훈련에 accuracy 가 0.892를 달성하였다. 그림 4에서 Kobert의
경우 0.901 의 accuracy 를 달성하였다고 문헌에
나와있는데, epoch 를 4이상으로 늘리면 달성이 가능할
것으로 기대된다.