2023. 5. 18. 01:49ㆍ연구 프로젝트/감성 자질 모델
2. 구현 도전
3) BERT의 사전 학습
**코드 출처: GitHub - monologg/KoELECTRA: Pretrained ELECTRA Model for Korean
GitHub - monologg/KoELECTRA: Pretrained ELECTRA Model for Korean
Pretrained ELECTRA Model for Korean. Contribute to monologg/KoELECTRA development by creating an account on GitHub.
github.com
(4) 감성 자질 임베딩 레이어 위치
*원래 BERT의 세 임베딩 입력값(토큰 임베딩, 세그먼트 임베딩, 위치 임베딩)은 modeling.py 파일의 embedding_postprocessor 함수에서 이루어짐
def embedding_postprocessor(input_tensor, #[배치 사이즈, 문장 길이, 임베딩 차원]의 tensor
use_token_type=False, #토큰 임베딩 사용 유무
token_type_ids=None, #입력 데이터의 세그먼트 정보
token_type_vocab_size=16, #입력 데이터의 세그먼트 정보의 단어 개수
token_type_embedding_name="token_type_embeddings", #세그먼트 정보 임베딩 변수 이름
use_position_embeddings=True, #위치 임베딩 사용 유무
position_embedding_name="position_embeddings", #위치 임베딩 변수 이름
initializer_range=0.02, #가중치 초기값 범위
max_position_embeddings=512, #문장 최대 길이
dropout_prob=0.1): #마지막 output tensor에 드롭아웃 적용할 확률
input_shape = get_shape_list(input_tensor, expected_rank=3) #입력값의 사이즈를 get_shape_list 함수 이용해 리스트 형태로 저장: [배치 사이즈, 문장 길이, 임베딩 차원]
batch_size = input_shape[0]
seq_length = input_shape[1]
width = input_shape[2]
output = input_tensor #output 변수에 input_tensor(토큰 id화한 데이터) 저장 = 토큰 임베딩 결과★
if use_token_type: #세그먼트 임베딩 사용한다면,
if token_type_ids is None:
raise ValueError("'token_type_ids' must be specified if"
"'use_token_type' is True.")
token_type_table = tf.get_variable(
name=token_type_embedding_name,
shape=[token_type_vocab_size, width],
initializer=create_initializer(initializer_range)) #[세그먼트 레이어의 단어 개수, 임베딩 차원] 모양의 tensor 만들어 token_type_table 변수에 저장
# This vocab will be small so we always do one-hot here, since it is always
# faster for a small vocabulary.
flat_token_type_ids = tf.reshape(token_type_ids, [-1])
one_hot_ids = tf.one_hot(flat_token_type_ids, depth=token_type_vocab_size) #여기에서는 매번 원-핫 인코딩 사용. 세그먼트 레이어 단어 개수를 차원으로 갖는 원-핫 인코딩 벡터 생성
token_type_embeddings = tf.matmul(one_hot_ids, token_type_table) #원-핫 인코딩 벡터들이 모인 행렬과 token_type_table 간 행렬곱
token_type_embeddings = tf.reshape(token_type_embeddings,
[batch_size, seq_length, width])
output += token_type_embeddings #output 변수에 위 결과값 더함 = 토큰 임베딩 레이어 결과값+세그먼트 임베딩 레이어 결과값★
if use_position_embeddings: #위치 임베딩 사용한다면,
assert_op = tf.assert_less_equal(seq_length, max_position_embeddings) #요소 별로 seq_length가 max_position_embedding값보다 작거나 같다고 가정
with tf.control_dependencies([assert_op]):
full_position_embeddings = tf.get_variable(
name=position_embedding_name,
shape=[max_position_embeddings, width],
initializer=create_initializer(initializer_range))
position_embeddings = tf.slice(full_position_embeddings, [0, 0],
[seq_length, -1]) #위치 임베딩 행렬에서 첫 행, 첫 열을 시작으로 문장 길이 만큼의 열벡터 추출
num_dims = len(output.shape.as_list()) #output 차원을 리스트화 했을 때 길이(차원)을 num_dims 변수에 저장
# Only the last two dimensions are relevant (`seq_length` and `width`), so
# we broadcast among the first dimensions, which is typically just
# the batch size.
position_broadcast_shape = []
for _ in range(num_dims - 2):
position_broadcast_shape.append(1)
position_broadcast_shape.extend([seq_length, width])
position_embeddings = tf.reshape(position_embeddings,
position_broadcast_shape) #위치 임베딩 행렬을 positio_broadcast_shape와 같은 형태로 변형
output += position_embeddings #위치 임베딩을 output에 더함 = 토큰 임베딩+세그먼트 임베딩+위치 임베딩 결과 반환★
#output 변수에 polarity, intensity 임베딩 벡터를 추가하면?
output = layer_norm_and_dropout(output, dropout_prob)
return output
*embedding_postprocessor 함수가 반환하는 결과값: 토큰 임베딩 벡터 + 세그먼트 임베딩 벡터 + 위치 임베딩 벡터
=> 위 결과값에 감성 극성 임베딩 벡터와 감성 강도 임베딩 벡터를 더하면 참고 논문에서 말하는 감성 자질 모델의 입력값 구현 가능
(5) 감성 자질 레이어 추가 전 일부 클래스 및 함수 실험
(i) Tokenizer
*사전학습된 KoELECTRA의 토크나이저를 불러옴
*4가지 문장을 예시로 실험
-"[CLS] 나는 정말 행복해 [SEP]", "[CLS] 그래서 기분이 좋아 [SEP]", "[CLS] 나는 너무 불행해 [SEP]", "[CLS] 그래서 기분이 나빠 [SEP]"
-convert_tokens_to_ids: 토큰들을 각 토큰들에 대응되는 정수 인덱스로 변환해 정수 벡터를 반환
-convert_ids_to_tokens: 정수 인덱스로 변환된 토큰들을 다시 자연어로 반환
*한국어 형태소 분석기
-KOSAC에서 사용한 형태소 분류 체계와 동일한 체계를 갖는 Kkma(꼬꼬마) 형태소 분석기를 사용하기로 결정
*실제 embedding_postprocessor 함수가 3차원 tensor 형태의 입력값을 받는다는 전제 하에, 위 4개의 예시 문장으로 3차원 tensor를 만든 후 이를 1차원으로 변환
*1차원으로 만들어진 입력값에 대해 convert_ids_to_tokens 메소드를 사용하여 각 토큰 ID를 실제 자연어 토큰으로 변환한예시
(ii) 감성 극성 및 강도 임베딩 벡터
*극성(polarity) 임베딩 제작
-극성 값: COMP, NEG, NEUT, None, POS
-Pos(positive)일 시 1, NEG(negative)일 시 -1, 그 외 라벨일 시 0을 반환하도록 구현
*강도(intensity) 임베딩 제작
-강도 값: High, Medium, Low, None
-High일 시 3, Medium일 시 2, Lower일 시 1, 그 외 라벨일 시 0을 반환하도록 구현
*이후 입력 tensor 모양과 똑같은 모양의 감성 값 임베딩 tensor로 변환
'연구 프로젝트 > 감성 자질 모델' 카테고리의 다른 글
[파이썬] KoELECTRA 기반의 감성 자질 모델 구현 도전기 #2-3-1 (2) | 2023.05.14 |
---|---|
[파이썬] KoELECTRA 사전 학습을 위한 데이터셋 제작 (0) | 2023.04.25 |