😺

[cs231n] 6. Training Neural Networks Part 1

Activation Function

주로 사용되는 Activation Function에는 아래의 6가지가 있다.

Sigmoid

σ(x)=11+ex\sigma(x) = \cfrac {1}{1+e^{-x}}
가장 인기있게 사용되었던 함수이다.

Sigmoid의 단점

1.
Gradient가 0이 되는 문제가 발생한다. Gradient Kill, Gradient Vanish입력값이 매우 크거나 매우 작은 경우
2.
Output이 zero-centered 이지 않다.
Zero-centered 되지 않는 Output의 경우는 위 그림과 같이 학습 속도를 저하시킬 수 있다.
3.
지수함수는 계산 값이 비싸다.
따라서 현재는 더이상 사용하지 않는다.

Hyperbolic Tangent

σ(x)=tanh(x)\sigma(x) = {\rm tanh} (x)
Sigmoid Function의 Non zero-centered 문제를 해결하였지만 Gradient Kill의 문제는 해결하지 못하여 사용하지 않는다.

ReLU

f(x)=max(0,x)f(x) = {\rm max}(0,x)
많이 사용하는 함수이다.

ReLU의 장점

1.
0보다 큰 값에 대해서는 Gradient Kill이 발생하지 않음
2.
계산이 용이함. Sigmoid나 tanh보다 6배정도 빠르다.
3.
Biologically Plausible하다.

ReLU의 단점

1.
Zero-centered하지 않다.
2.
0보다 입력값이 작으면 Gradient Kill이 발생한다.

Leaky ReLU

f(x)=max(0.01x,x)f(x) = {\rm max}(0.01x, x)
0보다 작은 값에서도 Gradient Kill이 발생하지 않는다.

Parametric Rectifier (PReLU)

f(x)=max(αx,x)f(x) = {\rm max}(\alpha x, x)
Backpropagation을 통해 α\alpha를 학습해서 사용한다.

ELU

f(x)=α(ex1)  (x0),  x  (x>0)f(x) = \alpha (e^x -1)\ \ (x \leq 0), \ \ x\ \ (x >0)
Noise에 Robustness를 갖지만, 계산이 비싸고 x가 많이 작으면 여전히 Gradient Kill이 일어난다.

Maxout

f(x)=max(w1Tx+b1,w2T+b2)f(x) = {\rm max}(w_1^Tx+b_1, w_2^T + b_2)
Parameter가 2개라는 단점이 있음

결론

대부분 ReLU를 씀
가끔 Leaky ReLU나 Maxout이나 ELU등을 쓰기는 함
진짜 가끔 tanh를 쓰지만 기대는 하지마세요
Sigmoid는 안써

Data Preprocessing

zero-centered
평균을 조정하는것
이미지에서는 zero-centered만 보통 쓴다.
normalize
Scale을 조정하는 것
이미지는 normalize하면 feature가 날아가니까 하지 않는다.
decorrelated data
whitened data
→ 이해를 못했다... 수학 잘하고싶다...

Zero Centered Preprocessing

AlexNet

[32,32,3] Array에서 Mean 값을 전부 빼준다.

VGGNet

RGB각 채널에 대해서 Mean 값을 전부 빼준다.

Weight Initialization

W를 어떻게 초기화 할것인가에 대한 논의
1.
W를 가우시안 분포를 따르는 작은(0.01) 랜덤 숫자로 초기화
NN의 깊이가 깊어질수록 표준 편차가 0으로 수렴해 학습이 일어나지 않게 된다.
2.
랜덤 숫자의 크기를 키워서(1) 초기화
값들이 점점 -1이나 1로 수렴해서 Gradient가 0이됨

Xavier Initialization

