ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [pytorch] Dropout 알아보기
    AI-ML 2023. 8. 17. 07:05
    728x90
    반응형

    - 목차

     

    키워드.

    • - Regularization
    • - Dropout

     

    들어가며.

    Deep Learning 에서 Dropout 은 Regularization 의 한가지 방식입니다.

    Dropout 은 Input Tensor 의 일부 값을 0으로 변경시킵니다.

    이는 뉴럴 네트워크에서 일부 뉴런을 무효화시키는 결과를 만들어내는데요.

    예를 들어, 아래의 이미지처럼 뉴럴 네트워크의 일부 뉴런이 제외됩니다.

    출처 : https://wandb.ai/authors/ayusht/reports/Implementing-Dropout-Regularization-in-PyTorch--VmlldzoxNTgwOTE

     

    그럼 전체 네트워크에서 일부 뉴런이 제외됨으로써 얻을 수 있는 효과는 무엇일까요 ?

    이는 Overfitting & Regularization 과 관련됩니다.

     

    Overfitting.

    Overfitting 은 모델이 학습데이터를 학습할 때에 학습 데이터에 너무 과적합되는 상태를 의미합니다.

    아래 이미지가 Overfitting 을 잘 설명하는 자료라서 첨부하였습니다.

    학습데이터에 너무 과적합되면 현실의 데이터를 추론할때에 문제가 발생하기 마련입니다.

    모델의 복잡도를 높혀서 모든 학습데이터에 충족된 모델을 만들었을 때에, 학습 데이터와 다른 현실 데이터를 추론할 때에

    큰 오차를 유발할 가능성이 높습니다.

    출처 : https://medium.com/analytics-vidhya/understanding-regularization-with-pytorch-26a838d94058

     

     

    Regularization.

    Regularization 은 모델의 Overfitting 되는 것을 방지할 수 있는 하나의 수단입니다.

    일반적으로 Loss Function 은  $  \sum (\hat{y}_{pred} - y_{label})^{2} $ 와 같은 형식으로 구성되며,

    오차를 최소화하는 방향으로 Optimization 이 진행됩니다.

    이러한 형식에서 Overfitting 을 방지하기 위해서  Regularization Term 을 적용하곤 합니다.

    $$ Cost(W) =  \sum (\hat{y}_{pred} - y_{label})^{2} + \lambda \left|W\right| $$

    이는 $ \lambda $ 는 그 값의 크기만큼 RMSE, MSE, MAE 등의 오차 함수가 최소화되는 데에 제동을 걸게 됩니다.

    그래서 Overfitting 되는 상황을 최대한 방지하게 되죠.

     

    이처럼 Dropout 은 뉴럴 네트워크에서 적용할 수 있는 Overfitting 을 방지하는 하나의 방식입니다.

    의도적으로 일부 뉴런을 제외시켜서 Overfitting 되는 현상을 방지할 수 있습니다.

     

    nn.Dropout 사용해보기.

    Dropout 의 사용법은 아래와 같습니다.

    torch.nn 모듈의 Dropout 클래스를 생성하고, 생성된 Dropout 객체에 Tensor 를 입력합니다.

    아래와 같이 Dropout Layer 로 진입한 Tensor 는 일부 뉴런들이 0 으로 변경됩니다.

    import torch 
    import torch.nn as nn
    dropout = nn.Dropout(p=0.7)
    
    tensor = torch.ones((4, 5))
    # tensor([[1., 1., 1., 1., 1.],
    #         [1., 1., 1., 1., 1.],
    #         [1., 1., 1., 1., 1.],
    #         [1., 1., 1., 1., 1.]])
    
    dropout(tensor)
    # tensor([[0.0000, 3.3333, 0.0000, 0.0000, 0.0000],
    #         [0.0000, 0.0000, 0.0000, 3.3333, 0.0000],
    #         [0.0000, 3.3333, 0.0000, 0.0000, 0.0000],
    #         [0.0000, 3.3333, 0.0000, 3.3333, 0.0000]])

     

     

    p (Dropout Probability) .

    nn.Dropout 클래스는 p 라는 인자를 입력받습니다.

    이는 뉴런를 네트워크에서 제외시키는 확률을 의미합니다.

    위의 예시처럼 p=0.5 로 설정하게 된다면, 50% 의 확률로 뉴런이 네트워크에서 제외됩니다.

    즉 Input Tensor 의 특정 값이 0 으로 변경됩니다.

     

    그리고 주목할 점은 Dropout 되지 않은 뉴런들은 그 값이 증가하게 됩니다.

    증가하는 정확한 비율은 1 / (1 - p) 만큼 증가하게 되구요.

    p 가 0.5 라면 2 배로,

    p 가 0.7 이라면 1 / (1 - 0.7) = 1 / (0.3) = 3.3333... 배로 증가합니다.

    이렇게 값이 증가하게 되는 이유는 Activation Layer 과 관련이 있습니다.

    만약 Dropout 되어 일부 뉴런이 제외된다면 Dropout 된 뉴런만큼 Activation Layer 에 영향을 주지 못하여 다음 Layer 로 값이 전달되지 않을 수 있습니다.

    Sigmoid, ReLU 와 같이 입력 값이 작을수록 그 값은 0 에 수렴하게 되는데, Dropout 된 뉴런만큼 상쇄된 값을 보상하기 위해서 1 / (1 - p) 만큼 증가시키게 됩니다.

     

     

     

    train, eval 함수.

    Dropout 은 오직 학습 단계에서만 적용되는 것이 중요합니다.

    왜냐하면 그 태생적인 목적이 Overfitting 을 방지하는 것이기 때문이죠.

    따라서 학습된 결과로써 추론이나 테스트를 하는 과정에서는 Dropout 을 비활성화해야합니다.

    이러한 기능을 제공하는 것이 nn.Module 의 train, eval 함수인데요.

    간단한 사용법을 살펴보겠습니다.

     

    간단한 모델을 구성해보았습니다.

    nn.Linear 와 nn.Dropout 을 함께 구성하였구요.

    크게 의미있는 내용을 없습니다. Dropout 의 사용법을 설명하기 위함입니다.

    import torch 
    import torch.nn as nn
    
    class my_dropout(nn.Module):
        def __init__(self):
        
            super(my_dropout, self).__init__()
            
            self.linear = nn.Linear(in_features=5, out_features=1)
            
            self.dropout = nn.Dropout(p=0.7)
            
        def forward(self, tensor):
        
            return self.dropout(self.linear(tensor))

     

     

    그리고 model 을 생성합니다.

    model 은 nn.Module 을 상속하는 클래스인데요. nn.Module 은 train 함수와 eval 함수가 존재합니다.

    train 함수가 호출된 이후에는 Dropout 이 활성화되고,  eval 함수가 호출된 이후에는 Dropout 이 비활성화됩니다.

    tensor = torch.ones((4, 5))
    model = my_dropout()
    
    ## Train Mode 
    
    model.train()
    model(tensor)
    # tensor([[-0.0000],
    #         [-0.0000],
    #         [-2.5018],
    #         [-0.0000]], grad_fn=<MulBackward0>)
    
    
    ## Evaluation Mode 
    
    model.eval()
    model(tensor)
    # tensor([[-0.7506],
    #         [-0.7506],
    #         [-0.7506],
    #         [-0.7506]], grad_fn=<AddmmBackward0>)

     

     

    반응형
Designed by Tistory.