에 가 미치는 영향
참고
,
sigmoid 함수의 경우, 미분하면 f(x)(1-f(x))로 계산할 수 있다.
!pip install datasets # Package install
from datasets import load_dataset # Huggingface 데이터셋 패키지 import
data = load_dataset("sepidmnorozy/Korean_sentiment") # 데이터 다운로드
# connect google drive
from google.colab import drive
drive.mount('/content/drive')
# Download konlpy
%cd ./drive/MyDrive/Colab\ Notebooks/
! git clone https://github.com/SOMJANG/Mecab-ko-for-Google-Colab.git
%cd ./Mecab-ko-for-Google-Colab
!bash install_mecab-ko_on_colab_light_220429.sh
train_data = data['train']
dev_data = data['validation']
test_data = data['test']
# mecab 형태소 분석기 사용
from konlpy.tag import Mecab # KoNLPy를 통해 Mecab 패키지 import
mecab = Mecab()
# 형태소 단위로 Tokenization 된 텍스트를 {train/dev/test}_data에 저장
train_data = train_data.map(lambda example: {'label': example['label'], 'text': ' '.join(mecab.morphs(example['text']))})
dev_data = dev_data.map(lambda example: {'label': example['label'], 'text': ' '.join(mecab.morphs(example['text']))})
test_data = test_data.map(lambda example: {'label': example['label'], 'text': ' '.join(mecab.morphs(example['text']))})
from sklearn.feature_extraction.text import CountVectorizer # CountVectorizer: Bag of words 벡터화 구현을 하기 위한 클래스
vectorizer = CountVectorizer(strip_accents='unicode', token_pattern=r"(?u)\b\w\w+\b|'\w+") # 데이터를 벡터화 해주는 모델
vectorizer.fit(train_data['text']) # 텍스트 문서 모음을 토큰 수의 행렬로 변환
print(vectorizer.vocabulary_) # 텍스트 문서에 나타난 어휘의 집합을 출력
print(len(vectorizer.vocabulary_)) # 텍스트 문서에 나타난 어휘 집합의 길이를 출력
train_vectors = vectorizer.transform(train_data['text']) # 학습 데이터를 숫자로 변환
dev_vectors = vectorizer.transform(dev_data['text']) # 검증 데이터를 숫자로 변환
test_vectors = vectorizer.transform(test_data['text']) # 테스트 데이터를 숫자로 변환
import torch
import torch.nn as nn
import torch.optim as optim
# MLP 모델 정의
class MLP(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(MLP, self).__init__()
#Todo --> layer 정의, 모델 정의
self.layer1 = nn.Linear(input_size, hidden_size)
self.layer2 = nn.Linear(hidden_size, int(0.5*hidden_size))
self.layer3 = nn.Linear(int(0.5*hidden_size), output_size)
self.gelu = nn.GELU()
self.softmax = nn.Softmax(dim=1)
def forward(self, x):
#Todo --> 모델을 실행
out1 = self.layer1(x)
out2 = self.gelu(out1)
out3 = self.layer2(out2)
out4 = self.gelu(out3)
out5 = self.layer3(out4)
out6 = self.softmax(out5)
return out6
# 하이퍼파라미터 셋팅
input_size = len(vectorizer.vocabulary_) # input size
hidden_size = 100 # hidden size
output_size = 2 # output size is 2 (positive/negative)
learning_rate = 0.00001
batch_size = 128
num_epochs = 10
# 모델 정의 (초기화)
model = MLP(input_size, hidden_size, output_size)
device = torch.device("cuda") # use GPU
model = model.to(device)
# optimizer, loss function 정의
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
loss_function = nn.CrossEntropyLoss()
# dev_vectors와 dev_data['label']을 텐서 자료형으로 변환 --> 딥러닝 코드 학습하고, 계산하기 위해서
dev_tensors = torch.cuda.FloatTensor(dev_vectors.toarray(), device=device)
dev_labels = torch.tensor(dev_data['label'], dtype=torch.long, device=device)
# 학습 시작 (총 num_epochs 만큼)
for epoch in range(num_epochs):
# model을 학습하겠다
model.train()
# 출력용
epoch_loss = 0
best_accuracy = 0
# train_vectors를 텐서 자료형으로 변환
train_tensors = torch.cuda.FloatTensor(train_vectors.toarray(), device=device)
# batch size 단위로 학습 진행 --> batch size에 대해서 한번 파라미터 업데이트
for i in range(0, len(train_tensors), batch_size):
# batch 단위 데이터 생성
batch_data = train_tensors[i:i+batch_size]
batch_labels = torch.tensor(train_data['label'][i:i+batch_size], device=device)
# 1. 순전파
outputs = model(batch_data)
# 2. 오차 계산
loss = loss_function(outputs, batch_labels)
# 3. 역전파
optimizer.zero_grad()
loss.backward()
# 4. 가중치 업데이트
optimizer.step()
# loss 저장 for 출력
epoch_loss += loss.item()
# 매 epoch마다 dev 성능 측정
# 모델을 평가용으로 셋팅
model.eval()
with torch.no_grad():
dev_outputs = model(dev_tensors)
dev_preds = torch.argmax(dev_outputs, axis=1)
dev_accuracy = torch.sum(dev_preds == dev_labels).item() / len(dev_labels)
# save best model on dev data
if dev_accuracy > best_accuracy:
best_model = model
best_accuracy = dev_accuracy
print(f"Epoch {epoch+1}, Accuracy: {dev_accuracy} , loss: {epoch_loss/len(train_tensors)}")
from sklearn.metrics import accuracy_score # Accuracy 측정 함수 import
final_model = best_model # dev에서 성능이 제일 좋았던 모델
test_tensors = torch.cuda.FloatTensor(test_vectors.toarray(),device=device)
pred_results = final_model(test_tensors) # 최종 모델로 test 데이터 예측
pred_labels = torch.argmax(pred_results, axis=1)
accuracy = accuracy_score(test_data['label'], pred_labels.tolist()) # 정확도 측정
print("Accuracy: {:.2f}%".format(accuracy*100)) # 정확도 출력