2023. 9. 20. 10:11ㆍML&DL/NLP
🤗 Hugging Face
- Transformer과 같은 다양한 인공지능 모델을 사용할 수 있도록 라이브러리를 제공하는 모듈
- 대표적인 모델로 Transformer 기반인 BERT, GPT 모델 등이 있음
📌 목표
- 네이버 영화 리뷰를 감성(긍정/부정) 분류해보기!
💻 실습 코드
Hugging Face가 제공하는 transformers 라이브러리 설치
!pip install transformers
라이브러리 및 패키지 import
import pandas as pd
import numpy as np
import urllib.request
import os
from tqdm import tqdm
import tensorflow as tf
from transformers import BertTokenizer, TFBertModel
train & test 데이터 다운 / 확인
# train & test 데이터 설치
urllib.request.urlretrieve("https://raw.githubusercontent.com/e9t/nsmc/master/ratings_train.txt", filename="ratings_train.txt")
urllib.request.urlretrieve("https://raw.githubusercontent.com/e9t/nsmc/master/ratings_test.txt", filename="ratings_test.txt")
train_data = pd.read_table('ratings_train.txt')
test_data = pd.read_table('ratings_test.txt')
# 데이터 확인
print('훈련용 리뷰 개수 :',len(train_data)) # 훈련용 리뷰 개수 출력
print('테스트용 리뷰 개수 :',len(test_data)) # 테스트용 리뷰 개수 출력
# 데이터 확인
train_data[:5] # 상위 5개 출력
test_data[:5] # 상위 5개 출력
train & test 전처리
# 데이터 전처리 - 결측치 제거
train_data = train_data.dropna(how = 'any') # Null 값이 존재하는 행 제거
train_data = train_data.reset_index(drop=True)
print(train_data.isnull().values.any()) # Null 값이 존재하는지 확인
test_data = test_data.dropna(how = 'any') # Null 값이 존재하는 행 제거
test_data = test_data.reset_index(drop=True)
print(test_data.isnull().values.any()) # Null 값이 존재하는지 확인
train & test 토큰화
# BERT 모델의 토크나이저 가져오기
tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased')
#텍스트 인코딩
print(tokenizer.encode("보는내내 그대로 들어맞는 예측 카리스마 없는 악역"))
#텍스트 토큰화
print(tokenizer.tokenize("보는내내 그대로 들어맞는 예측 카리스마 없는 악역"))
# 인코딩된 문장을 원래 문장으로 디코딩
tokenizer.decode(tokenizer.encode("보는내내 그대로 들어맞는 예측 카리스마 없는 악역"))
Bert 모델에 알맞은 입력값으로 데이터 변환해주기
def convert_examples_to_features(examples, labels, max_seq_len, tokenizer):
input_ids, attention_masks, token_type_ids, data_labels = [], [], [], []
for example, label in tqdm(zip(examples, labels), total=len(examples)):
# input_id는 워드 임베딩을 위한 문장의 정수 인코딩
input_id = tokenizer.encode(example, max_length=max_seq_len, pad_to_max_length=True)
# attention_mask는 실제 단어가 위치하면 1, 패딩의 위치에는 0인 시퀀스.
padding_count = input_id.count(tokenizer.pad_token_id)
attention_mask = [1] * (max_seq_len - padding_count) + [0] * padding_count
# token_type_id는 세그먼트 임베딩을 위한 것으로 이번 예제는 문장이 1개이므로 전부 0으로 통일.
token_type_id = [0] * max_seq_len
assert len(input_id) == max_seq_len, "Error with input length {} vs {}".format(len(input_id), max_seq_len)
assert len(attention_mask) == max_seq_len, "Error with attention mask length {} vs {}".format(len(attention_mask), max_seq_len)
assert len(token_type_id) == max_seq_len, "Error with token type length {} vs {}".format(len(token_type_id), max_seq_len)
input_ids.append(input_id)
attention_masks.append(attention_mask)
token_type_ids.append(token_type_id)
data_labels.append(label)
input_ids = np.array(input_ids, dtype=int)
attention_masks = np.array(attention_masks, dtype=int)
token_type_ids = np.array(token_type_ids, dtype=int)
data_labels = np.asarray(data_labels, dtype=np.int32)
return (input_ids, attention_masks, token_type_ids), data_labels
형태에 맞게 변환된 데이터로 Train / Test 지정
train_X, train_y = convert_examples_to_features(train_data['document'], train_data['label'], max_seq_len=max_seq_len, tokenizer=tokenizer)
test_X, test_y = convert_examples_to_features(test_data['document'], test_data['label'], max_seq_len=max_seq_len, tokenizer=tokenizer)
데이터 확인
# 최대 길이: 128
input_id = train_X[0][0]
attention_mask = train_X[1][0]
token_type_id = train_X[2][0]
label = train_y[0]
print('단어에 대한 정수 인코딩 :',input_id)
print('어텐션 마스크 :',attention_mask)
print('세그먼트 인코딩 :',token_type_id)
print('각 인코딩의 길이 :', len(input_id))
print('정수 인코딩 복원 :',tokenizer.decode(input_id))
print('레이블 :',label)
pre-trained BERT 모델 불러오기
model = TFBertModel.from_pretrained("bert-base-multilingual-cased")
모델 학습 전에 input 값 정의해주기
max_seq_len = 128
input_ids_layer = tf.keras.layers.Input(shape=(max_seq_len,), dtype=tf.int32)
attention_masks_layer = tf.keras.layers.Input(shape=(max_seq_len,), dtype=tf.int32)
token_type_ids_layer = tf.keras.layers.Input(shape=(max_seq_len,), dtype=tf.int32)
outputs = model([input_ids_layer, attention_masks_layer, token_type_ids_layer])
모델 정의
class TFBertForSequenceClassification(tf.keras.Model):
def __init__(self, model_name):
super(TFBertForSequenceClassification, self).__init__()
self.bert = TFBertModel.from_pretrained(model_name, from_pt=True)
self.classifier = tf.keras.layers.Dense(1,
kernel_initializer=tf.keras.initializers.TruncatedNormal(0.02),
activation='sigmoid',
name='classifier')
def call(self, inputs):
input_ids, attention_mask, token_type_ids = inputs
outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
cls_token = outputs[1]
prediction = self.classifier(cls_token)
return prediction
with strategy.scope():
model = TFBertForSequenceClassification("bert-base-multilingual-cased")
optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5)
loss = tf.keras.losses.BinaryCrossentropy()
model.compile(optimizer=optimizer, loss=loss, metrics = ['accuracy'])
모델 학습 / 테스트 결과
model.fit(train_X, train_y, epochs=2, batch_size=64, validation_split=0.2)
results = model.evaluate(test_X, test_y, batch_size=1024)
print("test loss, test acc: ", results)
분류 결과 테스트 해보기
def sentiment_predict(new_sentence):
input_id = tokenizer.encode(new_sentence, max_length=max_seq_len, pad_to_max_length=True)
padding_count = input_id.count(tokenizer.pad_token_id)
attention_mask = [1] * (max_seq_len - padding_count) + [0] * padding_count
token_type_id = [0] * max_seq_len
input_ids = np.array([input_id])
attention_masks = np.array([attention_mask])
token_type_ids = np.array([token_type_id])
encoded_input = [input_ids, attention_masks, token_type_ids]
score = model.predict(encoded_input)[0][0]
print(score)
if(score > 0.5):
print("{:.2f}% 확률로 긍정 리뷰입니다.\n".format(score * 100))
else:
print("{:.2f}% 확률로 부정 리뷰입니다.\n".format((1 - score) * 100))
결과
부정 리뷰
sentiment_predict("보던거라 계속보고있는데 전개도 느리고 주인공인 은희는 한두컷 나오면서 소극적인모습에 ")
긍정 리뷰
sentiment_predict('와 개쩐다 정말 세계관 최강자들의 영화다')
출처 : https://github.com/ukairia777/tensorflow-nlp-tutorial
GitHub - ukairia777/tensorflow-nlp-tutorial: tensorflow를 사용하여 텍스트 전처리부터, Topic Models, BERT, GPT와
tensorflow를 사용하여 텍스트 전처리부터, Topic Models, BERT, GPT와 같은 최신 모델의 다운스트림 태스크들을 정리한 Deep Learning NLP 저장소입니다. - GitHub - ukairia777/tensorflow-nlp-tutorial: tensorflow를 사용하
github.com
'ML&DL > NLP' 카테고리의 다른 글
[NLP] 데이터 전처리 - 정제 / 정규화 (0) | 2023.09.27 |
---|---|
[NLP] 데이터 전처리 - 영어/ 한국어 토큰화 실습 (0) | 2023.09.21 |
[NLP] 데이터 전처리 - 한국어 토큰화 (0) | 2023.09.21 |
[NLP] Python 한글 맞춤법 검사 라이브러리 (0) | 2023.09.21 |
자연어 처리(NLP) (1) (0) | 2023.09.20 |