[NLP] KLUE-BERT 기반 멀티레이블 혐오 표현 분류 실습

2026. 1. 22. 15:51·개념 정리 step2/멀티모달(Multi-modal)

이번 실습에서는 문장이 하나 이상의 혐오 범주에 속할 수 있는 멀티레이블 분류(Multi-label Classification) 문제를 해결하기 위해 한국어 특화 모델인 KLUE-BERT를 활용했습니다.

데이터셋 개요

  • 풀네임: Korean Multi-label Hate Speech Dataset
  • 출처: GitHub - adlnlp/K-MHaS
  • 데이터 구성:
    • kmhas_train.txt: 학습 데이터
    • kmhas_valid.txt: 검증 데이터
    • kmhas_test.txt: 테스트 데이터
  • 형식: 탭(\t)으로 구분된 텍스트 파일 (Document + Label)

1. 멀티레이블 분류의 이해

일반적인 단일 분류(Multi-class)와 달리, 하나의 텍스트가 여러 개의 레이블을 가질 수 있는 구조입니다. 예를 들어, 한 문장이 '성차별'이면서 동시에 '혐오욕설'일 수 있습니다. 이를 처리하기 위해 출력층에서는 Sigmoid 함수를 사용하고, 각 레이블의 포함 여부를 독립적으로 판단합니다.

멀티레이블 구조의 특징

K-MHaS의 가장 큰 특징은 하나의 문장에 여러 레이블이 부여될 수 있다는 점입니다.

  • 예시: "저 나이 먹고 특정 종교 믿는 꼴이라니..."
  • 레이블 할당: 4 (연령차별), 7 (종교차별) → 모델 입력 시 [0, 0, 0, 0, 1, 0, 0, 1, 0] 형태로 처리됩니다.

2. 데이터 전처리: 레이블 이진화 (Binarization)

데이터셋 내의 레이블(예: '0, 4')을 모델이 학습할 수 있는 수치형 벡터로 변환하는 과정이 필요합니다.

레이블 파싱 및 Binarizing

# 문자열 형태의 레이블을 리스트로 변환
def parse_label(s):
    return [int(x) for x in str(s).split(",")]

# MultiLabelBinarizer를 이용한 0과 1의 벡터화
from sklearn.preprocessing import MultiLabelBinarizer
enc = MultiLabelBinarizer()
train_y = [parse_label(s) for s in train['label']]
train_labels = torch.tensor(enc.transform(train_y), dtype=torch.float32)

# 결과 예시: [1, 0, 0, 0, 1, 0, 0, 0, 0] (9개 클래스)

3. 토큰화 및 데이터셋 구축

BERT 모델의 입력 형식에 맞게 데이터를 변환합니다. 실습에서는 효율적인 학습을 위해 전용 함수를 구성했습니다.

데이터 텐서 변환 함수

def data_to_tensor(sentences, labels, tokenizer, max_len=128):
    # [CLS], [SEP] 토큰 추가 및 토큰화
    # Padding 및 Attention Mask 생성
    # ...
    return padded_inputs, tensor_labels, attention_masks

# DataLoader 설정 (Batch size 및 병렬 처리 최적화)
train_dataloader = DataLoader(
    train_dataset,
    batch_size=512,
    num_workers=8,
    pin_memory=True
)

4. 모델 설정 및 학습 최적화

KLUE-BERT-base 모델을 로드할 때 멀티레이블 설정을 명시적으로 지정합니다.

모델 로드 및 Mixed Precision 적용

A100 등 최신 GPU 환경에서 학습 속도를 높이기 위해 amp.autocast(Mixed Precision)를 사용했습니다.

model = BertForSequenceClassification.from_pretrained(
    'klue/bert-base', 
    num_labels=9,
    problem_type='multi_label_classification'
)

# 학습 루프 내 Mixed Precision 적용
from torch import amp
with amp.autocast(device_type="cuda", dtype=torch.bfloat16):
    outputs = model(b_input_ids, attention_mask=b_input_mask, labels=b_labels.float())
    loss = outputs.loss

5. 성능 평가 지표

멀티레이블 분류에서는 단순 정확도(Accuracy) 외에도 레이블별 성능을 종합하는 지표가 중요합니다.

  • F1-Score (Macro/Micro): 클래스 불균형이 있는 데이터셋에서 모델의 성능을 정밀하게 측정합니다.
  • Hamming Loss: 전체 레이블 중 모델이 틀린 레이블의 비율을 나타냅니다.
def multi_label_metrics(predictions, labels, threshold=0.5):
    probs = torch.sigmoid(torch.Tensor(predictions))
    y_pred = (probs >= threshold).numpy().astype(int)
    
    accuracy = accuracy_score(labels, y_pred)
    f1_macro = f1_score(labels, y_pred, average='macro', zero_division=0)
    # ... 기타 지표 계산
    return metrics

6. 실제 문장 추론 (Inference)

학습된 모델을 사용하여 새로운 문장에 대한 혐오 표현을 감지합니다.

