Sunwoo Kim's Computer Vision, Machine & Deep Learning Blog search

CS231n-Lecture07(training neural network 2)

|

목차

저번 강의 때 배웠던 부분을 살펴보자.

먼저, 일부 활성화 함수에 대해서 살펴보는 시간을 가졌었다.

그리고 가중치 초기화의 중요성에 대해서도 살펴보았다.

data processing에 대해서도 간략히 살펴보았으며, zero centered하게 데이터를 정규화 시켜주는게 중요하다고 하였었다.

네트워크를 훈련 시키면서 내부 공변량 이동(internal covariant shift)가 일어남으로 이를 방지하기 위한 방법인 배치 정규화(batch normalization)방법에 대해서 살펴보았다.

그 후, 훈련을 시킬 때, 적절한 하이퍼파라미터가 무엇인지 찾기 위하여 이를 바꾸어 나가면서 그래프를 살펴보는 시간을 가졌었다.

적절한 하이퍼 파라미터를 고르기 위하여 1,2,3과 같은 정해진 구역보다 1.1, 2.5 와 같은 지점에도 최적의 파라미터 값이 존재할 수 있으므로, 구간 내 랜덤 탐색이 최적의 파라미터를 찾기 더 좋은 방법이라고 배웠다.

Fancier optimization

최초 초기화한 가중치 지점에서 최적의 파라미터 지점까지 경사 하강법을 통하여 최적화를 진행하였다.

SGD를 사용할 때, 한 방향으로는 그라디언트가 빠르게 바뀌지만(즉, 그라디언트가 큰 방향과 작은 방향의 크기의 비율이 높다면), 다른 방향으로는 느리게 바뀐다면 경사 하강법은 어떻게 움직일까? 바로, shallow dimension(일부 몇개의 차원만을 의미하는 것 같다.)에서 매우 느리게 업데이트되며, 가파른 방향으로 진동(jitter)한다고 한다. 지그재그로 업데이트되 기 때문에 속도가 더 느려진다. 이러한 문제는 고차원에서 많이 발생하는 문제라고 한다.

SGD에서 문제가 되는 점은 무엇을까? 바로 local minima와 안장점(saddle point)이다. local minima는 모든 방향의 그라디언트가 지역적으로 최소인 지점이고, saddle point는 한쪽으로는 로스가 증가하고 한쪽으로는 로스가 감소하는 방향에서의 극점(기울기가 0)인 지점이다. 저차원에서는 local minima 가 saddle point에 비해서 더 자주 나타나지만, 고차원으로 갈수록 saddle point와 같은 양상이 더 많이 보이게 된다.쉽게 생각해서, 100만 차원이 존재할때, 100만개의 방향이 지역적으로 모두 최소인것보다, 일부 방향이 saddle point에 빠지는 것이 훨씬 가능성이 높을것이다.

SGD의 또다른 문제점은 그라디언트가 미니 배치로부터 구해진다는 것이다. 그렇기 때문에 위 그림과 같이 검은색 부분으로 보이는 데가 있는데, 불규칙한 진동을 보이면서 최적점에 다가가고 있는 모습이다. 이것은 노이즈 때문에 발생하는 문제점이다.

그렇다면, local minima 및 안장점에서 생기는 문제가 미니 배치를 사용했기 때문일까? 그것은 아니다. 좀 더 안정적으로 학습이 진행될 뿐, 여전히 발생하는 문제이다. 그렇다면 이 문제를 어떻게 해결할까?

해당 문제를 해결하기 위하여 SGD에 모멘텀(momentum)이라는 것을 추가하였다. 이것은 일반물리에서 가속도(acceleration)의 개념과 비슷하다. 즉 기존의 그라디언트는 그대로 구하는데, 그것이 속도개념이 되어서, 새로운 속도 개념이 되고, 기존의 속도의 반영 비율을 나타내는 것이 로(rho)이다. 크면 클수록 기존의 속도를 반영하겠다는 것을 의미한다. 그리고 그것을 다시 학습률에 곱해서 가중치를 업데이트 하는 방식이다.

모멘텀은 local minima 및 saddle point에 빠졌을 때 벗어나는데 도움을 주는데, 그 때 도움을 주는것이 기존의 속도를 반영하는 것이다. 현재 포인트에서 그라디언트가 0이 나왔을 지라도 기존의 속도를 반영하는 부분 때문에, 일정 포인트를 더 이동할 수 있게 된다. 이로써 극점에 빠져있을 확률을 줄여준다.

