개발자의 스터디 노트
옐프 리뷰 데이터셋으로 학습 하기 본문
먼저 포스팅으로 훈련에 필요한 데이터를 로딩하고 가공하는 준비를 하였습니다. 이제부터는 앞에서 만들어 두었던 부품을 가지고 조립을 해보겠습니다. 주피터 노트북을 사용할 경우 앞서 포스팅의 소스파일에 이어서 작업하여야 합니다.
1. 훈련 준비
- args 매개변수로 훈련할 정보를 받아 데이터셋과 모델을 만듭니다. 그리고 마지막으로 손실 함수와 옵티마이저를 만듭니다.
import torch.optim as optim
import torch
def make_train_state(args):
return {
'epoch_index' : 0,
'train_loss' : [],
'train_acc' : [],
'val_loss' : [],
'val_acc' : [],
'test_loss' : -1,
'test_acc' : -1
}
train_state = make_train_state(args)
if not torch.cuda.is_available():
args.cuda = False
args.device = torch.device("cuda" if args.cuda else "cpu")
#데이터셋과 Vectorizer
dataset = ReviewDataset.load_dataset_and_make_vectorizer(args.review_csv)
vectorizer = dataset.get_vectorizer()
#모델
classifier = ReviewClassifier(num_features=len(vectorizer.review_vocab))
classifier = classifier.to(args.device)
# 손실 함수와 옴티마이저
loss_func = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(classifier.parameters(), lr=args.learning_rate)
2. 훈련 반복
- 앞서 초기화한 객체를 사용해 모델의 성능이 높아지도록 모델 파라미터를 업데이트합니다. 훈련 반복은 두 개의 반복문으로 구성됩니다. 내부 반복문은 데이터셋의 미니 배치에 대해서 반복을 수행합니다. 외부 반복문은 내부 반복문을 여러 번 반복합니다. 내부 반복문에서 미니 배치마다 손실을 계산하고 옵티마이저가 모델 파라미터를 업데이트합니다.
## 정확도 계산 함수
def compute_accuracy(y_pred, y_target):
y_target = y_target.cpu()
y_pred_indices = (torch.sigmoid(y_pred)>0.5).cpu().long()#.max(dim=1)[1]
n_correct = torch.eq(y_pred_indices, y_target).sum().item()
return n_correct / len(y_pred_indices) * 100
for epoch_index in range(args.num_epochs):
train_state['epoch_index'] = epoch_index
# 훈련 세트 순회
# 훈련 세트와 배치 제너레이터 준비, 손실과 정확도를 0으로 설정
dataset.set_split('train')
batch_generator = generate_batches(dataset, batch_size=args.batch_size,device=args.device)
running_loss = 0.0
running_acc = 0.0
classifier.train()
print("epoch_index : ", epoch_index)
for batch_index, batch_dict in enumerate(batch_generator):
# 훈련 과정은 5단계로 이루어집니다.
# 1단계. 그레이디언트를 0으로 초기화합니다.
optimizer.zero_grad()
# 2단계. 출력을 계산합니다.
y_pred = classifier(x_in=batch_dict['x_data'].float())
# 3단계. 손실을 계산합니다.
loss = loss_func(y_pred, batch_dict['y_target'].float())
loss_batch = loss.item()
running_loss += (loss_batch - running_loss) / (batch_index + 1)
# 4단계. t손실을 사용해 그레이디언트를 계산합니다.
loss.backward()
# 5단계. 옵티마이저로 가중치를 업데이트 합니다.
optimizer.step()
# 정확도를 계산합니다.
acc_batch = compute_accuracy(y_pred, batch_dict['y_target'])
running_acc += (acc_batch - running_acc) / (batch_index + 1)
print("epoch_index = ",epoch_index," train_loss = ",running_loss)
print("epoch_index = ",epoch_index," train_acc = ",running_acc)
train_state['train_loss'].append(running_loss)
train_state['train_acc'].append(running_acc)
#검증 세트 순회
#검증 세트와 배치 제너레이터 준비, 손실과 정확도를 0으로 설정
dataset.set_split('val')
batch_generator = generate_batches(dataset, batch_size=args.batch_size, device=args.device)
running_loss = 0.
running_acc = 0.
classifier.eval()
for batch_index, batch_dict in enumerate(batch_generator):
#1단계. 출력을 계산합니다.
y_pred = classifier(x_in=batch_dict['x_data'].float())
#2단계. 손실을 계산합니다.
loss = loss_func(y_pred, batch_dict['y_target'].float())
loss_batch = loss.item()
running_loss += (loss_batch - running_loss) / (batch_index + 1)
#3단계. 정확도를 계산합니다.
acc_batch = compute_accuracy(y_pred, batch_dict['y_target'])
running_acc += (acc_batch - running_acc) / (batch_index + 1)
train_state['val_loss'].append(running_loss)
train_state['val_acc'].append(running_acc)
print("epoch_index = ",epoch_index," val_loss = ",running_loss)
print("epoch_index = ",epoch_index," val_acc = ",running_acc)
'파이썬 > 파이토치 자연어처리' 카테고리의 다른 글
다층 퍼셉트론 (0) | 2022.02.17 |
---|---|
옐프 리뷰 데이터셋으로 학습한 데이터 평가, 추론, 분석 하기 (0) | 2022.02.16 |
옐프 리뷰 데이터셋으로 학습 준비하기 (0) | 2022.02.14 |
부가적인 훈련 개념 (0) | 2022.02.12 |
지도학습 훈련 순서 (0) | 2022.02.12 |