본문 바로가기

딥러닝 & 머신러닝/딥러닝 지식

배치 정규화(Batch Normalization)의 설명과 탐구

# 배치 정규화(Batch Normalization)의 기능과 그 효과는?

 

우선 공변량 시프트(covariate shift) 현상이라는 것을 한 번 살펴보자. 아래 그림을 보자.

 

 

층 1에 훈련셋이 입력되면 층 2는 층 1의 가중치에 따라 변형된 분포의 훈련셋을 입력받는다. 그런데 학습 과정에서 가중치 값이 계속 갱신되므로, 매 학습마다 바뀐 가중치를 가진 층 1을 통과한 훈련셋인 ~x1, 즉 위에서 설명한 활성화 값은 계속 그 값이 바뀐다.

 

이처럼 학습 도중에 샘플 분포가 바뀌는 현상을 공변량 시프트라고 한다. 이 문제는 층이 깊어질수록 심각해지고 신경망이 잘 학습되지 않는 이유 중 하나다. 한마디로, 학습 중간에 가중치가 계속 업데이트 되면서 학습 데이터의 분포가 수시로 바뀌는 현상이다.

 

우리가 가중치 초기화(Weight Initialization)를 얘기할 때, 각 층에서의 활성화 값이 고르게 분포되어야 한다고 했다. 다시 한 번 짚어보면, 활성화 값이 한 쪽으로 치우친다는 것은 다수의 노드들이 같은 값을 출력한다는 의미이므로, 노드 여러 개를 둔 의미가 없다는 것이므로, 표현력이 제한된다는 뜻이다.

 

그러므로, 지금까지 본 공변량 시프트의 결과는 활성화 값이 고르게 분포되지 않는 것이라고 말할 수 있다.

 

데이터 전처리에서는, 위와 같이 일반적으론 어떤 데이터의 분포에서 각 데이터 마다 그 데이터들의 평균을 빼고, 그 값을 표준편차로 나눠줌으로써 평균 0, 표준편차 1인 분포를 따르도록 정규화한다.

 

BN(Batch Normalization)은 이 과정을 매 층마다 독립적으로 적용해서 각 미니 배치들이 표준 정규 분포를 따르도록 강제한다. 다시 말하면, 훈련하는 동안 데이터 분포의 평균과 분산이 바뀌더라도 이에 적응하여 데이터를 표준 정규화하는 것이다. 즉, BN은 각 층이 활성화 값을 고르게 퍼뜨리도록 강제하는 것이다.

 

한편 처음부터 훈련셋에 대해 정규화하고 훈련을 시작하는 게 아닌, 왜 하필 배치마다 정규화 하는걸까? 그 이유는 매 iteration 마다, 즉 미니 배치 안의 데이터를 한 번 훑을 때마다 가중치 업데이트가 되기 때문에(iteration 수 = 미니 배치 수), 그때마다 정규화하는게 성능이 낫다고 밝혀졌다.

 

그리고 BN은 어디에 적용하는 게 더 나을까? 이전 층을 통과하고 다음 층으로 통과할 준비가 된 입력 ~x(=y=t(z), t는 활성화 함수)가 나을까? 아니면 선형 연산을 적용한 중간 결과 z(=wx+b)가 나을까?

 

결론은 후자에 BN을 적용하는 것이 낫다. 왜냐하면 ~x=y=t(z)는 이미 활성화 함수 t의 영향을 받았기 때문에 아무리 정규화 하더라도 표준 정규 분포가 되지 않을 가능성이 크기 때문이다. 아래 그림을 보자. 활성화 함수가 ReLU일 때다.

 

 

 

따라서 배치 정규화 적용 이후에도 정규 분포를 가질 확률이 더 높은 값인 z = wx+b에 배치 정규화를 적용하는 것이 더 좋다. 그래서 보통 모델 코드에서도 활성화 함수 직전에 BN 층이 존재한다.

 

그리고 γ, β라는 값을 이용해서, 원본 값의 평균과 분산을 0,1로 만들면서 잃어버릴 수 있는 정보를 네트워크가 스스로 복원하게끔 한다. γ는 가중치 값의 분포의 너비를 결정하며, β는 가중치 값의 분포의 이동 위치를 결정한다. 두 변수는 선형 변환(linear transform)을 수행하게 하며, 학습으로 그 최적값을 알아내는 하이퍼 파라미터다. 선형 변환을 통해 가중치 값의 분포를 변형해서, 얼마나 많은 가중치를 활성화 할 것인지 결정할 수 있다. 자세한 내용은 아래 그림에서 볼 수 있다.

 

 

 

(추가) ReLU 함수의 경우엔 0 미만의 값들은 전부 gradient가 0으로 바뀌어 버리고, tanh 함수의 경우엔 0 근처 값들이 아니면 gradient가 0으로 수렴한다. 따라서 활성화 함수에 들어가기 직전에 주어지는 값들을 전부 0 근처로 오도록 분포를 강제하면 gradient가 0으로 가버리는 vanishing 문제를 해결할 수 있게 된다. 그것을 해결한게 BN이다.

 

