시작은 미약하였으나 , 그 끝은 창대하리라

[Pytorch 스크래치 코드] 회귀문제 Train, Validation 함수 본문

인공지능/딥러닝 스크래치 코드

[Pytorch 스크래치 코드] 회귀문제 Train, Validation 함수

애플파ol 2023. 12. 17. 15:27

※  (23.12.17기준) -> 코드 동작 100퍼센트 확인 못해봄.

 

✓ pytorch 에서는 Train 과 evaluation 과정을 코드를 통해 수행한다.

✓ 이를 위해 스크래치 코드를 작성해보았다. (회귀 문제임)

 분류는 train에서 loss, accuracy 처리법이 상이

 

 

❏ 분류 문제 Train, Validation 함수

 

→ 주의사항 : 회귀문제는 정확도를 뽑지않고 Loss 값만 출력을 실행하고, 모델을 평가할때도 정확도 지표보단 error(오차)값을 평가 지표로 사용한다. (이유: 회귀문제는 경향성(추세)이 중요하기 때문임, 정확도를 평가지표로 사용한다면, 말도 안되는 처참한 결과를 볼 수 있다.)

 

# 학습 함수
training_loss_hist = [] # tuple() 로 해도됨
def train(model_name, train_loader,device,optimizer,loss_func,log_interval=10):
    Train_total_loss=0

    # train mode로 설정
    model_name.train()
    for batch_idx,(x_train, y_train) in enumerate(tqdm(train_loader)):

        x_train=x_train.to(device)
        y_train=y_train.to(device)
        
        # 예측값 출력
        y_predict=model_name(x_train)
        
        # loss 계산
        loss=loss_func(y_predict,y_train)
        Train_total_loss+=loss.item()


        # 그라디언트 0으로 설정후 -> 파라미터 업데이트
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        # 한 epoch에서 'log_interval'번의 미니배치마다 loss 출력
        # if batch_idx % log_interval==0:
        #     print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
        #         1+epoch,batch_idx*len(x_train),len(train_dataloader.dataset),
        #         100.*batch_idx/len(train_dataloader.dataset),loss.item()
        #     ))

    avg_train_loss=Train_total_loss/len(train_loader)
    print('Train Epoch: {} Average loss: {:.6f}'
          .format(1+epoch, avg_train_loss))
    
    # 학습데이터에서 loss, accuracy 저장
    training_loss_hist.append(avg_train_loss)
    
    


# 평가 함수
val_loss_hist = []
def evaluate(model_name,test_loader,device,loss_func):
    correct=0
    val_loss=0

    # evaluation mode로 설정 
    model_name.eval()
    with torch.no_grad():
        for idx,(x_test,y_test) in enumerate(test_loader):

            x_test=x_test.to(device)
            y_test=y_test.to(device)         
        
            y_pred=model_name(x_test)
            loss=loss_func(y_pred,y_test)


            val_loss+=loss

    avg_val_loss=val_loss/len(test_loader)

    print('Validation set: Average loss: {:.4f}'
          .format(avg_val_loss))
    print()

    # 검증데이터에서 loss,  저장
    val_loss_hist.append(avg_val_loss)

    return avg_val_loss

 

 

❏ 실제 적용.

loss_func=nn.L1Loss()
optimizer = torch.optim.Adam(model_1.parameters(), lr=0.0001)

# 전체 훈련 데이터에 대해 경사 하강법을 20회 반복
nb_epochs = 3
for epoch in range(nb_epochs):
    train(model_name=model_1,
        train_loader=train_dataloader,
        device=device,
        optimizer=optimizer,
        loss_func=loss_func,
        log_interval=10)

    val_loss=evaluate(model_name=model_1,
                           test_loader=val_dataloader,
                           device=device,
                           loss_func=loss_func)

    early_stopping(val_loss, model_1)


    if val_loss < best_val_loss:
        best_val_loss = val_loss
        # Save the model when the validation loss improves
        model_path = f"{'./pt/'}model_epoch_{epoch}_Loss_{val_loss:.2f}.pt"
        torch.save(model_1.state_dict(), model_path)    

    if early_stopping.early_stop:
        print("Early stopping")
        break

 

 

❏ 참고하면 좋을 만한 정보.

 

https://put-idea.tistory.com/90

 

[Pytorch 스크래치 코드] 분류문제 Train, Validation 함수

✓ pytorch 에서는 Train 과 Validation 과정을 코드를 통해 수행한다. ✓ 이를 위해 스크래치 코드를 작성해보았다. (분류 문제임) ✓ 회귀는 train에서 loss, accuracy 처리법이 상이함. ❏ 분류 문제 Train, Ev

put-idea.tistory.com

 

https://put-idea.tistory.com/87

 

[Pytorch 스크래치 코드] Early Stopping

➢ Loss, Accuracy 에 따라 코드가 일부 상이함으로 주의. ✓ Pytorch 는 Tensorflow 처럼 Early stopping API 를 제공하지 않는다. 결국 early stopping을 위해 Pytorch 에서는 직접 구현을 해야 함. ✓ train.py (학습코

put-idea.tistory.com

 

Comments