def predict_hate_speech(text, threshold=0.5):
    model.eval()
    inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True).to(device)
    
    with torch.no_grad():
        outputs = model(**inputs)
    
    # Sigmoid를 통해 0~1 사이 확률값 도출
    probs = torch.sigmoid(outputs.logits).cpu().numpy()[0]
    # threshold 이상인 레이블만 추출
    results = [{'label': label_names[i], 'score': prob} for i, prob in enumerate(probs) if prob >= threshold]
    return results

테스트 결과 예시:

  • 입력: "잼민이들 왜 그렇게 민폐냐?"
  • 결과: {'label': '연령차별', 'score': 0.8245}

실습 요약

  1. 멀티레이블 처리: MultiLabelBinarizer와 BCEWithLogitsLoss의 조합이 핵심입니다.
  2. 성능 최적화: 대량의 데이터를 처리하기 위해 num_workers, pin_memory, BF16 연산을 활용하여 GPU 효율을 극대화했습니다.
  3. 한국어 특화: KLUE-BERT를 사용하여 한국어 구어체 및 신조어에 포함된 혐오 뉘앙스를 효과적으로 학습했습니다.

'개념 정리 step2 > 멀티모달(Multi-modal)' 카테고리의 다른 글

[Deep Learning] 동영상 데이터 분석: 3D CNN과 수화 인식 실습  (0) 2026.01.29
[Deep Learning] Vision Transformer(ViT) Multi-Branch 구현 실습  (0) 2026.01.23
[Deep Learning] 트랜스포머(Transformer): NLP 아키텍처 정리  (0) 2026.01.19
[딥러닝 NLP] NLU에서 트랜스포머 어텐션까지 핵심 개념 정리  (1) 2026.01.16
[RNN] 시퀀스 데이터와 순환 신경망(RNN) 학습 정리  (1) 2026.01.15
'개념 정리 step2/멀티모달(Multi-modal)' 카테고리의 다른 글
  • [Deep Learning] 동영상 데이터 분석: 3D CNN과 수화 인식 실습
  • [Deep Learning] Vision Transformer(ViT) Multi-Branch 구현 실습
  • [Deep Learning] 트랜스포머(Transformer): NLP 아키텍처 정리
  • [딥러닝 NLP] NLU에서 트랜스포머 어텐션까지 핵심 개념 정리
고니3000원
고니3000원
공부 내용 정리, 자기발전 블로그 입니다. 기존 네이버 블로그에서 티스토리로 이전했습니다. https://blog.naver.com/pak1010pak
  • 고니3000원
    곤이의 공부 블로그
    고니3000원
  • 전체
    오늘
    어제
    • 분류 전체보기 (178) N
      • 1. AI 논문 + 모델 분석 (20)
        • AI 논문 분석 (13)
        • AI 모델 분석 (7)
      • 2. 자료구조와 알고리즘 (16)
        • 2-1 자료구조와 알고리즘 (13)
        • 2-2 강화학습 알고리즘 (3)
      • 3. 자습 & 메모(실전, 실습, 프로젝트) (25)
        • 3-1 문제 해석 (4)
        • 3-2 메모(실전, 프로젝트) (14)
        • 3-3 배포 실전 공부 (7)
      • 4. [팀] 프로젝트 및 공모전 (14)
        • 4-1 팀 프로젝트(메모, 공부) (1)
        • 4-2 Meat-A-Eye (6)
        • 4-3 RL-Tycoon-Agent (3)
        • 4-4 구조물 안정성 물리 추론 AI 경진대회(D.. (4)
      • 5. [개인] 프로젝트 및 공모전 (0)
        • 4-1 귀멸의칼날디펜스(자바스크립트 활용) (5)
        • 4-2 바탕화면 AI 펫 프로그램 (4)
        • 4-3 개인 프로젝트(기타) (3)
      • 개념 정리 step1 (32)
        • Python 기초 (7)
        • DBMS (1)
        • HTML | CSS (3)
        • Git | GitHub (1)
        • JavaScript (5)
        • Node.js (5)
        • React (1)
        • 데이터 분석 (6)
        • Python Engineering (3)
      • 개념 정리 step2 (57) N
        • Machine | Deep Learning (15)
        • 멀티모달(Multi-modal) (23)
        • 강화 학습 (10)
        • AI Agent (9) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 네이버 곤이의 블로그(Naver->Tistory)
    • Github
  • 공지사항

  • 인기 글

  • 태그

    자료구조
    구현
    paddleocr
    pandas
    EfficientNet
    bottleneck
    javascript
    github
    html
    OCR학습
    귀칼
    프로젝트
    Attention Is All You Need
    transformer
    파인튜닝
    Vision
    학습
    ViT
    공모전
    강화학습
    알고리즘
    OCR
    데이터분석
    자바스크립트
    Grad-CAM
    강화 학습
    Python
    파이썬
    논문 리뷰
    Ai
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[NLP] KLUE-BERT 기반 멀티레이블 혐오 표현 분류 실습
상단으로

티스토리툴바