오른쪽 그림을 보면, 그라디언트가 가파른 방향으로 기존의 방향까지 추가해서 이동하기 때문에 기존의 SGD보다 더 빠르게 이동하는 모습을 볼 수 있다.

모멘텀을 주는것에도 여러가지 방식이 있는데 이번세 살펴볼 모멘텀은 네스테로브 모멘텀(Nesterov momentum)이다. 위 식을 보면, $\nabla f(x_t + v_t)$인 점이 특이하다는 것을 알 수 있다. 나는 이식을 보고 미리 그 곳을 가보고 갈 방향을 정한다는 느낌이 들었다. 간단히 말하자면 다음과 같다. 원래 우리는 $x_t$지점에서 그라디언트를 구하고 그 쪽 방향으로 더 이동한다. 그래서 $x_t + v_t$지점에 도달했다고 하자. 그런데 막상 이 지점에서 $\nabla f(x_t + v_t)$를 구하고 보니, 얕은 기울기 혹은 극점 혹은 증가하는 지점이었던 것이다. 즉 안 좋은 지점에 도착한 것이다.

그러므로 미리 그 지점의 그라디언트를 가져와서 반영하는 것이다. $v_{t+1} = \rho v_t - \alpha \nabla f(x_t + \rho v_t)$의 식에 이 개념을 대입하면, 미리 가보고, 그라디언트가 양수가 나온다면 속도가 줄어, 그 방향으로 덜 가게 되고, 음수가 나온다면 더 내려가도 된다는 뜻이므로 더 가파르게 다음 방향쪽으로 이동할 수 있게 된다.

위 슬라이드를 보면 네스테로브 모멘텀이 다른 방식에 비해서 빠르게 이동하는 모습을 볼 수 있다. (연두색이 없어진것 처럼 보이지만, 빨간색과 겹쳐져 색이 진해졌다…)

다음으로 설명할 것은 에이다(혹은 아다) 경사하강법(AdaGrad, 아다그라드)방법이다. 아다그라드는 변수의 업데이트 횟수에 따라 학습률(Learning rate)를 조절하는 옵션이 추가된 최적화 방법이다. 여기서 변수란 가중치(W) 벡터의 하나의 값(w[i])을 말한다. 아다그라드는 많이 변화하지 않은 변수들은 학습률(step size)를 크게하고, 반대로 많이 변화한 변수들에 대해서는 학습률을 적게한다. 이는 많이 변화한 변수는 최적값에 근접했을 것이라는 가정하에 작은 크기로 이동하면서 세밀한 값을 조정하고, 반대로 적게 변화한 변수들은 학습률을 크게하여 빠르게 loss값을 줄인다.

다음으로 살펴볼 optimizer는 RMSProp이다. RMSprop은 아다그라드에서 G(t)가 무한히 커지는 것을 방지하기 위해 나온 방법이라 한다. RMSprop은 지수이동평균을 이용한 방법이다. 지수이동평균은 지난 값과, 현재값에 $\alpha, (1-\alpha)$라는 가중치를 주어 계산 하는 방식이다. 이렇게 되면, 예전 값에는 $(1-\alpha)^{n}$이 곱해져, 결과적으로 업데이트가 되면 될 수록 영향력이 적어지게 된다. 이러한 $\alpha$를 forgetting factor, 혹은 decaying factor (여기서는 decaying rate)이라 불린다.

즉 위 슬라이드를 보면 아다그라드에서 바뀐점은 G(t)가 지수이동평균을 이용하여 더해진다는 점이다.

RMSProp이 SGD보다는 빠르게,SGD+Momentum보다는 보다 안정적으로 최적값에 도달해가는 모습을 볼 수 있다.

Adam은 RMSProp과 momentum를 합쳐놓은 방법이다. first momentum과 second momentum을 보면 각각 어느 부분이 그 역할을 하는지 알 수 있다. 하지만 위 슬라이드에서 Adam을 사용할 때, 첫 번째 가중치를 업데이트 할 때 나타나는 문제점이 무엇인지에 대해서 물어보고 있다. 그것은 바로 두 모멘텀이 초기에 0으로 초기화 되었을 때 문제가 나타난다는 것이다. 첫 번째 업데이트시 거의 0에 가까운 값으로 업데이트 되며(0으로 편향이 발생) 이것은 학습의 저하를 초래한다는 것이다.

