???:"휴먼, 당신의 말은 이해할 수 없습니다.(진짜모름)", 자연어처리를 위한 BERT 선택의 이유와 근거

2023. 8. 7. 20:23광고차단 머신러닝

728x90

뭐라는거죠 휴먼?

1. 상황

2023.07.24 - [산학협력프로젝트] - ??? : "하... 뭐 고르지?", 기술 선택의 이유와 근거 (1)

 

??? : "하... 뭐 고르지?", 기술 선택의 이유와 근거 (1)

뭐 먹을까요? 깔깔깔 산학협력 프로젝트, 광고 차단 오토로 돌리기 (졸업 하고 싶어요ㅠ) 1. 오늘의 주제 이번에 진행한 프로젝트는 산학협력 프로젝트입니다! 주제는 '기계 학습을 통한 광고 사

xpmxf4.tistory.com

저번 글에서 말했든 저는 <body> 태그 안 자연어들을 통해 

NLP 이를 학습시켜 추후 광고 사이트를 알아서 걸러내는

모델을 만드려고 합니다.

 

즉 현재 제가 원하는 바를 문장으로 정리한다면 다음과 같습니다.

 

HTML 문서 태그 안 자연어들을 보고 광고 사이트인지 판단하는 모델

 

이 문장은 (머신러닝 초보인 제가 봤을 때) 충분히 개발적(?)인 문장이다만

아직 좀 더 구체적으로 바꿔야하는 문장입니다.

더블로 바꿔!

위 문장을 좀 더 개발적으로 만들기 위한 작업을 진행해 보도록 하겠습니다

2. 자연어처리 모델(NLP) 가 하는 게 정확히 뭐지?

자연어처리를 한다고는 했지만, NLP 가 주로 해결하는 문제나

어느 상황에 사용이 되는 지 알아봐야 하겠죠?

자연어(natural language)란 우리가 일상생활에서 사용하는 언어를 말합니다.
자연어 처리(natural language processing)란 이러한 자연어의 의미를 분석하여
컴퓨터가 처리할 수 있도록 하는 일을 말합니다.

자연어 처리는 음성 인식, 내용 요약, 번역, 사용자의 감성 분석,
텍스트 분류 작업(스팸 메일 분류, 뉴스 기사 카테고리 분류), 질의응답 시스템, 챗봇과 같은 곳에서 사용되는 분야입니다.

[출처] : https://wikidocs.net/21667

자연어, 즉 사람의 말을 이해한다면 다양한 작업을 할 수 있음을

위 인용구에서 확인할 수 있고, 우리는 텍스트 분류 작업이 

우리가 원하는 작업임을 알 수 있습니다.

 

우리는 사이트를 방문할 때, 해당 사이트가 

광고 사이트인지 아닌지를 분류하려고 하니깐요!

 

즉, 아까의 문장을 개발적으로 푼다면

다음과 같이 바꿀 수 있을겁니다.

 

텍스트 분류 작업을 하는 모델 만들기

 

즉 우리의 앞으로의 작업은 텍스트 분류라는 작업임을 알 수 있습니다.

물론 단어만 보고 의미가 유추가 되는 작업이다만

좀 더 구체적으로 알아볼까요?

3. 텍스트 분류란? 

[정의]
주어진 텍스트(일반적으로 문장 또는 문서)를 하나 이상의 카테고리로 분류하는 작업입니다.

[대상]
전체 텍스트 문서나 문장

[목적]
주어진 전체 텍스트를 미리 정의된 카레고리 중 하나 또는 여러 개로 분류

[예시]
감정 분석 (Sentiment Analysis): 주어진 리뷰나 의견 텍스트가 긍정적인지 부정적인지 판별합니다.
예를 들어, "이 제품은 정말 좋아요!"라는 문장은 '긍정'으로 분류될 수 있습니다.

뉴스 카테고리 분류: 뉴스 기사를 스포츠, 정치, 경제 등의 카테고리로 분류합니다.

스팸 메일 분류: 이메일이 스팸인지 아닌지를 판별합니다.

[출처]
https://developers.google.com/machine-learning/guides/text-classification?hl=ko
https://wikidocs.net/21667

우리는 전체 텍스트(HTML 문서 안 자연어들)를 보고

특정 사이트의 카테고리(광고/비광고)를 고르는 작업

수행해야 함을 알 수 있습니다.

