KalelPark's LAB

[CODE] NLP's Study for BERT tutorial 본문

Data Science/CODE

[CODE] NLP's Study for BERT tutorial

kalelpark 2023. 3. 13. 21:36

BERT가 무엇인지에 관련해서는, 하단의 링크를 참조하시면, 감사하겠습니다..!

 

[논문 리뷰] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

Abstract BERT(Bidirectional Encoder Representations Transformers)에 대해서 소개합니다. BERT는 모든 layer로부터 양방향 정보를 활용하여, 학습합니다. 이후, downstream시, 단지 하나의 layer를 추가하여도, pretraining

kalelpark.tistory.com

하단의 링크를 통해서, 데이터를 다운로드 하는 것이 가능합니다..!

!git clone https://github.com/e9t/nsmc.git

EffectivePython 책을 참고하자면, 라이브러리는 ABC 순으로 작성하는 것이 효율적이라고 합니다.

다만 OS 및 운영체제는 윗부분에 작성하는 것을 언급합니다.

 

하지만, torch 및 machinelearning 관련된 라이브러리는 묶어서 놓는 것이 시각적으로 보기에 편합니다.

import os

import numpy as np
import pandas as pd

import torch
from torch.utils.data import Dataset, DataLoader
from pytorch_transformers import BertTokenizer, BertForSequenceClassification, BertConfig
from torch.optim import Adam
import torch.nn.functional as F

import warnings
warnings.filterwarnings(action = "ignore")

데이터가 상당히 많아 학습하기에 상당히 느립니다. 그러므로, 빠른 테스트를 위해 조그만 활용하였습니다.

train_df = pd.read_csv("nsmc/ratings_train.txt", sep = "\t")
test_df = pd.read_csv("nsmc/ratings_test.txt", sep = "\t")
train_df.dropna(inplace = True)
test_df.dropna(inplace = True)

train_df = train_df.sample(frac = 0.3, random_state = 128)
test_df = test_df.sample(frac = 0.3, random_state = 128)

 

데이터셋 및 데이터 로더를 생성합니다.

class NsmcDataset(Dataset):
    def __init__(self, df):
        self.df = df
    
    def __len__(self):
        return len(self.df)
    
    def __getitem__(self, idx):
        text = self.df.iloc[idx, 1]
        label = self.df.iloc[idx, 2]
        return text, label

nsmc_train_dataset = NsmcDataset(train_df)
nsmc_test_dataset = NsmcDataset(test_df)

train_loader = DataLoader(nsmc_train_dataset, num_workers = 4, shuffle = True, batch_size = 16)
test_loader = DataLoader(nsmc_test_dataset, num_workers = 4, shuffle = False, batch_size = 16)

모델을 활용하기 위해, pytorch_transformer를 사용합니다. 하단의 라이브러리를 참고하시기 바랍니다.

또한, pretrained model들이 많아 상당히 유용하다고 볼 수 있습니다.

https://github.com/huggingface/transformers

 

GitHub - huggingface/transformers: 🤗 Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, and JAX.

🤗 Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, and JAX. - GitHub - huggingface/transformers: 🤗 Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, a...

github.com

추후 자세한 내용 및 라이브러리를 상세하게 다뤄보도록 하겠습니다. :)

학습하는 방법을 만들어보도록 하겠습니다..!

for epoch in range(epochs):
    total_loss, total_len, total_correct = 0, 0, 0
    model.train()
    for text, label in train_loader:
        optimizer.zero_grad()
        
        // 단어의 token을 맞추기 위해 적용하는 것입니다.
        encoded_list = []
        encoded_list = [tokenizer.encode(t, add_special_tokens = True) for t in text]
        padded_list = [e + [0] * (512 - len(e)) for e in encoded_list]
        
        sample = torch.tensor(padded_list)
        sample, label = sample.to(device), label.to(device)
        labels = torch.tensor(label)
        outputs = model(sample, labels=labels)
        loss, logits = outputs
        
        pred = torch.argmax(F.softmax(logits), dim = 1)
        correct = pred.eq(label)
        total_correct += correct.sum().item()
        total_len += len(label)
        total_loss += loss.item()
        loss.backward()
        optimizer.step()
    
    model.eval()
    eval_total_loss, eval_total_acc = 0, 0
    for text, label in test_loader:
        encoded_list = [tokenizer.encode(t, add_special_tokens = True) for t in text]
        padded_list = [e + [0] * (512 - len(e)) for e in encoded_list]
        sample = torch.tensor(padded_list)
        sample, label = sample.to(device), label.to(device)
        labels = torch.tensor(label)
        outputs = model(sample, labels = labels)
        loss, logits = outputs
        pred = torch.argmax(F.softmax(logits), dim = 1)
        correct = pred.eq(labels)
        eval_total_acc += correct.sum().item()
        total_len += len(labels)
        eval_total_loss += loss.item()
    
	print(f"Epochs [ {epoch + 1} / {epochs}] : Train_Accuracy : {total_correct / total_len}, Train_Loss {total_loss / total_len}, Test_Accuracy : {eval_total_acc / total_len}, Test_Loss {eval_total_loss / total_len}")
Comments