그래서 0으로 편향되는 것을 막기 위하여(bias correction) 각각 일정 값으로 나눠준다고 한다.

그림에서 보는것과 같이 Momentum과 RMSProp의 모습과 비슷한 형태로 학습하는 것을 볼 수 있다.

여태까지 다룬 모든 optimizer들은 learning rate를 필요로 한다. 그렇다면 어떤 learning rate가 최적의 learning rate가 될 수 있을까?

사실 이 질문은 tricky하다고 한다. 왜냐하면 처음에 높은 learning rate을 설정한 다음, learning rate을 decaying(하락) 시키면 된다는 것이다. 지수적으로 하락시키거나, 1/t씩 하락시키는 방법이 있다고 한다. 다른 방법들도 있을 것이다.

learning rate가 일어난다면 learning loss curve는 다음과 같이 바뀌게 될 것이다. 이러한 weight decay는 SGD방법에서 더 많이 쓰이며, Adam에서는 잘 쓰이지 않는다고 한다. (아무래도 가중평균이 적용되어 조절해주는 부분이 있어서 그런게 아닐까? 라고 짧게 생각해본다…)

그것을 아는가? 우리아 여태까지 살펴본 optimizer는 모두 first-order optimizer다 그것이 무슨소리냐면, 한번 미분한 가중치만 반영하는 optimizer만 살펴보았다는 것이다. 위 슬라이드를 보자. 한번 미분을 하게되면, 그 그라디언트를 따라 이동하게 되는데, 그럴경우 우리는 많은 범위의 이동을 할 수가 없다 왜냐하면 근사의 한계가 있기 때문이다. 우리가 대학교에 들어오자마자 배웠던 미적분학에서 등장한 테일러 급수를 떠올려보자. 추가되는 항이 많아질수록, 즉, 고차항이 많아질수록 근사를 정확히 할 수 있었다.

이러한 관점에서 second-order optimizer가 등장하였다. 위 슬라이드에서 볼 수 있듯이, 더욱 정확한 근사를 통하여 많은 범위를 움직일 수 있게 된다. 일차 미분을 할 때, 자코비언이 필요했다면, 이차미분의 행렬도 불리는 이름이 있는데 그것이 바로 헤세 행렬(Hessian matrix)이다.

이차 테일러 급수가 위 슬라이드에 나와있다. $1/2 (\theta - \theta_0)^T H (\theta - \theta_0)$인 부분이 이차항을 나타내며 계산해보면 qudaratic form을 나타내게 된다. 이 파라미터 업데이트 방식은 뉴턴 방법(Newton method)라고 한다. 여기서 식을 보면 헤세 행렬의 역행렬을 사용하는데, 이 때 시간복잡도가 엄청난 것을 볼 수 있다. 가중치의 차원이 몇 백만 차원인 것을 생각해보면 이것을 사용하지 않는게 좋을 것이라는 생각이 바로 든다.

이를 보완한 방법이 콰시-뉴턴 방법(Quasi-Newton methods)라고 한다.

우선 여기서는 full batch에서 잘 작동하고, mini-batch 에서는 잘 작동하지 않는다는 점만 알아두자.

실제 에서는Adam이 모든 케이스에서 거의 기본적인 optimizer로 최초에 사용된다고 한다.

지금 까지 트레이닝 시에 사용되는 optimizer에 대해서 살펴봤다. 그런데 가장 중요한 것은 트레이닝이 아니다. 바로 아직 보지 않은 데이터(unseen)데이터에 대한 정확도이다. 그렇기에 train dataset의 정확도와 validation set과의 차이가 적은 모델이 좋은 모델이라고 할 수 있다. 그렇다면 이 둘의 차이는 어떻게 줄일 수 있을까?

그 방법중 하나로 강의에서는 모델 앙상블(Model ensembles)을 소개한다.여러 종류의 모델을 독립적으로 훈련 시킨후, 그 파라미터를 평균을 내어 적용하는 것을 뜻한다. 약 2%정도의 성능 향상을 얻을 수 있다. 아무 고민하지 않고, 모델만 주구장창 돌려서 이 정도 성능이면 아주 좋은 것 같다.

Regularization

