31. Weight 초기화 잘해보자 (lec 10-2)

이번 동영상은 Deep Learning을 잘 하는 두 번째 방법인 "초기화를 잘 해보자"에 대해 얘기한다.


backpropagation에서 layer를 따라 진행할수록 값이 사라지는 현상은 ReLU를 통해 해결할 수 있었다. 더욱이 그 이후에 ReLU를 응용한 다양한 방법을 비롯해서 창의적인 여러 가지 방법이 존재하는 것도 보았다.


hinton 교수님이 정리한 4가지 중에서 세 번째. 지금까지 우리는 잘못된 방법으로 weight을 초기화했다.


똑같은 코드에 대해서 난수로 초기화를 하기 때문에 ReLU에 대해서도 2가지 결과가 나온다. 어떤 초기값을 선택하느냐에 따라 매번 달라지고, 성능이 좋기도 하고 나쁘기도 하다.


weight에 대한 초기값을 모두 0으로 설정한다면? Deep Learning 알고리듬은 전혀 동작하지 않을 것이다.

그림 왼쪽에 있는 weight에 해당하는 W가 0이 된다면 어떤 일이 벌어지겠는가? W와 x를 곱셈으로 연결하고 있는데, W가 0이 된다면 x의 값은 아무런 의미가 없다. 즉, x의 값이 무엇이건 0이 되고, 지금까지 거쳐온 layer의 값들 또한 모두 무효가 된다.


전체 초기값을 0으로 주는 것은 안 된다고 말씀하시면서, 이 분야는 아직 해야할 것이 많다고 하신다. 2006년 hinton 교수님이 발표한 Restricted Boltzmann Machine(RBM)이 이 문제를 해결했다. 현재는 RBM보다 쉽고 좋은 방법들도 존재한다. 그러나, hinton 교수님께서 좋은 초기화를 할 수 있다는 길을 제시한 것은 틀림없다.


RBM의 구조를 보여주는 그림이라고 하는데, 처음 봐서는 잘 모른다. Restriction이란 단어를 붙인 것은 같은 layer 안에서 어떠한 연결도 존재하지 않기 때문이다. 단지 2개의 layer에 대해서만 x 값을 사용해서 동작하고 y 값도 사용하지 않는 초기화 방법이다.


RBM은 현재 layer와 다음 layer에 대해서만 동작한다. (forward) 현재 layer에 들어온 x값에 대해 weight을 계산한 값을 다음 layer에 전달한다. (backward) 이렇게 전달 받은 값을 이번에는 거꾸로 이전(현재) layer에 weight 값을 계산해서 전달한다.

forward와 backward 계산을 반복해서 진행하면, 최초 전달된 x와 예측한 값(x hat)의 차이가 최소가 되는 weight을 발견하게 된다.


RBM은 앞에 설명한 내용을 2개 layer에 대해 초기값을 결정할 때까지 반복하고, 다음 번 2개에 대해 다시 반복하고. 이것을 마지막 layer까지 반복하는 방식이다. 이렇게 초기화된 모델을 Deep Belief Network라고 부른다. 신뢰할 수 있는 초기값을 사용하기 때문에 belief라는 단어가 들어갔나 보다.


이러한 과정을 pre-training이라고 부른다. 첫 번째 그림에서 첫 번째 layer의 weight을 초기화하고, 두 번째 그림에서 두 번째 weight을 초기화하고, 세 번째 그림까지 진행하면 전체 layer에서 사용하는 모든 weight이 초기화된다. (앗, 3장의 그림인데, 마치 한 장처럼 붙어보일 수도 있겠다.)


이렇게 해서 네트워크 전체의 weight이 초기화 되었다.


제대로 초기화해서 학습을 시작하면 학습 시간이 얼마 걸리지 않는다. 그래서, 학습(learning)이라고 부르지 않고 Fine Tuning이라고 부른다. 그만큼 초기화가 중요하다는 뜻이다.


그런데, 설명이 긴 만큼 구현하는 것도 쉽지 않을 건 틀림없다. 좋은 소식이 있다. 굳이 복잡한 형태의 초기화를 하지 않아도 비슷한 결과를 낼 수 있다고 한다.

2010년에 발표된 xavier 초기화와 2015년에 xavier 초기화를 응용한 He 초기화가 있다. 이들 초기화 방법은 놀랄 정도로 단순하고, 놀랄 정도로 결과가 좋다.

  xavier(재비어) - 다음 영어사전에 보면 사비에, 자비에라는 남자의 이름으로 나온다.


아..! 코드가 놀랄 정도로 단순하다. 그냥 한 줄로 정리된다. 입력값을 fan-in, 출력값을 fan-out이라고 부른다. 홍콩 중문대 박사과정에 있던 he가 2015년에 이 방식을 사용해서 ImageNet에서 3% 에러를 달성했다.

  xavier - 입력값과 출력값 사이의 난수를 선택해서 입력값의 제곱근으로 나눈다.
  he - 입력값을 반으로 나눈 제곱근 사용. 분모가 작아지기 때문에 xavier보다 넓은 범위의 난수 생성.


스택 오버플로우에 있는 코드로, 구글링을 해서 쉽게 코드를 확인할 수 있다. 왠지 간단한 코드지만, 직접 만들 경우 조금 틀릴 수 있지 않을까, 하는 고민이 들었다. (아쉽지만, 언제인지 모르게 텐서플로우에 xavier 초기화 코드가 포함되었다.)

  http://stackoverflow.com/questions/33640581/how-to-do-xavier-initialization-on-tensorflow


성능 비교. xavier 초기화가 좋다고 해서 자랑해야 하는데, 더 좋은 초기화 방법들이 수두룩하다. 그래도 간단한 초기화만으로 성능을 획기적으로 끌어올릴 수 있다는 사실은 여전히 놀랍다.


이 분야는 아직도 연구 중이다. 잠깐 찾아봤는데, 앞에 언급된 초기화를 사용해서 다양한 초기화 방법이 여러 논문으로 발표되고 있다. 모두 비교한 방법보다 좋았기 때문에 발표하는 것일텐데.. 이 부분은 최신 연구동향에 신경을 써야할 것 같다. 최신의 발표되는 논문을 가끔 살펴보는 정도로.


hinton 교수님께서 제안한 좋은 초기화에 대해 이번 동영상에서 설명했다. sigmoid를 개선한 ReLU 사용 및 RBM 방식을 사용한 좋은 초기화. 여기에 xavier와 he 초기화도 포함됐다.