👩‍💻LEARN : ML&Data/Lecture

[CS231n] Lecture6. Training Neural Networks 2

쟈니유 2023. 5. 15. 17:02
728x90

복습

Activation Functions 

ReLU, LeakyReLU, tanh, ELU, Maxout, Sigmoid

ReLU가 기본 선택으로 가장 좋음 

 

Weight Initialization

초기 값이 너무 작을 경우 : Activation, gradient 모두 0이 되어 학습이 되지 않음

초기 값이 너무 클 경우 : Activation이 폭발!(tanh)하고 gradient가 0이되어 학습이 되지 않음

Xavier, MSRA(He etal) 을 사용할 것

  • Xavier : W = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in) 
  • MSRA (Xavier for ReLU) : W = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in/2)

Data Processing

zero-centered & normalized 

normalize되지 않으면 classifier 직선이 조금만 움직여도(=W가 약간만 변해도) loss가 예민하게 반응

 

Batch Normalization

activation이 zero-mean & unit variance되게 하는 것 

 

Babysitting Learning 

Loss와 train-val set 간 정확도 차이를 모니터링 하는 것 

 

Hyperparameter Search

Random search than Grid Search 

성능이 파라미터에 좌우될 때 그 ㅍ ㅏ라미터를 더 넓은 범위로 탐색할 수 있게 함 

 

Coarse to Fine search

최대한 처음엔 넓은 범위로 시작해서 점차 줄여나갈 것 

 

파라미터는 보통 learning rate, regularization, lr decay, model size...등 2~4개 사이로 정하는 것이 좋음 

 

Today 
Fancier Optimization
Regularization
Transfer Learning 

Optimization 

[Problems with SGD]

while True:
	weight_grad = evaluate_gradients(loss_fun, data, weights) #gradient계산
    weights = weights - ( stepsize* weights_grad )#기존 가중치에서 stepsize*graident만큼 빼면서 움직이는 것

1. Very slow progress along shallow dimension, jitter along steep direction 

  • Loss가 넓은 원반 모양일 때, 수평으로 가는 속도가 수직으로 가는 것 보다 느림 
  • Loss가 수직엔 sensitive하지만 수평으론 그렇지 못해서 지그재그 문제가 생김 
  • 고차원이 될 수록 이 문제가 더욱 강화됨 

2. Local minima & saddle point

  • local minima나 saddle point를 만나게 되면 gradient=0이 되어 더이상 업데이트가 되지 않음 
  • 특히 고차원에서는 saddle point 문제가 만연함. saddle point 주변도 기울기가 0에 가깝기 때문에 전반적인 업데이트 속도가 느려짐 

3. Noisy gradients from mini-batches

  • gradient를 계산할 때 미니배치로부터 전체 배치를 추정하여 계산하기 때문에 gradient가 noisy estimate되며, 이로 인해 minima까지 도달하는 시간이 오래 걸림 

[SGD + Momentum]

기존 SGD에 Velocity 개념을 추가해서 측정된 gradient 방향으로 가속할 수 있도록 개선 

기울기가 0이어도 velocity로 인해 update를 지속할 수 있음 

parameter Rho : 0.9, 0.999 for 마찰 (너무 심하게 가속하면 안되니까)

 

vx = 0 #초기 velocity 0으로 초기화 

while True:
	dx = compute_gradient(x) #기울기 개선
    vx = rho * vx + dx      #기울기가 0이어도 rho*vx가 있어서 업데이트 가능 
    x = x + learning_rate * vx

SGD+Momentum and Nestrov Momentum

  • SGD의 경우 현재 지점에서의 gradient를 개선하고 이를 velocity와 곱해서 actual step을 구함 
  • Nestrov의 경우 먼저 velocity 방향으로 간 다음 거기에서 gradient를 계산, 다시 원점으로 돌아온 다음 actual step을 수행
  • Nestrov는 convex엔 잘 적용되지만 CNN등엔 잘 적용되지 않음 

계산방법

먼저 t+1시점 에서의 velocity를 t시점의 velocity와 gradient를 통해 구한다 

그 다음, 원점으로 돌아와, 원점에 t+1시점의 velocity를 더해 미래의 actual step을 구한다 

dx = compute_gradient #기울기
old_v = v 

v = rho*v - learning_rate*dx 
x = x - rho * old_v + (1+rho) * v

 

[AdaGrad]

  • gradient의 제곱들을 합하여 step(learning rate*dx)을 나눠줌으로써, gradient를 요소별로 스케일링 해주고자 함 
    • small gradient: 더욱 작은 수로 나눠주기 때문에 속도가 더 잘 붙을 수 있음 
    • large gradient : 큰 수로 나누는 것이기 때문에, wiggling 문제에서 속도를 천천히 내려가게 만들 수 있음 (?)
  • 학습횟수가 늘어날수록 grad_squared가 증가하면서 업데이트 값은 줄어들 수 밖에 없어 saddle point와 같은 형태에선 멈출 수 있음 
  •  
grad_squared = 0
while True:
	dx = compute_graidnet(x)
    grad_squared = grad_squared + dx*dx
    x = x - (learning_rate * dx)/(np.sqrt(grad_squared) + 1e-7)

