Dropout 실습

Layer의 노드가 필요이상으로 너무 많으면 Loss를 잘 줄이지만 기계적으로 정답을 맞히게 된다 -> Overfitting문제 발생!!

-> 각 노드의 역할 분담을 잘 시켜서 적절히 학습이 이루어지도록 만들어주는 것이 Dropout의 목적이다.

직접 코드로 실행해보고 결과를 보려고 한다.

x = torch.randn(3,7) 
drop = nn.Dropout(p=0.3)
print(drop(x))

여기서 p는 노드를 사용하지 않을 확률이다.(논문에는 사용할 확률로 되어있음.)

결과는 아래와 같다.

tensor([[-1.7319, -0.8754, -0.0000,  1.6761,  0.0000, -0.9214,  0.0000],
        [-1.6490,  0.6455,  0.0178, -0.5975,  0.0000, -0.0000, -0.0000],
        [ 0.8004,  0.0000,  0.7655, -0.0000, -0.5344, -0.3155,  0.0000]])

7개 노드에 3번씩 데이터를 통과시켰더니 어떤 노드는 사용하고 어떤 노드는 사용되지 않아, 0으로 출력되는 것을 확인할 수 있다.

 

간단한 Linear 모델에 dropout을 적용해서 결과를 확인해보자.

class sample_model(nn.Module):
    def __init__(self):
        super().__init__()
        self.drop_layer = nn.Sequential(nn.Linear(5, 7),
                                        nn.Dropout(p=0.3))
        
    def forward(self,x):
        x = self.drop_layer(x)
        return x
model = sample_model()
model.train()
x = torch.randn(3,5)
print("Train Result:")
print(model(x)) # train mode: 누구는 살리고, 누구는 죽이고

model.eval()
print("Test Result:")
print(model(x)) # test mode: 결과에 p를 곱한다.

5개 input이 있는 데이터 3개를 input으로 내가 생성한 model에 통과시키면, 7개 output이 있는 3개의 데이터가 출력될 것이다.

-> (3, 7)

train 모드에서 p는 노드를 사용하지 않을 확률로 이용했다면, test 모드에서는 결과에 p를 곱해서 출력해준다.

결과를 확인해보면,

Train Result:
tensor([[ 0.0000,  0.0521, -0.0000,  0.4185,  0.1143, -0.0000, -1.6034],
        [ 0.0076,  1.3590, -1.9730, -3.2093,  0.0000,  2.0047,  0.7290],
        [-0.9279,  0.0435, -1.0143, -1.2515,  0.3047,  0.0000,  0.5264]],
       grad_fn=<MulBackward0>)
Test Result:
tensor([[ 0.4936,  0.0364, -0.3606,  0.2929,  0.0800, -0.1384, -1.1224],
        [ 0.0054,  0.9513, -1.3811, -2.2465,  1.3970,  1.4033,  0.5103],
        [-0.6495,  0.0305, -0.7100, -0.8761,  0.2133,  0.6243,  0.3685]],
       grad_fn=<AddmmBackward0>)

train모드에서는 0.3 확률로 노드를 사용하지 않아 결과가 0으로 나오고, test모드에서는 0.3을 곱한 결과를 표시해준다.(new_x = x*p)

e.g. Tensor[0,1]의 결과: 0.0521*0.3 = 0.015629999999999998