이번주에는 28일 수요일에 정보처리기사 2회차 필기 시험이 있어 공결로 강의에 불참하였다.
기출문제 풀이 시 3과목이 점수가 나오질 않아 합격에 간당간당하여 너무 걱정되었다.
이번주는 트랜스포머 기반 모델 실습이 주로 이뤄졌다. 기존과 달리 대규모 텍스트까지 처리가 가능한 모델이기 때문에 중요한 실습이라고 생각한다.
강의 내용 및 요약 정리
1. 트랜스포머(Transformer) 기반 기계번역 실습
A. 트랜스포머란?
- 자연어 문장 내 모든 단어쌍의 관계를 한 번에 파악하는 딥러닝 모델입니다.
- 기존 RNN/LSTM과 달리 병렬처리가 가능하고, 긴 문장도 효과적으로 처리합니다.
- 번역, 요약, 질의응답 등 다양한 NLP 작업의 표준 구조입니다.
B. 실습 흐름
1) 데이터 준비 및 전처리
# 영어-스페인어 병렬 문장 데이터 다운로드
path_to_file = tf.keras.utils.get_file('spa-eng.zip', origin='http://storage.googleapis.com/download.tensorflow.org/data/spa-eng.zip')
# 파일 읽기 및 정제 함수
def preprocess_sentence(w):
w = w.lower().strip()
w = re.sub(r"([?.!,¿])", r" \1 ", w)
w = re.sub(r'[" "]+', " ", w)
w = re.sub(r"[^a-zA-Z?.!,¿]+", " ", w)
return ' ' + w.strip() + ' '
- 설명: 문장을 소문자로 변환, 불필요한 기호/공백 제거, 시작/종료 토큰 추가
2) 토큰화 및 패딩
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
tokenizer = Tokenizer(filters='', oov_token='<unk>')
tokenizer.fit_on_texts(sentences)
sequences = tokenizer.texts_to_sequences(sentences)
padded_sequences = pad_sequences(sequences, padding='post')
- 설명: 각 단어를 숫자(토큰)로 변환, 길이 맞춤(패딩)
3) 포지셔널 인코딩
def positional_encoding(position, d_model):
angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis, :], d_model)
pos_encoding = np.zeros(angle_rads.shape)
pos_encoding[:, 0::2] = np.sin(angle_rads[:, 0::2])
pos_encoding[:, 1::2] = np.cos(angle_rads[:, 1::2])
return tf.cast(pos_encoding, dtype=tf.float32)
- 설명: 단어 순서 정보를 벡터에 더해줌
4) 멀티헤드 어텐션 레이어
class MultiHeadSelfAttentionBlock(tf.keras.layers.Layer):
def __init__(self, d_model, num_heads):
super().__init__()
self.mha = tf.keras.layers.MultiHeadAttention(num_heads=num_heads, key_dim=d_model//num_heads)
self.norm = tf.keras.layers.LayerNormalization(epsilon=1e-6)
def call(self, x, mask=None):
attn_output = self.mha(x, x, x, attention_mask=mask)
return self.norm(x + attn_output)
- 설명: 여러 '관점'에서 문장 내 단어 관계를 파악
5) 인코더-디코더 구조
class Encoder(tf.keras.layers.Layer):
def __init__(self, num_layers, d_model, num_heads, dff):
self.enc_layers = [EncoderLayer(d_model, num_heads, dff) for _ in range(num_layers)]
def call(self, x, mask):
for layer in self.enc_layers:
x = layer(x, mask)
return x
- 설명: 인코더는 입력 문장을 벡터로 요약, 디코더는 이를 바탕으로 번역문 생성
6) 학습 루프
for epoch in range(EPOCHS):
for (batch, (inp, tar)) in enumerate(dataset):
dec_input = tar[:, :-1]
with tf.GradientTape() as tape:
predictions = transformer([inp, dec_input])
loss = loss_function(tar[:, 1:], predictions)
gradients = tape.gradient(loss, transformer.trainable_variables)
optimizer.apply_gradients(zip(gradients, transformer.trainable_variables))
- 설명: 입력-출력 쌍을 반복 학습, 손실 최소화
2. BERT 파인튜닝 실습
A. BERT란?
- 대규모 텍스트로 사전학습된 트랜스포머 기반 모델
- 다양한 언어 작업(감성분류, 질의응답 등)에 소량 데이터만 추가 학습(파인튜닝)하면 높은 성능
B. 실습 흐름
1) 데이터 준비 및 분할
texts = [
"이 영화 정말 재미있어요! 강력 추천합니다.",
"배우들 연기가 너무 좋았고 스토리도 탄탄해요.",
# ... (생략)
]
labels = [1, 1, 0, 0, ...]
train_texts, test_texts, train_labels, test_labels = train_test_split(texts, labels, test_size=0.2)
- 설명: 텍스트와 라벨(긍정/부정) 데이터 준비, 학습/평가용 분리
2) BERT 토크나이저 및 모델 불러오기
from transformers import BertTokenizerFast, BertForSequenceClassification
tokenizer = BertTokenizerFast.from_pretrained('bert-base-multilingual-cased')
model = BertForSequenceClassification.from_pretrained('bert-base-multilingual-cased', num_labels=2)
model.to(device)
- 설명: 사전학습된 BERT 모델과 토크나이저 불러오기
3) 데이터 전처리 (토큰화, 패딩)
train_encodings = tokenizer(train_texts, truncation=True, padding=True, max_length=128, return_tensors='pt')
test_encodings = tokenizer(test_texts, truncation=True, padding=True, max_length=128, return_tensors='pt')
- 설명: 텍스트를 BERT 입력(숫자 시퀀스, 마스크)으로 변환
4) PyTorch Dataset/DataLoader 구성
class SentimentDataset(Dataset):
def __init__(self, encodings, labels):
self.encodings = encodings
self.labels = labels
def __getitem__(self, idx):
item = {key: val[idx] for key, val in self.encodings.items()}
item['labels'] = self.labels[idx]
return item
def __len__(self):
return len(self.labels)
train_dataset = SentimentDataset(train_encodings, torch.tensor(train_labels))
train_loader = DataLoader(train_dataset, batch_size=4, shuffle=True)
- 설명: 미니배치 단위로 데이터 공급
5) 파인튜닝(학습) 루프
optimizer = AdamW(model.parameters(), lr=5e-5)
for epoch in range(3):
model.train()
for batch in train_loader:
optimizer.zero_grad()
input_ids = batch['input_ids'].to(device)
attention_mask = batch['attention_mask'].to(device)
labels = batch['labels'].to(device)
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
loss = outputs.loss
loss.backward()
optimizer.step()
- 설명: 사전학습된 BERT를 내 데이터에 맞게 추가 학습
6) 평가 및 예측
def predict_sentiment(text, model, tokenizer, device, max_length=128):
model.eval()
encoding = tokenizer([text], truncation=True, padding=True, max_length=max_length, return_tensors='pt')
input_ids = encoding['input_ids'].to(device)
attention_mask = encoding['attention_mask'].to(device)
with torch.no_grad():
outputs = model(input_ids, attention_mask=attention_mask)
prediction_idx = torch.argmax(outputs.logits, dim=-1).cpu().item()
return "긍정" if prediction_idx == 1 else "부정"
- 설명: 학습된 모델로 새 문장의 감성(긍정/부정) 예측
정리
- 트랜스포머 실습:
1. 데이터 전처리 → 토큰화/패딩 → 포지셔널 인코딩/어텐션 → 인코더-디코더 조립 → 학습 루프
2. 기계번역 등 다양한 NLP 작업에 적용
- BERT 파인튜닝 실습:
1. 사전학습된 BERT 모델과 토크나이저 불러오기 → 내 데이터로 파인튜닝 → 감성분류 등 실전 적용
2. 소규모 데이터로도 높은 성능
오늘이 이 과정을 시작한지 정확히 4개월이 끝나는 날이다. 프로젝트 마무리까지 2개월이 채 안남은 시점이기도 하다.
이번달은 특히 더 정신없이 보낸거 같다는 생각이 든다.
공모전 프로젝트는 본격적으로 시작했지, 자격증은 간당간당하지, 한컴 프로젝트도 당장 다음주부터 시작하지, 채용 준비도 병행하지..
여러가지를 병행하고 있다보니 심리적으로 나도 모르게 지쳐가고 있지 않은가 싶기도 했다.
체력적으로도 다시 회복이 더뎌가고 있는건지 일주일째 헬스도 못가고 있다. (도저히 새벽에 일어날 수가 없었..ㅠ)
다음주엔 수액 한번 맞고 헬스도 하며 다시 달려갈 생각이다.
본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.
'HANCOM' 카테고리의 다른 글
| [스나이퍼팩토리] 한컴AI아카데미 86~95일차 : 25.06.09(월)~20(금) (0) | 2025.06.21 |
|---|---|
| [스나이퍼팩토리] 한컴AI아카데미 82~85일차 : 25.06.02(월)~05(목) (2) | 2025.06.06 |
| [스나이퍼팩토리] 한컴AI아카데미 72~76일차 : 25.05.19(월)~23(금) (2) | 2025.05.23 |
| [스나이퍼팩토리] 한컴AI아카데미 67~71일차 : 25.05.12(월)~16(금) (3) | 2025.05.16 |
| [스나이퍼팩토리] 한컴AI아카데미 65~66일차 : 25.05.07(수)~09(금) (2) | 2025.05.09 |