Batch Normalization
Concept
Deep learning이 흥행하기 시작하면서 가장 중요했던 아이디어 중 하나는 Batch Normalization이라고 할 수 있다.
Batch normalization은 신경망을 더욱 튼튼하게(?) 만들어주는 효과가 있어 Hyperparameter에 대한 문제를 좀 더 쉽게 완화해준다.
이전에 배웠던 Data Normalization은 elongated하게 퍼져있던 데이터들을 균일한 분포로 모아주면서 학습 속도를 가속화 시켜주는 효과가 있었다.
하지만 Deep neural network는 여러개의 layer가 그 전의 layer로부터 a값을 받아 z를 구하기 때문에, 전체 데이터X에대한 Normalization은 크게 효과를 볼 수 없다.
그러므로 각각의 Layer마다 z값 혹은 a값을 Normalize 해주면서 학습하는 방법이 바로 Batch normalization이라고 할 수 있다. (a값을 normalize할 수도 있지만, 토론 결과 z의값이 더 보편적이라고 결론.)
위의 사진은 Batch normalization의 진행과정을 대략적으로 나타낸것이다.
보는 것과 같이 Activation function 전에, z에 대하여 z_tilde를 구한 후 a를 구해 넘겨준다.
z_tilde를 구하는 과정은 Data Normalization할때와 유사하다.
layer l의 z^[l]의 z^(i)들에 대해서 평균과 편차를 구한 뒤 z_norm을 구해준다. 이때 분모가 0이 되는것을 막기위해 아주 작은 수인 epsilon을 더해준다.
이로써 모든 z의 요소들은 평균값0과 편차1을 가지게 되는데, 우리는 모든 hidden unit이 이와 같은 분포를 가지는것을 원하지 않는다.
따라서 감마(r)와 베타(B)를 통해 z_tilde를 구해준다. 감마와 베타는 Gradient descent를 통해서 learning이 가능하다.
z_tilde를 구하는 과정에서, +b는 평균화에 의해 사라지므로 Gradient descent를 할때 db를 구할 필요가 없다.
W,B,r 에 대해서 Gradient Descent를 진행하면 된다.
게다가 Tensor flow나 Pytorch 같은 프레임 워크를 사용하면 보통 Batch normalization은 코드 한줄로 구현을 할 수 있기 때문에 세세한 부분은 신경쓰지 않고 개념 정도만 익혀놓으면 좋을 것 같다.
Why does Batch normalization Work?
Batch normalization는 Covariate Shift를 상쇄시켜주는 역할을 하기 때문에 모델의 학습에 도움을 준다.
Covariate Shift는 train data의 distribution과 test data의 distribution이 달라지는 경우를 뜻한다.
예를들어 우리가 고양이를 판별하는 모델을 검은고양이의 사진들로만 학습시켰다고 해보자.
만약 색이 있는 고양이들을 input으로 주어도 모델을 잘 판별해야하는데, distribution이 다르므로 잘 판별하지 못하게 되고, 이런 경우 모델을 다시 학습시켜야 할 수도 있다.
이러한 상황에서 Batch normalization은 평균을0, 편차를1 (감마,베타에 의해서 바뀔수도 있음) 혹은 다른값으로 제한시켜주기 때문에 입력값이 변할때 생기는 문제를 막아준다.
추가적으로, 의도치는 않았지만 추가적으로 생기는 regularization 효과가 있다.
Batch normalization은 mini-batch의 단위로 일어나기 때문에 여기서 산출된 평균/편차는 전체 데이터셋의 그것보다 더 많은 noise를 갖게 된다. 따라서 Drop out과 같이, hidden layer의 activation에 noise를 더해주어 일종의 regularization 효과를 준다.
하지만 Batch norm은 regularization이 주 목적이 아니라 부수적인 효과이기 때문에, regularization의 목적으로 사용하면 안된다.
Batch Normalization at Test time
Batch norm은 data를 Mini-batch 단위로 처리한다. 하지만 우리는 model을 test할때, 데이터를 하나하나의 단위로 처리해야 할 수도 있다. 이러한 경우를 위해서 어떠한 신경망에 처리를 해주어야 할까?
데이터를 하나씩 처리할때는 평균이나 편차를 구할 수도 없다. 이를 위해 우리는 Batch normalization을 하며 학습할 때, 각 layer에 대한 뮤(평균) 값과 시그마제곱(편차)를 저장하며 Exponentially Weighted Average를 계속해서 구한다.
그리고 테스트 데이터가 들어오면, 그 값을 사용하여 z_tilde의 값을 구한다.
(사실 프레임 워크를 사용하면 신경쓰지 않아도 된다.)
연관글
Improving Deep Neural Networks: Hyperparameter Tuning, Regularization and Optimization
Practical Aspects of Deep Learning(1)