그렇다면, 여러 모델을 사용하는게 아니고, 단일 모델만을 사용할 때, 성능을 높힐 수 있는 방법은 무엇이 있을까? 강의에서는 그 방법중 하나인 규제(regularization)에 대해서 소개한다.

Add term to loss

이 슬라이드는 우리가 예전에 보았던 슬라이드일 것이다. CS231n-Lecture03 에서 L1, L2 regularization의 원리에 대한 간략한 설명을 한 적이 있다.

드랍아웃(Dropout)

포워드 패스를 진행할 떄, 일정확률로 랜덤하게 특정 뉴런의 값을 0으로 만드는 것이다. 보통 50%의 확률이 적절하다고 한다.

그렇다면 어떻게 이것이 좋은 아이디어가 될 수 있을까? 첫 번째로, 불필요한 표현을 제거하여 그런 뉴런들의 상호작용을 줄여준다는 것이다.

두 번째 관점으로는 드랍아웃 자체로 앙상블의 효과를 낼 수 있다는 것이다. 왜냐하면 그 때 마다 제거되는 뉴런이 다르기 때문에, 그 자체로 하나의 독립적 네트워크가 될 수 있다는 뜻이다.

그렇다면 드랍아웃 적용시, 테스트 때는 어떻게 헤야할까? 우리가 아주아주 사랑하는 평균을 이용하면 된다. 그렇다면 위의 식과 같이 인테그럴을 이용하여 식을 표현할 수 있을텐데, 드랍아웃 되는 모든 경우의수를 더해서 평균을 낸다는게 사실상 불가능 하다. 그렇다면 어떤 방법을 사용해야 할까?

생각해보면 경우의 수는 4가지 밖에 없다. 위의 슬라이드 처럼 말이다. 여기서는 빨간 글씨로 드랍아웃 확률을 그냥 곱해주면 된다고 나와있다. 위 슬라이드의 식을 조금더 풀어쓰면, $p^2(a+b) + p(1-p)(a+0)+p(1-p)(0+b)+(1-p)^2(0+0) = (p^2 + p(1-p))(a+b) = p(a+B)$가 나오기 때문이다. 그렇기 때문에 어떤 드랍아웃 확률을 쓰던 테스트 시에는 p를 곱해주면 되는 것이다.

regularization의 훈련시와 테스트시 적용의 일반적인 패턴에 대해서 설명한다. 즉, 훈련 시키고 테스트시에는 훈련시에 고정된 어떤 값을 이용한다는 뜻이다. 그 이유는 CS231n-Lecture06의 배치 정규화 부분을 살펴보자.

규제의 다른 방법으로 데이터 증강(data augmentation)이 있다. 즉 기존의 훈련 데이터에 약간의 변형을 가하여 데이터를 변형하는 것이다.

위의 슬라이드들은 규제의 일반적인 패턴들을 설명하고 있다.

일반적인 경우로는 BN으로도 충분하지만 그렇지 않을경우 dropout도 고려해보라고 강의에서 말하고 있다.

Transfer Learning

우리는 항상 딥러닝 네트워크를 훈련시키기 위하여 엄청나게 큰 데이터셋이 필요할까? 그렇지 않을 수도 있다.

transfer learning을 이용하면 된다. IMAGNET으로 우선 네트워크를 한 번 훈련 시킨다. (여기서 부터 이미 큰 데이터가 필요한게 아닌가?…. 하지만 다음 우리가 훈련시킬 데이터는 그렇지 않으니까.) IMAGNET으로 훈련시킨 가중치는 손쉽게 온라인에서 가져올 수 있다. 그렇다면 우리가 훈련시키고 테스트를 원하는 데이터셋이 CIFAR-10 같이 10class인 small datset이면 두 번째와 같이 마지막 FC layer만 다시 훈련시켜준다. 그 밑에 레이어 들의 가중치는 고정시킨다.

만약에 더 큰 데이터셋을 훈련시킨다면, 그 조금 더 밑의 FC layer까지 훈련시키도록 한다.

이런 방법은 우리가 앞서 배웠던 CNN의 특징에 기인한다. 즉 네트워크의 끝으로 갈수록 조금 더 high level의 feature를 가지게 된다. 그 말은 밑에 레이어들은 물체들의 일반적인 특징들을 가지고 있다는 것이다.

transfer learning은 아주아주아주아주 자주 사용되는 기법이다. (거의 매번?)