HyeM

[PyTorch] Optimization & Training & Evaluating 본문

Study/AI&DeepLearning

[PyTorch] Optimization & Training & Evaluating

Hailey_HyeM207 2021. 1. 18. 16:35

plan0a-0z-entering-security.tistory.com/95

지난 번 글에서 만든 model을 이용하여 실습을 해보자.

model

 

 


01. Optimization & Training


▶Optimization

Model과 Optimization 설정
parameter들 확인(weight, bias 순서대로 보여줌)

▶ Before Training

학습하기 전에 Model이 Train할 수 있도록 Train Mode로 변환

(Convolution 또는 Linear 뿐만 아니라, DropOut과 추후에 배우게 될 Batch Normalization과 같이 parameter를 가진 Layer들도 학습하기 위해 준비)

 

1. 모델에 넣기 위한 첫 batch 데이터 추출

2. 추출한 batch데이터를  cpu 또는 gpu와 같은 device에 compile

3. gradients를 clear해서 새로운 최적화 값을 찾기 위해 준비

4. 준비한 데이터를 model에 input으로 넣어 output을 얻음

5. Model에서 예측한 결과를 Loss Function에 넣음

(예제에서는 Negative Log-Likelihood Loss 라는 Loss Function을 사용)

6. Back Propagation을 통해 Gradients를 계산

7. 계산된 Gradients는 계산된 걸로 끝이 아니라 Parameter에 Update

▶ Training

for epoch in range(1, epochs+1):
    # Train Mode
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader): #enumerate로 같이 인덱스 출력?
        data, target = data.to(device), target.to(device)  #cpu 탑재
        optimizer.zero_grad()  #clear하기 
        output = model(data)  #받은 data를 모델에 넣음 
        loss = F.nll_loss(output, target) #output과 target을 비교하여 loss 구함
        loss.backward() #기울기 구하고 
        optimizer.step() # update하기 
        
        #로그파악        
        if batch_idx % log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset), #전체 데이터의 몇번째 인지, 몇퍼센트인지, loss.item하면 그 값들이 나옴
                100 * batch_idx / len(train_loader), loss.item()
            ))
            
            
    #위에서 trian하고 아래서 eval함. 한 에폭당 돎        
    model.eval()

    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)

    print('\nTest set: Average Loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset)))

결과값

 

 

 


02. Evaluation


앞에서 model.train() 모드로 변한 것처럼 평가 할 때는 model.eval()로 설정

- Batch Normalization이나 Drop Out 같은 Layer들을 잠금

model.eval()  #모델 평가모드 

test_loss = 0
correct = 0

with torch.no_grad(): #기울기 같은거 다 꺼버림 #이걸 하는 이유 : 메모리 사용량 줄이고, 속도 높여줌 
    for data, target in test_loader: 
        data, target = data.to(device), target.to(device) #device에 탑재 
        output = model(data) #모델에 넣음 
        test_loss += F.nll_loss(output, target, reduction='sum').item() #loss를 한번에 계산해서 넣어줌
                                                        # sum : sum하면 하나의 스칼라로 리턴하여 test_loss에 더하는게 가능 
        
        # 하나의 데이터에 대해서 가장 강한 인덱스(컴퓨터가 생각하는 정답)을 얻음 => keepdim : 차원 유지 
        pred = output.argmax(dim=1, keepdim=True) 
        correct += pred.eq(target.view_as(pred)).sum().item() #얼마나 맞았는지 모음
                                                            #같은건 같은 거 끼리 , sum해서 item에 담음 (eq는 같은지)

test_loss /= len(test_loader.dataset) # test_loader를 불러옴 

print('\nTest set: Average Loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
    test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset)))

결과값(예측률 89%)

 

Comments