평균 뿐만 아니라 분산 또한 컨트롤하는 이유는, 변환된 값들의 평균이 0이더라도, 그것들의 변화 폭이 너무 작으면 tanh의 아웃풋 값 또한 변화 자체가 너무 작아서 데이터들 간의 차이를 네트워크가 구분하기 어렵다. 또한 변환된 값들의 평균이 0이더라도, 그것들의 변화 폭이 너무 크면 실제 값들 (활성화 함수에 의해 매핑되기 전의 입력값) 이 매우 큰 경우, 그 값을 포함한 다른 값들의 평균을 0으로 만들 때 적정한 값으로 제한하는데에 실패할 것이다.

 

BN의 문제점 중 하나는, 활성화 함수 통과 전의 뉴런의 출력 값들이 고유한 평균과 분산을 갖고 있고, 그러한 평균과 분산 자체도 우리 데이터의 고유한 특징이라서 네트워크가 학습해야하는 중요한 정보를 담고 있는 경우가 있다. 이러한 경우 평균과 분산을 0, 1로 만드는 변화는 결국 네트워크가 잘 추출한 정보를 잃어버리게 만드는 과정일 수 있다. 그래서 평균과 분산을 0, 1로 만들면서 잃어버려진 정보를 우리가 네트워크로 하여금 스스로 정보를 복원하도록 만드는 과정이 존재한다. 평균과 분산을 0, 1인 분포를 갖는 바로 그 값에다가 gradient descent를 통해 γ, β라는 파라미터를 최적화하는 추가 레이어가 BN내에 존재한다.

 

* 현재는 수학적으로 공변량 시프트를 조정하는 것이 아님이 증명되었고, loss function을 smoothing 한다는 효과가 있다고 함.

 

# BN의 장/단점

 

- 가중치의 초기값에 크게 의존하지 않음. 어차피 각 층이 활성화 값을 고르게 퍼뜨리도록 강제하므로.

- 오버피팅을 억제함. 훈련 데이터의 미니 배치마다 각기 달랐던 평균, 표준편차를 0, 1로 통일시켜 사용하므로 원래 훈련 데이터에 노이즈를 넣는 효과가 난다. 즉, Dropout과 비슷하고, 일종의 규제로도 볼 수 있다. 즉, 각종 규제 기법의 필요성이 감소하여 L1, L2 규제, Dropout의 필요성이 감소한다.

- Gradient Vanishing / Exploding 문제를 해결함.

- 학습 시간이 감소함.

 

한편 미니 배치의 사이즈(코드에서 batch_size)가 너무 작으면 동작이 잘 안된다. 또한 BN을 중간중간 끼워넣음으로써 결국엔 모델이 복잡해진다는 단점도 있다.

 

# BN을 적용해서 모델을 학습시킨 이후 실제 이 모델을 사용할 때 주의점은?

 

학습시에는 각 미니 배치 단위의 평균과 표준편차를 이용해 Normalize하지만, 실제 Test 데이터에 대해 사용할 때는 모델에 입력되는 미니 배치의 단위가 더 작을 수 있기 때문에 미리 Training 데이터에서 뽑아낸 평균과 표준편차를 이용해 Normalize 해야한다.

 

# GAN에서 Generator쪽에 BN을 적용해도 될까? 이미지 복원 모델에서는?

 

일반적인 GAN에서 Generator의 output layer와 Discriminator의 input layer에는 BN을 적용하지 않는다. Discriminator가 조작되지 않은 Generator 결과물의 정확한 값으로 학습하기 위해서다. BN을 적용하면 데이터가 표준화되는 것이므로 조작이 가해지는 것이다. 비슷한 이유로, Denoising이나 Super-Resolution과 같은 이미지 복원 task에서도 BN을 사용하지 않는다. 이미지 복원 task들은 input image의 feature를 최대한 보존하며 끌어와 사용해야하기 때문에, BN과 같은 조작이 들어가면 안된다. 이러한 것은 SR의 경우 EDSR 논문에서 증명되었다. 

 

또한, 주로 작은 image patch를 사용하는 low-level task에서는 mini-batch간의 분산이 커지기 때문에 미니 배치의 사이즈에 영향을 많이 받아, BN은 잘 사용되지 않는다. 대안으로 Instance Normalization(IN)은 normalization을 학습과 추론시에 동일하게 적용하며 batch 영역과 무관하게 평균과 분산을 재조정하는 역할을 함으로써 BN보다 더 많은 정보를 보존한다는 장점이 있다. 이에 기인해 HINet 저자들은 IN을 활용한 HIN Block을 제안했다. HIN Block은 말그대로 input에 대해 절반만 IN을 적용한다.

 

# BatchNorm, LayerNorm, InstanceNorm, GroupNorm 설명

 

N개의 데이터가 하나의 미니 배치를 이루고, (즉 N = 미니배치 사이즈) 각각의 데이터는 HxWxC의 크기를 갖고 있다. 동일한 색깔로 칠해진 것들이 한번에 normalize 된다. 자세한 설명은 블로그 링크 참고.

 

 

https://dongsarchive.tistory.com/74