BERT 로는 노오력이 부족하다, RoBERTa 로 성능 개선 시도했는 데 결과물이...?

2023. 8. 3. 09:28광고차단 머신러닝

728x90

2023.08.01 - [산학협력프로젝트] - "너가 만든 거 유효하긴 해?", BERT, Random Forest 성능테스트 하기

 

"너가 만든 거 유효하긴 해?", BERT, Random Forest 성능테스트 하기

동전에 이어 이번에는 나무...? Random Forest Model 은 뭘까 2023.06.28 - [산학협력프로젝트] - 산학협력 프로젝트, 광고 차단 오토로 돌리기 (졸업 하고 싶어요ㅠ) 산학협력 프로젝트, 광고 차단 오토로

xpmxf4.tistory.com

저번 글을 읽고 오시면 좋습니다!


저번 글에서는 BERT, RF,

그리고 이 2가지 모델을 합친 가중평균 모델을 사용해

광고 사이트들인지 분류하는 것까지 해봤습니다

 

오늘은 BERT 모델을 바탕을 개선, 개량된 버전인

RoBERTa 모델에 대해 알아보고, 이를 토대로 성능 측정 해보겠습니다!

아오 BERT 시치~

RoBERTa는 기계학습 분야에서 사용되는 언어 모델인데요,

RoBERTa가 BERT라는 모델을 바탕으로 발전한 버전이라고 보시면 됩니다.

 

그렇다면 BERT는 무엇일까요? 잠깐 다시 알아보겠습니다!

귀 열어라

BERT는 사람이 문장을 이해하는 것처럼

기계가 문장을 이해하게 도와주는 모델인데요,

이를 가능하게 하는 기술이 '트랜스포머'입니다.

 

자, 여기서 잠깐 '트랜스포머'에 대해 설명하면,

그것은 문장의 각 단어가 서로 어떤 관계를 가지고 있는지 파악하도록 돕는 기술입니다.

 

이해하기 쉽게 예를 들어볼게요.

 

'나는 오늘 강아지를 산책시켰다'라는 문장이 있을 때,

BERT 모델은 '나는', '오늘', '강아지를', '산책시켰다'라는 단어들이

서로 어떤 관계를 가지고 있는지 파악합니다.

 

예를 들면, '나는'이라는 주어가 '산책시켰다'라는 동사의 행동을 하고,

그 행동의 대상이 '강아지'라는 것, 그리고 그 일이 '오늘' 발생했다는 것을 이해하게 됩니다.

이렇게 단어들 사이의 관계를 이해하면서 문장 전체의 의미를 파악하는 것이죠.

마치 사람이 문장을 읽고 이해하는 것처럼 말이죠.

 

그런데 BERT에는 문제가 있었습니다.

 

문장을 이해하려면 문장이 주어질 때마다 계속해서 훈련을 시켜야 했는데,

이 과정이 많은 시간과 컴퓨터 자원을 필요로 하게 되었습니다.

RoBERTa 란?

이런 문제를 해결하고자, Facebook의 연구자들이 RoBERTa를 개발하게 되었습니다.

RoBERTa는 BERT를 훨씬 빠르게 학습시키기 위한 여러 가지 개선 사항들을 도입했습니다.

 

RoBERTa는 문장을 이해하는 방식이 조금 특별합니다.

 

우리가 글을 읽을 때 모든 단어를 정확하게 봐야만 글의 의미를 이해할 수 있을까요?

가끔은 중요한 부분만 집중적으로 보고도 대략적인 내용을 파악할 수 있죠.

RoBERTa는 비슷한 방식으로 학습을 진행하는데, 이것을 '동적 마스킹'이라고 부릅니다.

 

예를 들어, '나는 오늘 학교에 가서 친구들과 공부했다'라는 문장이 있다고 할 때,

RoBERTa는 이 문장을 학습하면서 가끔 몇몇 단어를 '가립니다'.

즉, '나는 오늘 ___ 가서 친구들과 ____ 했다'처럼 일부 단어를 빈 칸으로 만드는 거죠.

그리고 이 빈 칸에 들어갈 단어가 무엇일지 추측하면서 학습을 진행합니다.

 

그런데 RoBERTa의 특징은 이 '가리는' 방식을 항상 똑같이 하지 않는다는 점입니다.

같은 문장을 다시 학습할 때는 다른 단어를 가리고 학습하죠.

이렇게 되면 모델이 더 다양한 문장 구조를 학습하게 되는 것이죠.

 

하나의 특징은 RoBERTa가 '덩치가 크다'는 것입니다.

즉, RoBERTa는 한 번에 많은 양의 데이터를 처리하고, 많은 양의 데이터로부터 배울 수 있습니다.

