import numpy as np
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
try:
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
except RuntimeError as e:
print(e)
with open('/kaggle/input/2024-1-nlp-5/Korean_movie_reviews_2016.txt/Korean_movie_reviews_2016.txt', encoding='utf-8') as f:
docs = [doc.strip().split('\t') for doc in f]
docs = [(doc[0], int(doc[1])) for doc in docs if len(doc) == 2]
texts, labels = zip(*docs)
words_list = [doc.strip().split() for doc in texts]
print(words_list[:2])
print(len(texts))
Num GPUs Available: 1
[['부산', '행', '때문', '너무', '기대하고', '봤'], ['한국', '좀비', '영화', '어색하지', '않게', '만들어졌', '놀랍']]
165384
GPU 있는지 확인하고, 데이터 읽어옵니다.
from tensorflow.keras.utils import to_categorical
y_one_hot = to_categorical(labels)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(texts, y_one_hot, test_size=0.2, random_state=0)
y 이진 분류 문제니까 나눠주고, 테스트 트레인도 나눠줍니다.
from transformers import BertTokenizer, TFAlbertForSequenceClassification, AdamW,Trainer,TrainingArguments
tokenizer= BertTokenizer.from_pretrained("kykim/albert-kor-base") #허깅 페이스에 존재하는 토크나이저이다.
이번에 사용할 모델은 Albert이다.
X_train_tokenized = tokenizer(X_train, return_tensors="np", max_length=30, padding='max_length', truncation=True)
X_test_tokenized = tokenizer(X_test, return_tensors="np", max_length=30, padding='max_length', truncation=True) # 파라미터에 맞춰 토큰화
데이터 토큰화도 진행해주고
model = TFAlbertForSequenceClassification.from_pretrained("kykim/albert-kor-base", num_labels=2, from_pt=True)
model.summary()# 토크나이저랑 모델이름이 보통 같다. 프리트레이닝이 끝난 모델들이다.
모델도 불러옵니다.
모델 사이즈는 약 50MB정도
from keras.optimizers import Adam
from transformers import create_optimizer
epoch = 3
batch_size = 20
num_train_steps = len(X_train_tokenized['input_ids'])//batch_size * epoch # 총 학습 스텝 수 (에포크 * 배치 수)
optimizer, schedule = create_optimizer(init_lr=3e-5, num_warmup_steps=0, num_train_steps=num_train_steps)
model.compile(optimizer=optimizer, loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
train_dataset = tf.data.Dataset.from_tensor_slices((
{
'input_ids': X_train_tokenized['input_ids'],
'token_type_ids': X_train_tokenized['token_type_ids'],
'attention_mask': X_train_tokenized['attention_mask']
},
tf.cast(y_train, tf.float32)
)).batch(batch_size)
# 모델 훈련
model.fit(train_dataset, epochs=epoch)
#model.fit(X_train_tokenized,y_train, batch_size = batch_size, epochs=epoch)
학습을 진행합니다.
1 epoch당 대락 10분정도 걸리고 정확도도 확실하게 오르네요
y_preds = model.predict(dict(X_test_tokenized))
prediction_probs = tf.nn.softmax(y_preds.logits,axis=1).numpy()
y_predictions = np.argmax(prediction_probs, axis=1)
y_test = np.argmax(y_test, axis=1)
from sklearn.metrics import classification_report
print(classification_report(y_predictions, y_test))
평가로는 Precision, recall모두 괜찮게 나와 F1 score도 높게 나왔습니다.
이번엔 DistillBERT를 사용해보겠습니다.
from transformers import DistilBertTokenizer, TFDistilBertForSequenceClassification,BertTokenizer
tokenizer= BertTokenizer.from_pretrained("monologg/distilkobert") # 토크나이저랑 모델 맞춰주기
X_train_tokenized = tokenizer(X_train, return_tensors="np", max_length=30, padding='max_length', truncation=True)
X_test_tokenized = tokenizer(X_test, return_tensors="np", max_length=30, padding='max_length', truncation=True)
model_distillBERT = TFDistilBertForSequenceClassification.from_pretrained("monologg/distilkobert", num_labels=2, from_pt=True)
model_distillBERT.summary() # 버트의 한국어 버전이다. 알버트 보다는 파라미터가 두배 더 많다.
크기는 대략 2배정도 큽니다.
학습 속도는 왜 더 빠른지 모르겠네여 ㅎㅎ....
그렇지만 정확도도 무지하게 떨어집니다. 이유는....
모델의 크기와 학습 속도, 정확도는 여러 요인에 의해 결정됩니다. monologg/distilkobert가 kykim/albert-kor-base보다 크지만 학습 속도가 빠르고 정확도가 낮은 이유는 다음과 같습니다:
- 모델 아키텍처 차이:
- DistilKoBERT는 DistilBERT 아키텍처를 기반으로 하여 BERT의 층을 절반으로 줄이고, 일부 매개변수를 제거하여 크기를 줄이고 속도를 높였습니다. 하지만 이 과정에서 표현력도 줄어들어 정확도가 낮아질 수 있습니다.
- 모델 최적화:
- DistilKoBERT는 원래 빠른 추론과 학습 속도를 목표로 설계되었습니다. 따라서 BERT보다 경량화되어 있어 빠르게 학습할 수 있지만, 정확도는 약간 희생됩니다.
- 훈련 데이터와 파인튜닝:
- 두 모델이 학습된 데이터의 차이도 성능에 영향을 미칠 수 있습니다. ALBERT는 BERT의 성능을 유지하면서도 파라미터 효율성을 높이기 위해 설계되었습니다. 이는 학습 시간이 길어질 수 있지만, 일반적으로 더 나은 정확도를 제공합니다.
따라서, 모델의 크기 외에도 아키텍처와 최적화 방법, 훈련 데이터가 모델의 학습 속도와 정확도에 중요한 영향을 미칩니다.
GPT 바보....
평가도 처참해진 것을 볼 수 있습니다.
동일한 학습 시간으로 해도 증가치가 높지 않아서 굳이 할 이유가 없을 것 같습니다...
마지막으로 기본 BERT
from transformers import TFBertForSequenceClassification,BertTokenizer
tokenizer= BertTokenizer.from_pretrained("kykim/bert-kor-base")
X_train_tokenized = tokenizer(X_train, return_tensors="np", max_length=30, padding='max_length', truncation=True)
X_test_tokenized = tokenizer(X_test, return_tensors="np", max_length=30, padding='max_length', truncation=True)
model_BERT = TFBertForSequenceClassification.from_pretrained("kykim/bert-kor-base", num_labels=2, from_pt=True)
model_BERT.summary()
사이즈가 제일 큽니다 ....
ALBERT의 10배입니다 ㄷㄷ...
그렇지만 학습 속도는 1.1배 정도밖에 차이가 나지 않습니다.
f1 score도 큰 차이가 없는 것을 봐선 굳이 쓸 이유가 없을 것 같네요
모델 | 사이즈 | 학습 속도 | F1 score |
BERT | 451.27MB | 740 s/epoch | 0.93 |
ALBERT | 50.31MB | 650 s/epoch | 0.92 |
DistillBERT | 108.32MB | 210 s/epoch | 0.77 |
'인공지능 > 자연어 처리' 카테고리의 다른 글
Gen AI LM - GPT (1) | 2024.07.20 |
---|---|
Generative AI - LM Baseline (1) | 2024.07.20 |
자연어 처리 기말고사 대비 문제 만들기 (2) | 2024.06.12 |
자연어 처리 기말고사 정리 (0) | 2024.06.11 |
자연어 처리 17강 - Parameter efficient Tuning (1) | 2024.06.05 |