본문 바로가기

ML&DL/PyTorch

[PyTorch] 시계열 데이터를 위한 다양한 Normalization기법 (BatchNorm1d, GroupNorm 사용법)

Normalization

Neural network의 깊이가 점점 깊어질수록 학습이 안정적으로 되지 않는 문제가 발생한다. 이런 학습의 불안정화의 원인으로 'internal covariance shift'가 언급되었다. 이는 딥러닝에서 각 layer를 지나면서, inner representation의 distribution이 달라지는 현상을 말한다. 그러므로 layer를 지날 때 마다 변하는 데이터 분포의 scale을 맞춰주는 과정을 통해 안정된 학습을 보장할 수 있는데 이러한 방법을 Normalization이라고 한다. 기본적인 정규화로 표준정규분포를 맞춰주는 방법을 생각할 수 있을 것이다.

 

  • 데이터의 범위를 정한다. (이 범위에 따라 batch normalization/ layer normalization이 나눠진다.)
  • 평균과 분산을 구한다.
  • 표준화 시킨다. (zero mean, unit variance)
  • 추가로 scale과 shift를 추가해 분포를 조정할 수도 있다. (affine transform)

scale과 shift를 통해 affine transform 가능 (둘다 learnable parameter)

Normalization의 장점

1) 학습의 안정화: Gradient vanising/exploding 문제를 해결할 수 있음

2) 학습시간의 단축: learning rate를 크게 할 수 있음

3) 성능 개선: local optimum에서 빨리 빠져나올 수 있음

 

용어 정의

내가 다루는 데이터가 시계열데이터(음성)이다보니, 시계열 데이터를 기준으로 작성하였다. 그래서 내가 사용하는 시계열 데이터를 기분으로 용어를 정의하고 시작하겠다.

 

B: Batch_size

T: Time step

N: Feature dimension

Batch Normalization (BN)

한 feature dimension에 대해 모든 batch를 normalize한다. (=batch 차원의 정규화) #[B, N, T] -> [B, N, T]

** feature dimension이 1이라면 time step마다 normalize한다. # [B, T] -> [B, T]

 

class block(nn.Module):
    def __init__(self, in_channel, out_channels):
        super(block, self).__init__()
        bn = nn.BatchNorm1d(in_channel)
        ...
    def forward(self,x):
        out = bn(x)  #[B, N, T] -> [B, N, T]

Layer Normalization (LN)

모든 time step에 대해 하나의 layer만 normalize한다. (=Feature 차원의 정규화)

 

class block(nn.Module):
    def __init__(self, in_channel, out_channels):
        super(block, self).__init__()
        ln = nn.GroupNorm(1, in_channel, eps=1e-08)
        ...
    def forward(self,x):
        out = ln(x)  #[B, N, T] -> [B, N, T]

 

Group Normalization (GN)

채널 방향으로 group을 지어서 normalization을 진행하고 아래의 예시처럼 2로 설정하면 2개의 group으로 나누어 normalization을 진행한다.

 

class block(nn.Module):
    def __init__(self, in_channel, out_channels):
        super(block, self).__init__()
        gn = nn.GroupNorm(2, in_channel, eps=1e-08) 
        ...
    def forward(self,x):
        out = gn(x) #[B, N, T] -> [B, N, T]

 

Instance Normalization (IN)

각 채널별로 normalization한다. 주로 style transfer에 쓰이는 방법이다. instance normalization을 통해 contents요소만 살리고 화풍을 지울 수 있다고 한다.

 

class block(nn.Module):
    def __init__(self, in_channel, out_channels):
        super(block, self).__init__()
        in = nn.GroupNorm(in_channel, in_channel, eps=1e-08) 
        ...
    def forward(self,x):
        out = in(x) #[B, N, T] -> [B, N, T]

 

Reference

Wu, Yuxin, and Kaiming He. "Group normalization." Proceedings of the European conference on computer vision (ECCV). 2018.

pytorch.org/docs/stable/generated/torch.nn.BatchNorm1d.html

discuss.pytorch.org/t/batch-normalization-disambiguation/42391/2