W = np.random(fan_in, fan_out) / np.sqrt(fan_in)
Python
입력값의 수가 작으면 작은 수로 나눠서 큰 값을 얻고, 입력값의 수가 크면 큰 수로 나눠서 작은 값을 얻는 방법. 
tanh의 경우에는 잘 작동하지만 ReLU의 경우는 절반의 Gradient를 0으로 날려버리기 때문에 잘 작동하지 않는다.
따라서 아래와 같은 대안이 등장했고, 잘 작동한다.
W = np.random(fan_in, fan_out) / np.sqrt(fan_in / 2)
Python

Batch Normalization

Layer의 출력이 정규 분포 (Unit Gaussian)을 따르게 하기 위한 방법을 말한다.
고등학교 확통시간에 배웠던 정규화와 비슷한 과정이네 (식이 똑같다.)
x^k=x(k)E[xk]σ([xk])\hat{x}^{k} = \cfrac{x^{(k)}-E[x^{k}]}{\sigma([x^{k}])} 이런 과정을 Normalization (정규화) 라고 한다.
Batch Normalization은 Batch들에 대해서 평균과 표준편차를 계산해서 Normalize 하는 것을 말한다.
Batch Normalization은 주로 FC나 CONV 직후에 넣어준다. 이를 통해 Bad Scaling Effect를 해소할 수 있다.
CONV에서 Normaliza할때 차원별로 하는것이 아니라 같은 Activation Map의 같은 채널에 있는 요소들은 전부 같이 Normalize 해준다.
이후, Normalize의 정도를 조정해주기 Scaling과 Shift 효과를 더해주는데,
y(k)=γ(k)x^(k)+β(k)y^{(k)} = \gamma^{(k)}\hat x^{(k)} + \beta^{(k)} 의 식을 통해 Normalize 정도를 조절할 수 있다. (감마와 베타는 학습 가능하다.)

Batch Normalization을 하는 이유

Gradient의 Flow를 향상
높은 Learning Rate를 사용할 수 있음
Initialization의 의존성을 낮춤
Regularization의 역할도 수행한다.
결론은 학습이 좋아지고 쉬워진다.

Babysitting the Learning Process

학습 과정을 살펴보자.
1.
데이터 전처리 (Preprocessing)
2.
아키텍쳐 설계
3.
Loss가 말이 되는지 확인 (Softmax가 Log(C)가 되는 것처럼...) → Goot Sanity Check
4.
데이터의 일부만 먼저 학습해본다.
a.
Overfit이 발생하고, Loss가 작을 것이다.
b.
Regularization을 하지 않음
c.
Epoch마다 Loss가 내려가는것을 확인한다.
5.
Learning Rate를 결정한다.
a.
Learning Rate가 너무 작으면 Loss가 잘 변하지 않음
b.
Learning Rate가 너무 높으면 Cost가 NaN(Inf)가 됨.
c.
일반적으로 Learning Rate는 1e-3 에서 1e-5정도를 사용함

Hyperparameter Optimization

1.
Coarse하게 골라서 적은 Epoch으로 몇가지 값을 골라낸다.
2.
Coarse하게 고른 결과를 바탕으로 범위를 대충 고르고
3.
해당 범위를 Fine하게 보면서 결정한다.
4.
Validation Accuracy가 높은 값을 선택하는데, 높은 값이 중간 정도에 위치하게 하면서 탐색하는 것이 좋다.
Sampling 시에 Learning Rate의 선택 범위를 Log Scale로 고르는것이 좋다. 1e-(랜덤)

Grid Search vs Random Search

Random Search가 일반적으로 더 좋다. Important Variable에서 더 많은 테스트를 할 수 있기 때문 (?)

좋은 Learning Rate란?

파란색과 같은 Learnign Rate

주의점

그래프가 이렇게 생겼다면 Backpropagation이 초기에는 안되다가 나중되서 잘되는 것이기 때문에 Initialization의 문제이다.
Training Accuracy와 Validation Accuracy의 차이가 크다면 그것은 Overfit되어서 그럴지도 모른다. 따라서 Reg Strengh를 높여야 한다.
변한 정도와 원래 값 사이의 Ratio가 0.001 근처가 되는것이 좋다.