히비스서커스의 블로그

[CS231n 7] training neural network 2 본문

Theory/Computer Vision

[CS231n 7] training neural network 2

HibisCircus 2021. 2. 14. 13:49
728x90

 내용들은 전적으로stanford university의 CS231n 2017 7강 강의 내용을 기반으로 작성하였음을 먼저 밝힙니다.

 

 

이전 6강에서는 Training Neural Networks 1에 관해서 살펴보았다.

 

 

2021/02/07 - [Programming/CS231n] - [Lecture 6] Training Neural Networks 1

 

[Lecture 6] Training Neural Networks 1

※이 내용들은 전적으로stanford university의 CS231n 2017 6강 강의 내용을 기반으로 작성하였음을 먼저 밝힙니다.※ 이전 5강에서는 Convolutional Neural Networks에 관해서 살펴보았다. 2021/02/01 - [Program..

biology-statistics-programming.tistory.com

 

 

 

7장 내용은 training neural network 2에 관한 내용이다.

 

Optimization

손실함수는 가중치가 얼마나 안좋은지 나타냄을 우리는 앞서 배웠다. 우리가 최적화과정을 해나갈 때 Gradient의 반대방향으로 업데이트하였다. 그 이유는 이 방향이 손실함수가 내려가는 방향이기 때문이었다. 

 

가장 간단한 알고리즘은 Stoachastic Gradient Descent인데 이는 2가지 문제점이 존재한다.

 

첫 번째 문제점 :: 축의 스케일이 다를 경우와 local minima, saddle point


  1. 두 축의 스케일이 다를 때 최적화 해내가는 방법이 매우 비효율적이 된다 지그재그 형태의 비효율

둘 중 어떤 하나는 업데이트를 해도 손실함수가 아주 느리게 변하는 경우의 함수가 존재한다.

 

즉, 수평 축의 가중치는 변해도 Loss가 아주 천천히 줄어든다. 다시 말해 Loss는 수직 방향의 가중치 변화에 훨씬 더 민감하게 반응하는 것이다. 그 이유는 이런 함수에서는 gradient의 방향이 고르지 못하기 때문이다. 이런 문제는 고차원 공간에서 발생하게 된다.

즉, 차원의 수가 (가중치의 수가 매우 많아질 경우) GSD는 잘 작동하지 않을 것이다.

 

 

  1. local minima , saddle point

 

위의 그림의 X축은 어떤 하나의 가중치를 나타내고 Y축은 Loss를 나타내고 있다. 이 그림에서 local minima에서는 gradient는 0이 되고 양쪽의 기울기는 모두 양수가 된다. 따라서, 학습이 멈추게 된다.

 

saddle point는 어떤 방향에서는 증가하고 어떤 방향에서는 감소하는 방향이 되기에 차원이 높아질 때 빈번하게 발생한다. gradient가 0이 되어 학습을 멈추게 된다. 손실함수를 계산할 때 많은 매번 전부를 계산해야한다.

 

 

문제1과 2에서 더 문제가 되는 사항은 2번이다. 왜냐하면 파라미터의 수가 증가하면 문제 1에서와 같이 파라미터의 gradient가 모두 양의 값을 같거나 음의 값을 가져야 하는 경우의 확률은 매우 낮기 때문이다. 하지만 문제 2에서는 일부가 양의 값을 일부가 음의 값을 갖게 된다면 일어날 수 있으므로 파라미터의 수가 많아질 경우 문제가 된다.

 

두 번째 문제점 :: 미니 배치를 통한 noise


 

이때 미니 배치를 얻게 되는데 정확한 gradient가 아니라 추정값을 이용해서 추론하는것이다. gradient에 noise가 들어간다고 생각하면 된다. 이럴 경우 손실함수가 여러 방향으로 헤매기 때문에 minima에 도덜하는 시간이 더 오래 걸릴 것이다.

 

하지만, full batch를 사용한다고 해도 (Gradient Descent를 사용한다고 해도) 미니 배치를 통한 문제점이 그대로 발생하게 되며 saddle point에 의한 문제도 여전하다.

 

 

첫 번째 해결 방법 :: Momentum 더해주기와 Nesterov Momentum


GSD + Momentum

 

아이디어는 velocity를 유지하는 것이다. 방향만 고려하는 것이 아니라 velocity도 같이 고려한다. velocity의 영향력을 rho를 통해 맞춰준다. 

 

이 방법을 통해 local minima 와 saddle point에서 gradient가 0이 되더라도 진행해나가며 local minima를 찾을 수 있다. 이는 공이 내려오던 속도가 붙는다고 생각하면 쉽다.

 

momentum이 지그재그의 방향의 문제를 해결해준다. momentum을 추가해서 velocity가 추가되면 noise가 평균화된다. momentum을 추가하지 않은 모델보다 더 부드럽게 움직인다. 위와 같은 방향의 Momentum의 변형이 존재한다. 바로 Nesterov mementum이다.  

 

 

 

Nesterov Momentum

 

 

먼저 velocity의 방향으로 움직인 후 그 방향에서 gradient의 방향을 계산하는 식이다. 두 정보을 섞어주는 방법이라고 생각하면 쉽다. convex optimization에서는 잘 작동하지만 nonconvex problem에서는 잘 작동하지 않는다.

 

여기서, 초기 velocity의 지정 0이다. 또한, 직관적으로 보면 velocity는 이전 gradients Weighted sum이며 gradient moving average라고 볼 수 있고 매 스텝마다 이전의 기울기는 지수적으로 감소하게 된다.

 

 

세 가지 비교를 살펴보자.

 

momentum을 추가하면 velocity에 영향을 받기 때문에 minima를 무시해 버리고 이동하다가 갑자기 방향을 바꾸어 수렴한다. Nesterov Momentum이 일반적인 Momentum 에 비해 over shooting이 덜하다는 것을 알 수 있다.

 

 

그렇다면 minima가 매우 가파른 곳에 존재한다면 momentum들이 minima를 무시하고 지나칠 수 있지 않을까?

 

다행히도 우리가 원하는 minima는 보통 평평한 모양에 존재하기 때문에 그런 경우는 거의 존재하지 않는다. 따라서, 크게 고려하지 않아도 된다.  minima가 매우 가파른 곳에 존재한다면 overfitting이 발생하며 test data에 잘 적용할 수 없기 때문이다.

 

 

 

두 번째 해결 방법 :: gradient를 제곱하여 나눠주는 방식의 AdaGrad & RMSProp


AdaGrad

 

 

훈련도 중 계산되는 gradient를 활용하는 방법이다. velocity term 대신에 grad squared term을 활용한다. 그리고 학습 도중에 계산되는 gradient에 제곱을 하여 계속 더해준다. update할 때 update term을 앞서 계산한 gradient 제곱항으로 나눠준다. 이때, small dimension에서는 gradient의 제곱 값 합이 작다. 따라서, 이 작은 값이 나눠지므로 가속도가 붙게 되는 것이다. 반면에 large dimension에서는 반대의 현상이 일어나 속도가 줄어들게 된다.

 

AdaGrad의 step size가 점점 감소하게 되는데 이는 convex case에서는 좋으나(점점 느린속도로 Minima에 수렴하므로) 그렇지 않다면 문제가 될 수 있다. local minima에서 멈출 수 있기 때문이다.

 

 

 

RMSProp

 

RMSProp에서는  AdaGrad의 gradient 제곱 항을 그대로 사용한다. 하지만 누적만 시키는 것이 아니라 기존의 누적값에 decay_rate를 곱해준다. 따라서,  AdaGrad와 같이 step 의 속도를 증가 감소 시킬 수 있으나 AdaGrad와 달리 속도가 점점 줄어드는 문제를 해결할 수 있다.

 

 

RMSProp은 각 차원마다 상황에 맞게 적절하게 궤적을 조정한다. 위에서 사실 AdaGrad도 초록색으로 존재하나 RMSProp과 궤적은 비슷하나 속도가 느리기 때문에 RMSProp에 가라져 보이지않는다. 일반적으로 adagrad는 nerual network를 학습할 때 사용하지 않는다.

 

 

두 해결 방안을 모두 고려한 방안 :: Adam 


adam (almost) 

Adam은 RMSProp(second squred gradients) + momentum와 비슷하다고 생각하면 편하다. 

 

이 방식에도 문제는 존제한다. second moment을 0으로 주게 되면 초기 step이 매우 커지게 되는데 이는 손실함수에 의존하여 계산에 의한 것이 아니라(가파르기 때문에 계산된 값이 아니라) 초기값을 지정하기 위한 인공적인 값이므로 좋지 못하다.

 

이를 해결하기 위해 보정하는 항(bias correction term)을 추가해야 한다.

 

 

이것이 완전한 Adam의 형태이다. 

 

 

learning rate

 

 

learning rate 적절하게 고르는 것은 하이퍼파리미터 튜닝을 하는 과정이므로 적절한 값을 여러 시도 끝에 구할 수 있다. 적절한 값은 아래의 그래프에서 빨간색 선과 같이 나타날 때이다. 이후에 하이퍼파라미터 튜닝 과정으로 step decay learning rate 방법이 존재한다. 이 방법은 Epoch의 증가에 따른 loss의 감소가 줄어들 때 learning rate를 감소시켜서 minimum에 더 다가가기 쉽도록 해주는 방법이다.

 

 

 

Newton step :: 2차 근사를 이용한 방법

 

Newton step은 앞에서 진행했던 1차 미분에 비해 훨씬 더 효율적이다.

 

하지만 Deep learning에서 Newton step을 사용할 수 없다. 그 이유는 Hessian matrix는 N x N행렬인데 (N은 network의 파라미터 수이다) 파라미터의 수가 증가할수록 행렬의 크기가 기하급수적으로 커지므로 메모리도 부족해지고 역행렬도 구할 수 없기 때문이다. Hessian matrix에 근사시켜서 적용한 방법으로 quasi newton method과 L-BFGS방법이 존재한다.

 

 

앞의 내용들을 요약하자면

 

- 실제로는 Adam을 가장 많이 쓴다.

- full batch update가 가능하고 stochasticitiy가 적은 경우 L-BFGS가 좋은 선택이 될 수 있다.

 

 

 

위의 Optimization 을 통해서 Training error을 줄이는데 성공하였다. 다음 목표는 train/test의 error를 줄이는 것이다. 즉, 한번도 보지 못한 데이터에 대해서 성능을 올리는 방법을 알아보자.

 

 

모델 앙상블


가장 빠르고 쉬운 길은 Esemble 모델을 사용하는 것이다. 이 방법은 여러 개의 모델을 독립적으로 학습시키는 것이다. 이때 결과는 모델 결과의 평균을 이용한다. 모델의 수가 늘어날수록 overffiting이 줄어든다. 이 방법이 일반적인 모델 앙상블 방법이다.

 

 

더 창의적 모델은 학습 도중 중간 모델을 저장하여(training 과정 중에 snapshot을 찍어) test time에서 snapshot의 예측값들을 평균내서 사용하면 된다.

 

다른 독특한 방법으로 learning rate를 매우 높혔다가 낮췄다가를 반복하는 방법이 존재한다. 이를 통해 손실함수에 다양한 지역에 수렴할 수 있도록 해주는 것이다.

 

이러한 앙상블 기법들은 모델을 한 번만 Train 시키더라도 좋은 성능을 얻을 수 있는 방법들이다. 

 

 

 

 

앙상블이 아닌 단일 모델의 성능을 향상시키기 위해서는 어떻게 해야할까?

Regularization

drop out


Drop out은 모든 노드를 사용하는 것이 아니라 일부만 선택해서 하는 방법이다. Drop out은 FC layer에서 사용하지만 가끔씩 conv layer에서도 볼 수 있다.

 

 

Drop out이 좋은 이유는 특징들 간의 상호작용을 방지한다. 고양이를 분류하는 네트워크를 생각해보자.

 

 

Dropout을 적용하게 되면 네트워크가 일부 features에만 의존하지 못하게 해주고 다양한 features가 골고루 이용할 수 있게 해준다. 즉, Drop out이 overffiting을 어느 정도 막아준다.

 

 

 

Drop out을 사용할 경우 입력으로 z라는 변수가 추가된다. z라는 변수는 랜덤성을 나타내며 random dropout mask이다. 

 

 

Drop out은 결과를 일관적으로 내보내기 위해서 average out방법을 사용한다. 위에서와 같이 x노드와 y노드가 만들 수 있는 경우의 수에 확률을 곱해주어 기댓값을 구해주는 방법이다. 이를 통해 test time에서 이 모델을 통해 동일한 이미지를 넣어주면 동일한 판단을 할 수 있게 된다. (stochasticity를 제거해준다.)

 

 

 

Drop out & Batch Normalization

 

 

Batch Normalization은 Mini batch로 하나의 데이터가 샘플링 될 때 매번 서로 다른 데이터들과 만나게 된다. Test time에서는 정규화를 (Train time에서와 같이)mini batch 단위가 아닌 global 단위로 수행함으로써 stochasticity 를 평균화시킨다. 즉, Train time에는 stochasticity(noise)가 추가되지만 Test time에서는 전부 평균화되는 것이 Dorpout 방법과 유사한 것이다. 실제로 BN을 사용하면 drop out을 사용하지 않는다.

 

 

 

data augmentation


 

train time에 이미지를 무작위로 변환시켜 학습하는 것이다. 수직적으로 대칭시킨다던가, 다양한 사진으로 자르는 등 다양한 방법들을 적용할 수 있다. 

 

 

color jittering PCA의 방향을 고려하여 color offset을 조절하는 방법이다. 더욱 데이터에 근거한 방법이다. 

 

 

 

DropConnect & Fractional Maxpooling & Stochastic Depth


DropConnect

 

 

DropConnect은 activation이 아닌 weight matrix를 임의적으로 0으로 만들어주는 방법이다. 

 

 

 

Fractional Maxpooling

 

 

train에서는 Fractional Maxpooling 연산을 수행할 지역이 임의로 설정된다. test에서는 stochasticity를 고정시켜주기 위해 pooling regions를 고정시켜버리거나 여러 개를 만든 후 averaging over시킨다.

 

 

 

Stochastic Depth

 

 

Train에서는 임의로 레이어를 건너뛰고 test에서는 전부 사용하는 방법이다.

 

 

 

Transfer learning


데이터셋의 양이 부족할 경우 사용한다.

 

 

일반적인 절차는 마지막 FC layer를 초기화 시켜 작은 데이터셋에 맞추는 것이다.

 

fine tunning: 세부적인 튜닝 대부분 그대로 두되 하이퍼파라미터만 조금씩 조절해준다. 이 부분에서 기존의 learning rate보다 낮춰서 학습한다.

 

 

 

요약


Optimization: training loss 를 개선하는 것

Regularization: test data에서의 성능을 향상시킴

transfer learning: training data가 적을 경우에

 

 

 

 

 

2021.02.15.월

 

 

-히비스서커스-

728x90