본문 바로가기

[Pytorch] Gradient Vanishing & Exploding 막는 방법

Derrick 발행일 : 2022-06-04
728x90
반응형

 

많은 layers를 가진 Neural Network을 학습할 때, Backpropagation 과정에서 input층으로 갈수록 Gradient가 점점 소멸되는 현상을 Gradient Vanishing.
Weight가 업데이트가 잘 이루어지지 않아서 최적의 모델을 만들어낼 수 없다.
→ 이번엔 Gradient Vanishing과 그 반대인 Exploding 현상 방지법에 대해 공부!

 

1. ReLU function

앞서 공부한 내용이므로 조금 복습하면, Sigmoid 함수를 Activation function으로 사용할 경우, 양끝단(입력의 절대값이 큰 경우)에 output이 0 혹은 1에 수렴하면서 기울기(Gradient)가 0에 가까워지는 현상이 발생한다.
- 이 때, input측으로 갈수록 제대로 학습이 진행될 수 있도록 Gradient Vanishing 발생!
- 이를 완화하기 위해서, ReLU 함수를 Activation function으로 사용한다.

 

 


 

2. Weight initialization (가중치 초기화)

설계한 모델을 훈련시킬 때, Weight(가중치)가 초기에 가진 값에 따라서 학습 결과가 달라질 수 있다.
- 즉, Weight initialization를 잘 수행한다면 Gradient Vanishing 현상을 줄일 수 있다.
- 딥러닝 모델의 Weight initialization을 한 후 학습을 하면 훨씬 성능이 향상됨.

 

 

 위의 수식과 같이, 가중치 초기화하는 방법에는 2가지가 있다. (Xavier / He initialization)
- He initialization은 Xavier의 변형된 모델이며, 수식도 매우 유사하다.
- Xavier 수식에서 n_out(= layer의 output 수)를 소거함.

 

''' import, data load 생략 '''

# nn layers
linear1 = torch.nn.Linear(784, 256, bias=True)
linear2 = torch.nn.Linear(256, 256, bias=True)
linear3 = torch.nn.Linear(256, 10, bias=True)
relu = torch.nn.ReLU()

# xavier initialization 적용
torch.nn.init.xavier_uniform_(linear1.weight)
torch.nn.init.xavier_uniform_(linear2.weight)
torch.nn.init.xavier_uniform_(linear3.weight)

 

>>
Parameter containing:
tensor([[-0.0215, -0.0894,  0.0598,  ...,  0.0200,  0.0203,  0.1212],        # weight값 초기화 확인
        [ 0.0078,  0.1378,  0.0920,  ...,  0.0975,  0.1458, -0.0302],
        [ 0.1270, -0.1296,  0.1049,  ...,  0.0124,  0.1173, -0.0901],
        ...,
        [ 0.0661, -0.1025,  0.1437,  ...,  0.0784,  0.0977, -0.0396],
        [ 0.0430, -0.1274, -0.0134,  ..., -0.0582,  0.1201,  0.1479],
        [-0.1433,  0.0200, -0.0568,  ...,  0.0787,  0.0428, -0.0036]],
       requires_grad=True)

 


 

3. Batch Normalization

Batch NormalizationGradient Vanishing & Exploding 문제를 직접적으로 해결할 뿐 아니라 "Internal Covariate Shift" 문제를 해결하기 위한 정규화(Normalization) 방법이다.
# Covariate Shift
 : 입력 데이터의 분포(distribution)가 학습할 때와 테스트할 때 다르게 나타나는 현상
 → training set과 test set의 분포가 서로 다르면, 학습시킨 모델의 분류 성능이 떨어지게 된다.
 
# Internal Covariate Shift
 : 위의 Covariate Shift 현상이 Neural Network 내부에서 layer마다 일어나는 것을 것을 말한다.
 → 하나의 layer 기준에서 layer들 사이의 Covariate Shift가 발생할 수 있기 때문에, layer가 깊어질수록 더 많이 발생할 수 있다. 이를 해결하기 위해 'Batch Normalization' 수행!

 

 

Batch NormalizationNeural network를 학습할 때, 각 layer마다 변형된 분포(distribution)이 발생하지 않도록 각 mini-batch들마다 normalization을 해주는 방식이다.

 

'''모델 구현할 때, Batch normalization 추가(예시)'''

# nn layers
linear1 = torch.nn.Linear(784, 32, bias=True)
bn1 = torch.nn.BatchNorm1d(32)                            # Batch Normalization 적용

linear2 = torch.nn.Linear(32, 32, bias=True)
bn2 = torch.nn.BatchNorm1d(32)                            # Batch Normalization 적용

relu = torch.nn.ReLU()

 

Batch normalization은 보통 relu activation 등의 function 이전에 사용하며, Dropout 때와 마찬가지로 training mode와 evaluation mode를 구분해서 적용해야 한다.   

 

[ Batch Normalization Architecture ]

 


 

4. Layer Normalization

 Layer Normalization은 기본적으로 Batch Normalization과 동일하게 batch 단위로 정규화를 실행한다는 면에서 동 일한 컨셉이지만, 정규화를 할 때 어느 축을 기준으로 하냐에 따라 차이가 있다.
 즉, "Data Sample 단위로 정규화"할 것인지 혹은 "Feature 단위로 정규화"할 것인지의 차이

 

[ Batch Norm vs Layer Norm / 세로축 : features, 가로축 : batch ]

 

- Batch Normalization
 : mini-batch의 feature별 평균(mean)과 분산(variance)를 구해서 정규분포로 전환
 → 위의 그림에서 feature 수가 6개로, 6개의 평균과 표준편차를 계산하고 이를 통해 정규화 수행! (Feature 단위로 정규화 수행)
 
- Layer Normalization
 : batch에 있는 모든 feature의 평균과 분산을 구한다. 즉, hidden layer 전체의 평균과 분산으로 normalization을 수행한다.
 → 특성의 수, batch size와 상관없이 sample의 수가 3개로, 3개의 평균과 표준편차를 계산한다. (Data Sample 단위로 정규화 수행)

 

 

 

 

댓글