티스토리 뷰
Vanishing Gradient 문제 해결 방법
1. LeLU
2. 초기값을 잘 줘야 한다.
같은 LeLU를 줘도 초기값에 따라 다음과 같은 차이가 생기기도 한다.
초기값(w)을 모두 0으로 줘보자.
어떤 문제가 발생할까?
x를 가지고 f를 구한다음 다시 propagation을 이용해 역으로 구하는데 x의 미분값이 0이면 앞에 있는 모든 미분값이 0이 되어버린다.
초기값을 매우 현명하게 줘야만 한다.
1. 초기값을 모두 0을 주면 안된다. (학습 전혀안됨)
2. 2006년 'A Fast Learning Algorithm for Deep Belief Nets" by Hinton 에서 어떻게 초기화 시키는 것이 좋은지 방법을 제시. - Restricted Boatman Machine (RBM) 지금은 사용하지 않지만 자주 언급하므로 알아둘것.
다음은 RBM구조이고, 입력단과 출력단으로만 구성된 네트워크이다.
어떤 입력값이 있을때 어떻게 구성되나 알아보자.
두 가지 operation을 가지는데, 이 operation의 목적은 입력을 재생산 해내는 것이다.
첫 번째는 Forward한 방법으로 각 데이터 셋들이 가중치의 곱으로 값을 만들어 낸다. 값의 크기에 따라 activation이 발생하기도 하고 발생하지 않기도 한다.
두번째는 Backward로 똑같은 일을 반대로 한다. 아까 받아놨던 값들을 weight는 그대로 해서 역으로 쏴준다.
이렇게해서 처음 쏴줬던 dataset의 값들과 역으로 쏴준 값을 비교한다. 두 값의 차가 최소가 되도록 weight를 조정하는 것을 RBM이라고 한다.
또, forward를 auto encoder, backward를 auto decoder라고도 한다.
이거가지고 어떻게 하지라고 생각할 수 있을까?
레이어들이 있으면 인접해있는 2개의 레이어만 보고 위의 과정을 시행을 해서 weight을 결정해 준다. 다음 Deep Belief Network를 예제로 보자.
PRE - Training에서는 label도 필요없다. x값만 있으면 된다.
다음과 같이 2개의 layer씩 짝지어 weight들을 결정해준다. 이렇게 다 결정해 준 값을 초기화 값으로 사용한다.
그 다음 Fine Tunning에서는 x 데이터를 놓고 labels을 놓고 학습시킨다. (이미 weight이 잘 학습되어 있어 tunning이라고 말한다.)
그런데 RBM을 굳이 안써도 된다.
매우 simple한 초기값을 주는 방법을 알아냈다.
- Xavier initialization(2010): 몇개 입력이고 몇개 출력인지에 비례관계로 초기값을 준다.
- He's initialization(2015): 위의 방법을 좀 더 개선 (RBM보다 비슷 혹은 더 잘 나오더라)
>imagenet의 오류를 3%미만으로 떨어뜨리게 한 방법
# Xavier initialization # Glorot et al. 2010 W = np.random.randn(fan_in, fan_out)/np.sqrt(fan_in)
# He et al. 2015 W = np.random.randn(fan_in, fan_out)/np.sqrt(fan_in/2)
|
prettytensor implementation (구현해 놓은 것)
def xavier_init(n_inputs, n_outputs, uniform=True): """Set the parameter initialization using the method described. This method is designed to keep the scale of the gradients roughly the same in all layers. Xavier Glorot and Yoshua Bengio (2010): Understanding the difficulty of training deep feedforward neural networks. International conference on artificail intelligence and statistics. Arg: n_inputs: The number of input nodes into each output. n_outputs: The number of output nodes for each input. uniform: If true use a uniform distribution, otherwise use a normal. Returns: An initializer. """
if uniform: # 6 was used in the paper. init_range = math.sqrt(6.0 / (n_inputs + n_outputs)) return tf.random_uniform_initializer(-init_range, init_range) else: # 3 gives us approximately the same limits as above since this repicks # values greater than 2 standard deviations from the mean. stddev = math.sqrt(3.0 / (n_inputs + n_outputs)) return tf.truncated_normal_initializer(stddev=stddev) |
이 정도 방법만 잘 사용할 줄 알아도 초기화할 수 있다.
이 분야가 연구가 많이 이루어지고 있는 분야이다. 어떤게 최고의 초기값을 줄 수 있을지 아직 모른다.
데이터마다 다르므로 여러가지 사용해보고 가장 잘 되는 방법 사용할 것.
'beginner > 파이썬 딥러닝 기초' 카테고리의 다른 글
레고처럼 넷트워크 모듈을 마음껏 쌓아 보자 (0) | 2019.05.08 |
---|---|
Dropout과 앙상블 (0) | 2019.05.08 |
XSigmoid 보다 ReLU가 더 좋아 (0) | 2019.05.08 |
Tensor Board로 딥네트웍 들여다보기 (0) | 2019.05.07 |
XOR을 위한 텐서플로우 딥네트웍 (0) | 2019.05.07 |