4. 텍스트 분류 모델 선택하기

이제 분류를 수행할 모델을 선택해야 합니다.

물론 처음부터 일일이 다 training 시켜 모델을 

만들 수도 있습니다.

 

하지만 이를 위해선 굉장히 방대한 데이터의 양과

이를 무리 없이 처리하기 위한 고성능의 컴퓨터가 필요하죠.

 

저에게는 이 2 가지가 다 없기 때문에

다른 사람이 미리 학습(pre-traing)시킨 모델을 사용해야 합니다.

이를 위해 고려한 모델이 바로 BERT입니다.

 

수많은 모델들 중 BERT를 선택하게 된 이유는 다음과 같습니다.

1. 데이터의 크기

"For the pre-training corpus we use the BooksCorpus (800M words)
(Zhu et al., 2015) and English Wikipedia (2,500M words)."

[출처] : https://arxiv.org/pdf/1810.04805.pdf

BERT는 BooksCorpus와 English Wikipedia와 같은 대규모의
텍스트 데이터를 사용하여 사전 학습되었기 때문에
언어의 다양한 패턴과 구조를 압니다!

2. 작업의 복잡성

[출처] : https://arxiv.org/pdf/1810.04805.pdf의 4. Experiments

BERT는 다양한 NLP 테스크에서 높은 성능을 보였습니다.

즉, 모델이 다양한 작업의 복잡성을 처리할 수 있음을 알 수 있습니다!

3. 학습 시간과 리소스

Training of BERTLARGE was performed on 16 Cloud TPUs (64 TPU chips total).
Each pretraining took 4 days to complete.

[출처] : https://arxiv.org/pdf/1810.04805.pdf

BERT의 training 과정에는 대용량 학습 데이터가 필요하지만

구글이 이미 4일에 걸쳐 (4일 밖에...?) 학습을 해놨기 때문에

충분한 학습이 되어 있는 상태입니다.

4. 전이 학습

Fine-tuning is straightforward since the self-attention mechanism
in the Transformer allows BERT to model many downstream tasks

BERT는 pre-training, fine-tuning 두 단계로 학습됩니다.

pre-train 된 BERT 모델을 사용자가 자신의 상황에 맞게 fine-tuning 만 한다면

빠르게 적응해 높은 성능을 낼 수 있습니다!

 

5. 성능

BERTBASE and BERTLARGE outperform all systems on all tasks by a substantial margin

[출처] : https://arxiv.org/pdf/1810.04805.pdf

BERT 는 타 NLP 모델 대비 (2019년 기준)

벤치마크에서 최고의 성능을 보여줬습니다.

6. 다양성

To make BERT handle a variety of down-stream tasks,
our input representation is able to unambiguously represent
both a single sentence and a pair of sentences

[출처] : https://arxiv.org/pdf/1810.04805.pdf

BERT의 기분 구조를 기반으로 다양한 파생 모델들이 개발되었습니다.

따라서, BERT로 먼저 시도를 해본 뒤에 성능 개선을 위하여

추후 BERT based 모델들을 시도하기 편합니다.


이러한 이유들로 BERT를 선택하게 되었습니다.

또한 NLP 모델 중 워낙 대표적인 기초 모델이기도 해서

선택을 했습니다.

 

이제는 실제로 BERT 를 사용해 보도록 하겠습니다!

5. BERT 사용 코드

1. 라이브러리 및 환경설정

각종 라이브러리를 import 후, GPU 사용 설정을 해줍니다!

import pandas as pd
import torch
from torch.utils.data import Dataset, DataLoader
from transformers import BertTokenizer, BertForSequenceClassification, AdamW

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

2. 데이터 로딩 및 전처리

현재 저의 CSV 파일은 2 개의 파일로 분리되어 있습니다.

  1. Keyword, URL, Label
  2. HTML문서(코드, 문자열), 자연어

두 개의 파일의 같은 행은 같은 정보를 의미합니다.

 

두 개의 파일을 읽어와 병합하고, 혹 결측값이 있을 경우 제거합니다.

또한 레이블 2(광고의심)의 경우 1로 대체하고 계산을 진행했습니다.

df1 = pd.read_csv('result_csvs/keyword_url_label.csv')
df2 = pd.read_csv('result_csvs/HTML_NL.csv')

df = pd.concat([df1['Label'], df2['Natural_Language']], axis=1)
df = df.dropna()