[RMSProp]

decay_rate (0.9~0.99)을 추가해서 속도가 감소하는 Adagrad의 문제를 해결하려고 함 

grad_squared = 0
while True:
	dx = compute_gradient(x)
    grad_squared = decay_rate * grad_squared + (1-decay_rate) * dx * dx
    x = x - (learning_rate * dx) / (np.sqrt(grad_squared)+1e-7)

[Adam] 

  • Momentum + AdaGrad 를 합친 버전 
  • first moment : velocity처럼 beta1*first_moment가 기울기가 0이 되어도 업데이트를 지속하게 해줌 
  • second_moment :기울기를 제곱한 다음  합하여 update step에서 이를 제곱근 취한 값으로 나누게 함 
  • 단 초기 seond_moment 값이 0일 경우, 두번째 업데이트시 second_moment 값은 (1-beta2)*dx*dx. 이 때 beta2가 0.9가량이므로 이 값은 0에 수렴하는 매우 작은 값이 될 것임. update를 second_moment로 바로 나눠주게 되면 너무 작은 값으로 나눈 것이기 때문에 업데이트가 매우 크게 되어 한번의 step이 매우 커질 수 있음 
  • 이를 방지하기 위해 unbias를 추가

 

[Learning rate decay]

  • 에포크가 거듭될 수록 loss가 점차적으로 줄어들 수 있는 것이 good learning rate
  • learning rate을 점차적으로 감소시키는 방법이 있음 
    • step decay : 몇개의 에포크마다 학습률을 절반으로 낮추는 것 
      • SGD+Momentum에 사용 
    • exponential decay : e의 역수를 기존 a에 곱해주는 것 
    • 1/t decay : 기존 a를 특정 수로 나눠주는 것 
  • 단 learning rate decay는 부차적인 파라미터이며 learning rate이 중요함 

[Second Order Optimization] 

  • 이차 함수 모양의 근사치를 사용하기 위해 gradient와 헤세 행렬을 사용하는 것으로 근사치의 minima에 해당하는 방향으로 step을 밟게 함 
  • 장점으로는 파라미터, 학습률이 필요하지 않다는 것 
  • 하지만 NN과 같은 딥러닝을 수행하게 되면 연산량이 많아 적합하지 않음 O(N**2)..! 
  • ...이건 여기서..멈춰본다..

 

Regularization

training - val 간 갭을 줄이는 것 

 

[Model ensembles]

  • 다양한 독립적인 모델을 학습시킨다 
  • test 시 다양한 독립적인 모델들의 result를 평균내서 사용한다
  • 이렇게 하면 2% 정도 성능이 높아짐 (큰 ..의미..없다..)
  • 대신 하나의 모델을 학습시킬 때, training 때의 스냅샷을 여러개 만들어서 이들을 모델 앙상블처럼 쓸 수도 있음 

 

[Add term to loss]

  • Loss 계산시 regularization 을 추가해서 train data 과적합을 막았음
  • L1,2는 NN에선 많이 사용되지 않음 

 

[Dropout]

  • 순전파 학습 시, 몇개의 뉴런을 랜덤하게 0로만드는 것 (.5가 일반적)
  • 신경망이 생략된 representation을 학습하게 함으로서 feature간의 상호작용을 방지함 

Test 시 dropout

  • 랜덤하게 뉴런을 drop하는 것이기 때문에 test 시에 고정된 drop을 시행해야 할 필요성이 있음 
  • 이를 평균내어 랜덤성을 없애고 싶지만 이러한 적분은 쉽지 않음 

  • training 시 뉴런의 on/off 경우의 수를 생각해보면 확률을 도출할 수 있음. 이 확률을 test 시에도 동일하게 곱해줌으로서 dropout을 테스트에 적용하고자 함 
  • 테스트 시엔 모든 뉴런이 살아있으므로, 각 뉴런의 training 시 기대값 = test 시의 실제 아웃풋을 동일하게 만들어주기 위해 이와 같이 수행하는 것 

 

[BatchNorm]

배치정규화의 예시, 학습에 랜덤한 미니배치들을 정규화하며 학습시키고 테스트 시엔 fixed stats를 사용 

BatchNorm 과 Dropout을 동시에 쓰는 경우는 많지 않음 

[Data Augmentation]

주어진 데이터에 변형을 취하는 것

  • Horizontal Flip
  • Random Crops and scales : 한 이미지에서 여러 범위의 crop을 시행해 샘플링 하는 것 
  • Color jitter : Contrast/Brightness를 랜덤하게 만드는 것. 
    • training set의 RGB 에 픽셀 단위로 PCA를 적용 
    • principal component에 따라 color offset을 샘플링함
    • training image의 모든 픽셀에 offset을 더함 

 

Transfer Learning

 

  • 적은 수의 데이터로도 CNN을 학습시킬 수 있게 함 
  • 갖고 있는 데이터의 형태와 수에 따라 맨 마지막 레이어 혹은 마지막 부분 레이어를 학습시키는 방식