이는 마치 사람이 여러 권의 책을 동시에 읽고 그 내용을 종합하여 이해하는 것과 비슷하다고 볼 수 있습니다.

 

이런 방식 덕분에 RoBERTa 문장을 빠르고 효율적으로 이해하며,

결과로 좋은 성능을 내는 AI 시스템을 구축할 있게 됩니다.

이런 이유로 많은 사람들이 프로젝트에 RoBERTa 적용하려고 하는 것입니다.

자 그럼 RoBERTa 써보자~

1. 필요한 라이브러리와 데이터 로드

import pandas as pd
import torch
from torch.utils.data import Dataset, DataLoader
from transformers import RobertaTokenizer, RobertaForSequenceClassification

# GPU 사용 설정
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 데이터 읽기
df1 = pd.read_csv('keyword_url_label.csv')
df2 = pd.read_csv('HTML_NL.csv')

# 두 데이터프레임 병합
df = pd.concat([df1, df2['Natural_Language']], axis=1)

# RoBERTa 토크나이저
tokenizer = RobertaTokenizer.from_pretrained('roberta-base')

부분은 필요한 라이브러리를 불러오는 과정이며, 데이터를 로드하고 이를 합치는 작업을 수행합니다.

또한, RoBERTa 모델을 사용하기 위한 토크나이저를 불러옵니다.

2. 데이터셋 및 데이터 로더 설정

# 데이터셋 정의
class MyDataset(Dataset):
    def __init__(self, sentences, tokenizer):
        self.sentences = sentences
        self.tokenizer = tokenizer

    def __len__(self):
        return len(self.sentences)

    def __getitem__(self, idx):
        sentence = self.sentences[idx]
        encoding = self.tokenizer.encode_plus(
            sentence,
            add_special_tokens=True,
            truncation=True,
            padding='max_length',
            max_length=512,
            return_tensors='pt'
        )
        return {
            'input_ids': encoding['input_ids'].flatten(),
            'attention_mask': encoding['attention_mask'].flatten()
        }


# 데이터셋 생성
dataset = MyDataset(df['Natural_Language'].values, tokenizer)

# 데이터로더 설정
dataloader = DataLoader(dataset, batch_size=32)

부분에서는 PyTorch Dataset DataLoader 사용하여

데이터를 모델에 입력할 있는 형태로 만드는 과정을 수행합니다.

3. 모델 로드 및 추론

# RoBERTa 모델 로드
model = RobertaForSequenceClassification.from_pretrained('roberta-base', num_labels=2)
model.load_state_dict(torch.load('models/RoBERTa_ver2.pt'))
model = model.to(device)
model.eval()

# 추론 및 결과 기록
df['Infer_Label_RoBERTa'] = None
problematic_rows = []
for i, row in df.iterrows():
    try:
        inputs = tokenizer(row['Natural_Language'], return_tensors='pt', padding='longest', truncation=True)
        inputs = {key: inputs[key].to(device) for key in inputs}
        outputs = model(**inputs)
        _, predicted = torch.max(outputs.logits, 1)
        df.loc[i, 'Infer_Label_RoBERTa'] = predicted.item()
    except Exception as e:
        problematic_rows.append(i)

부분에서는 사전에 학습된 RoBERTa 모델을 불러온 ,

데이터 프레임의 행에 대해 추론을 수행하고 결과를 기록합니다.

4. 오차 비율 계산 및 결과 출력

# 문제가 있는 행 출력
print("Problematic Rows:")
for row_index in problematic_rows:
    print(row_index)

# 오차 비율 계산
total_rows = len(df)
mismatch_rows = df[(df['Label'] != df['Infer_Label_RoBERTa']) & (~df.index.isin(problematic_rows))]
mismatch_ratio = len(mismatch_rows) / total_rows

# 결과 출력
print(f"Total Rows: {total_rows}")
print(f"Mismatch Rows: {len(mismatch_rows)}")
print(f"Mismatch Ratio: {mismatch_ratio}")

마지막으로 문제가 발생한 행의 인덱스를 출력하고,

모델의 예측 결과와 실제 레이블이 일치하지 않는 행의 수와 비율을 계산하여 출력합니다.

이를 통해 모델의 성능을 평가할 있습니다.

BERT vs RoBERTa 성능 비교

????

RoBERTa 와 BERT 의 성능일 비교했는 데

소수점 저 아래까지 동일하다...

아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ

다음 글에서는 왜 그런지에 대한 분석과 함께

제대로 RoBERTa 측정 및 나머지 모델과

성능 비교를 해보는 글로 찾아뵙겠습니다!

 

728x90