sentences = df['Natural_Language'].values
df['Label'] = df['Label'].replace(2, 1)
labels = df['Label'].values

3. BERT 토크나이저 설정

 

??? : 토크나이저...? 토큰...? 동전...?, 기술 선택의 이유와 근거 (2)

2023.07.24 - [산학협력프로젝트] - ??? : "하... 뭐 고르지?", 기술 선택의 이유와 근거 (1) ??? : "하... 뭐 고르지?", 기술 선택의 이유와 근거 (1) 뭐 먹을까요? 깔깔깔 산학협력 프로젝트, 광고 차단 오

xpmxf4.tistory.com

토크나이저에 대한 기초 설명은 위 글을 추천드립니다 :)


간단하게 토크나이저는 텍스트를 기계가 이해할 수 있도록 변환하는 도구입니다.

그리고 우리는 Google 이 BERT를 pre-train 했을 때의 토크나이저를

그대로 가져와 사용할 겁니다!

tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased')

4. 데이터셋 정의

데이터셋은 PyTorch의 Dataset클래스를 상속받아

사용자 정의 데이터셋을 만들었습니다!

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

    def __len__(self):
        # ...

    def __getitem__(self, idx):
        # ...

이렇게 정의된 데이터셋은 저의 텍스트 데이터와

레이블을 BERT 모델에 맞게 변환하는 작업을 수행하게 됩니다!

5. DataLoader 설정

DataLoader 데이터를 배치 단위(한 번에 처리되는 데이터의 단위)로 가져와 

모델에 공급하는 역할을 하게 됩니다!

dataset = MyDataset(sentences, labels, tokenizer)
dataloader = DataLoader(dataset, batch_size=32)

6. BERT 모델 및 옵티마이저 설정

이제 실제로 BERT 모델을 불러오는 단계입니다!

 

이때 GPU에 모델을 올려 더 빠르게 계산을 수행하도록 설정하고

이때 AdamW는 옵티마이저로서 학습 과정에서 모델의 가중치를 업데이트해

손실을 줄이는(모델을 더 정확하게 만드는) 역할을 수행합니다!

model = BertForSequenceClassification.from_pretrained('bert-base-multilingual-cased', num_labels=2)
model = model.to(device)

optimizer = AdamW(model.parameters(), lr=1e-5)

7. 학습

데이터를 모델에 전달하고, 모델의 예측과 실제 레이블을 비교해

오차를 계산하고, 이 오차를 줄이기 위해 가중치를 조정하는 작업을

epoch라는 변수를 통해 몇 번 진행할지 정하게 됩니다.

# 학습
model.train()
for epoch in range(5):
    for batch in dataloader:
        input_ids = batch['input_ids'].to(device)
        attention_mask = batch['attention_mask'].to(device)
        labels = batch['label'].to(device)

        outputs = model(input_ids=input_ids, attention_mask=attention_mask, labels=labels)
        loss = outputs.loss
        loss.backward()

        optimizer.step()
        optimizer.zero_grad()

    print(f'Epoch {epoch + 1}, Loss {loss.item()}')

 

6. 모델 성능 테스트

오차율 약 5.679%

제가 진행한 BERT 모델의 오차율은 약 5.769% 정도가 나왔네요!

즉, 정확도는 94.231% 정도가 나왔습니다!

 

제 예상보다는 되게 잘 나와서 다행입니다!

.

.

.

 

라고 생각했지만, 이는 제 큰 오산이었습니다...

이 수치는 잘못된 수치였습니다....

어아러ㅏㅓㅇㄹ미ㅏ너;ㄹ

왜 잘못되었는지는

2023.08.03 - [산학협력프로젝트] - 어디서부터 이게 잘못된 걸까..., 기계 학습 시 데이터셋 양의 중요성

 

어디서부터 이게 잘못된 걸까..., 기계 학습 시 데이터셋 양의 중요성

2023.08.03 - [산학협력프로젝트] - BERT 로는 노오력이 부족하다, RoBERTa 로 성능 개선 BERT 로는 노오력이 부족하다, RoBERTa 로 성능 개선 2023.08.01 - [산학협력프로젝트] - "너가 만든 거 유효하긴 해?", BER

xpmxf4.tistory.com

위 글에서 나옵니다!


긴 글 읽어주셔서 감사합니다 😀

728x90