이번 강의에서는 어떻게 모델을 "잘" 학습시킬지에 대한 전략들에 대해 다룬다.
(마지막 파트에 대한 보충설명이 곧 추가될 예정)
Part 1 : Batch Normalization
만약 모델을 학습시키는데 학습이 잘 안되는 경우에 어떻게 해야할까?
Neural Net은 복잡하기에 다양한 전략을 사용해서 훈련시켜야한다.(이전 강의들에서 봤듯이, local minima등에 빠질 가능성이 너무 높다!!)
이에 사용할 수 있는 방법들로는 다음이 있다.
만약 데이터가 다음의 두 상황이라면 어떨까?
오른쪽의 경우가 왜 어려운 경우일까?
그래프로 확인할 수 있듯이 오른쪽에서는 첫번째 차원이 훨씬 크다. 이러한 경우에 왜 문제가 될 지 이전에 배운 back propagation으로 확인해보자.
Loss function을 첫번째 weight matrix $W^{(1)}$에 대해 derivative를 구하면 위와 같이 $\delta x^T$형태가 되는데 오른쪽의 경우, 즉 차원끼리 너무 magnitude가 차이나는 경우에는 $\delta x^T$가 차원끼리 너무 차이가 나버린다. 즉 어떤 derivative는 너무 작고 어떤 건 너무 크게 되는 것이다.
이를 그림으로 표현하면 다음과 같다.
즉 최적의 점으로 가기가 오른쪽의 경우에 힘들어진다.
일반적으로는 이런게 큰 영향을 끼치지 않는다. 이미지, 텍스트의 경우에 각각 0부터 255사이의 픽셀값을 갖거나 one-hot vector로 표현되기 때문이다.
하지만 예를 들어 날씨를 예측한다고 해보자. 이는 magnitude에 민감하므로 적절한 전략을 취해주지 않는다면 큰 오차가 발생할 것이다.
그럼 이를 위해 어찌해야할까???
간단한 방법으로는,
1. Standardization
데이터가 평균 0, 표준편차가 1이 되도록 변환해준다.
(고등학교때 배운 평균빼고 표준편차로 나눠주는 방법이라 생각하면 된다.)
모든 이러한 계산을 차원마다 해줘야한다.
또한 input뿐만 아니라 output에도 적용해줄 수 있다!(Regression 같은 경우에)
그럼 activation에도 사용가능할까? 즉 activation function을 거친 값들에도 standardization을 해주는 게 적절할까?
👉🏻 기본적으로는 맞지만, 학습하는 동안 평균과 표준편차는 계속해서 변한다는 것을 명심해야 한다.
이러한 아이디어가 사실 Batch Normalization의 베이스다.
위의 계산을 고려한다면 gradient descent방법등으로 weight가 업데이트될때마다 매번 standardization을 매 파라미터에 해줘야 한다는 게 되는데 당연히 계산량이 어마어마해질 것이다.
👉🏻 이에 배치마다 진행하는 것이 Batch Normalization이다.
또한 $\gamma$, $\beta$라는 파라미터가 등장하는데 스케일링과 bias를 담당하게 된다.
그럼 자연스럽게 이러한 질문이 생길 것이다.
"어디에 Batch Normalization을 사용해야 하는데?"
예를 들어 모든 레이어 바로뒤에 넣는 경우와 activation뒤에 넣는 경우를 생각해보자.
아래의 그림을 보자.
첫번째는 ReLU후에 Batch Normalization을 사용하므로 BN의 input은 모두 양수의 값을 가진다.
두번째는 BN뒤에 ReLU를 적용하므로 BN으로 음수가 되었던 값이 ReLU후에 양수값으로 된다.
(이 방법이 원래 BN논문에 나온 방법이라고 한다.)
사실 어떤 것이 더 나은지는 합의된 바가 없다. 두 가지 방법 모두 작동은 하기 때문이다.
또, Batch Normalization을 사용할 때 몇가지 고려해야할 사항이 있다.
1. 더 큰 Learning rate를 쓸 수 있다.
2. 모델이 더 빨리 학습된다는 것
3. Regularization이 덜 필요하다.
Part 2 : Weight Normalization
모델을 정의하고 학습하기 전에 weight는 보통 random 값으로 초기화되어 있다.
Weight를 어떻게 초기화해야 최적의 값으로 수렴이 가능할까?
이번 강의에서는 이에 대해 다룬다.
가장 간단하게 생각할 수 있는 것은 Gaussian 분포로부터 나온 random weight이다.
위와 같은 Gaussian 분포를 생각해보면,
layer가 깊어질수록 위의 파란 그래프와 같이 거의 0에 weight가 수렴하게 된다.(1보다 작은 값을 계속해서 곱하다보면 0에 가까워지기 때문)
이게 왜 문제가 될까? Back propagation에서 gradient를 계산하고 update한다고 할 때 이 gradient가 0에 가까우면 거의 업데이트가 안되기 때문이다. 만약 plateau와 같은 영역에 있다면 영원히 거기에 갇히게 된다.
좀 더 복잡한 초기화 방법을 생각해보자.
위의 경우에 표준편차의 제곱, 즉 분산이 $1/{D_a}$가 되는 경우는 "Xavier initialization"이라고 불린다.
하지만 생각한것과는 달리 아래의 파란그래프를 보면 표준편차가 계속해서 감소하는 것을 볼 수 있는데, 우리가 놓친 것이 있기 때문이다. 바로 활성화함수다.
예를 들어 ReLU를 쓴다고 생각하면 input의 거의 절반가량이 ReLU를 거치고 나면 0으로 나오게 된다. 이에
표준편차가 계속 줄어 0으로 수렴하는 것이다.
👉🏻 이를 어떻게 해결할 수 있을까? 방법은 표준편차를 위와 같이 설정하는 대신 $1/{\sqrt{1/2 D_a}}$로 설정하는 것이다. 즉 표준편차를 조금 키워서 초기화시키는 방법이다.
이제까지는 기본적인 초기화방법에 대해 다뤘다. 이제 좀 더 고급(?) 초기화방법에 대해 배워보자.
Back propagation을 고려해보면 여러 Jacobian Matrix가 계속해서 곱해지게 되는데, 이러한 행렬이 1보다 작은 값이 대다수면 gradient가 줄어들고 크면 gradient가 커지게 될 것이다. 또한 1에 가깝다면 identity matrix에 가깝게 된다!!
여기서 Singular value decomposition에 대해 짚고 넘어가보자.
각 Jacobian Matrix에 대한 SVD는 다음과 같다.
여기서 가운데 람다 행렬은 일종의 scale를 정하는 역할을 한다.
우리가 애초에 정하는건 weight matrix이기에 SVD를 weight matrix $W$에 대해 생각해보자면,
가운데 람다 행렬이 identity행렬이 되도록 정하면 다음과 같다.
(사실 실제로 사용할 때는 U와 V중 하나를 선택하여 사용하게 된다.)
또 마지막으로 Gradient clipping에 대해서도 짧게 알아보자.
Gradient를 실제로 계산해보면 값이 엄청나게 튀는 일종의 몬스터 그래디언트가 나타나게 된다.
이러한 몬스터가 나타나는 이유로는 다음과 같다.
큰 데이터를 사용하고 랜덤한 일이 많기 때문에 이러한 gradient가 발생하는 경우가 드물지 않다.
이러한 gradient가 그대로 사용되면 loss 함수는 더이상 되지 않고 최적의 점에서 더 멀어지는 현상이 일어나게 된다.
이러한 몬스터를 해결할 수 있는 간단한 방법이 Clipping이다.
Part 3 : Ensembles & Dropout
만약 모델이 제대로 작동하지 않고 실수를 하게 되면 어떨까?
이에 해결할 수 있는 방법으로는 여러가지 모델을 써서 평균값을 사용하는 방법이 있다.
이를 앙상블(Ensembles)이라 부르는데, 이론적으로 더 알아보자.
한 데이터셋으로부터 independent 데이터를 뽑아낸다고 할 때, 이를 i.i.d로 뽑아낼 수 있다.
이렇게 뽑아낸 데이터를 이용하여 모델들을 학습시킨다고 해보자.
그럼 그 결과를 어떻게 사용할 수 있을까?
👉🏻 가장 간단한 방법은 평균을 내는 방법 또는 가장 많은 표를 받은 값을 사용하는 것이다.
하지만, 두번째 방법은 무조건 1번째 class 등만 점수로 매기기에 second best가 답이 될 수 있는 경우를 고려하지 못하기 때문에 사용이 권장되지는 않는다.
그럼 이제 앙상블을 이론이 아닌 실제 사용에 비추어 알아보자.
신경망을 학습하는데는 사실 이미 너무 랜덤성이 너무 많다.
초기화, 정규화 전략등을 사용한다고 해도 어쨋든 다음과 같은 과정에서 랜덤성이 생겨난다.
이에 앙상블을 통해 이러한 랜덤성을 어느정도 극복할 수 있다.
그럼 이러한 의문이 생길 것이다.
많은 모델 학습시켜야하니까 더 오래걸리는게 아닌가?
사실 어떠한 경우에는 앙상블이 더 빠르기도 한다. 아래의 그림을 보자.
다음으로, Dropout은 랜덤하게 몇개의 activation을 0로 만드는 방법으로, 일종의 대규모 앙상블이라고 볼 수 있다.
앞에서 배운 방법들에 대한 하이퍼파라미터에 대한 내용은 다음과 같다.
'개발 > UC Berkely CS182' 카테고리의 다른 글
[Lecture 9] Visualization and Style Transfer (0) | 2021.05.19 |
---|---|
[Lecture 8] Computer Vision (2) | 2021.05.09 |
[Lecture 5] Backpropagation (6) | 2021.04.18 |
[Lecture 4] Optimization (2) | 2021.04.11 |
[Lecture 3] Error Analysis (2) | 2021.04.04 |
댓글