Group Normalization
Batch Normalization에서 Batch의 크기가 작으면 생기는 문제들을 해결하기 위해 Chanel 별로 Normalize하는 Layer Normalize나 Indtance Normalize, Group Normalize등이 생겨났음.
Optimization
Stochastic Gradient Descent 의 문제점
1.
SGD의 경우 불균형한 방향이 존재한다면 SGD의 학습 속도가 급격하게 느려진다. (Poor Conditioning)
2.
Local Minima는 최솟값은 아니지만 gradient가 0이기 때문에 학습이 멈춰버린다.
3.
Saddle point의 경우 계속 증가하거나 감소하지만 gradient가 0이기 때문에 학습이 멈춰버린다.
큰 NN은 Saddle point에 굉장히 취약하다.
4.
Mini-batch를 이용해서 gradient를 계산하기 때문에 실제 gradient를 얻는 것이 아닌 gradient의 추정값 만을 얻는다. 따라서 빠른 경로로 학습할 수 없기 때문에 시간이 오래 걸린다.
SGD + Momentum Term
Gradient를 계산할때 Velocity를 고려하는 방법. 일반적인 SGD를 수식으로 나타냈을 때 라면, Momentum을 추가하면 아래와 같다.
( 이다. 일반적으로)
는 velocity의 영향력을 결정하는 hyper parameter이다.
Momentum Term을 추가하면 Local minima나 saddle point에 도착하더라도 velocity가 남아있기 때문에 지속해서 학습할 수 있다.
Poor conditioning의 경우 momentem이 지나친 변동을 상쇄시킬 수 있다.
Nesterov Momentum
일반적인 Momentum이 Velocity와 Gradient를 계산해서 더하는 것이라면, Nesterov Momentum은 Velocity만 계산해서 해당 방향으로 이동후, 이동한 점에서의 Gradient를 계산해서 더하는 방법이다.
여기서, 를 라 하면,
가 성립한다.
AdaGrad
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared += dx ** 2
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)
Python
복사
Poor Conditioning 문제를 효과적으로 해결할 수 있다. dx가 큰 방향의 경우 grad_square의 값이 같이 커져서 해당 방향으로의 Step Size를 조절하는 효과를 갖는다.
하지만 Saddle Point에 가까워지면 step size가 작아져서 멈춰버릴 수 있음
RMSProp
AdaGrad의 변형판으로, AdaGrad의 문제를 해결하였다.
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared = decay_rate * grad_squared + (1-decay_rate) * dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)
#decay_rate는 주로 0.9나 0.99등을 씀
Python
복사
RMSProp의 경우 느리지만 길을 바로 찾아가는 느낌이고, Momentum은 Overshoot한 뒤에 제자리를 찾아가는 느낌이다.
Adam
Momentum 계열과 AdaGrad계열을 조합한 방법
first_moment = 0
second_moment = 0
for t in range(num_iterations):
dx = compute_gradient(x)
first_moment = beta1 * first_moment + (1 - beta1) * dx
second_moment = beta2 * second_moment + (1-beta2) * dx * dx
first_unbiased = first_moment / (1 - beta1 ** t)
second_unbiased = second_moment / (1 - beta2 ** t)
x -= learning_rate * first_unbias / (np.sqrt(second_unbias) + 1e-7))
#대충 beta1=0.9 beta2=0.999 learning_rate = 1e-3, 5e-4 정도로 놓으면 대부분 개잘돌아감
Python
복사
Learning Rate Decay
Step Decay
몇개의 epoch마다 learning rate를 낮춘다.
Exponential Decay
1/t Decay
loss의 감소가 잘 일어나지 않을때 learning rate를 낮추면 효과를 볼 수 있다.
Learning Rate Decay는 Adam 보다 SGD Momentum에서 자주 쓴다.
Learning Rate Decay또한 또 다른 Hyperparameter이므로 바로 사용하는것은 좋지 않고 일단 Learning Rate를 잘 고르는 것이 중요하다.
Second-Order Optimization
GD는 기본적으로 1차 테일러 근사와 같다. 하지만 1차 근사를 하면 조금만 멀어져도 값이 차이나는 한계가 있다. 따라서 2차 테일러 근사를 통해 minima로 더 빠르게 이동할 수 있다.
하지만 2차 테일러 근사(Hessian Matrix)는 N*N 행렬이므로 계산할 수가 없다.
Quasi-Newton Method (BGFS)
Full Hessian Matrix가 아닌 근사시킨 값을 사용한다.
L-BFGS
Hessian Matrix를 근사시켜 사용하는 방법이지만 2차 근사는 stochastic case에서 잘 작동하지 않으므로 잘 안쓴다.
→ Full batch update가 가능하고 stochasticity가 작다면 써봄직하다.
Optimization은 Training Error를 줄이고 Loss Fucntion을 최소화시키기 위해 사용한다. 하지만 사실 Training Error는 별로 중요하지 않고, 처음 보는 데이터에 얼마만큼 성능을 내는지가 중요한데 이는 곳 Training Error와 Test Error의 차이를 줄이는 것이다.
Model Ensembles
모델을 하나만 학습시키지 말고 여러 모델을 독립적으로 학습시켜 평균값을 이용한다.
모델이 늘어날수록 Overfitting이 줄고 2%정도 성능이 늘어난다.
단일 모델을 학습시킬때 학습 시키는 중간에 모델을 snapshot하고 그것을 Ensemble해서 사용한다.
Regularization
L2 Reg는 NN에 잘 어울리지 않기 때문에 조금 다른 것을 사용함.
Dropout
Forward pass과정에서 임의로 일부 뉴런의 activation을 0으로 설정함. Forward pass 할때마다 0이되는 뉴런이 계속 변화한다.
dropout의 무/유
FC Layer나 CONV Layer에서 주로 사용한다.
Dropout은 네트워크가 특정 feature에 의존하지 못하게 해준다. 해당 feature를 판별하는 neuron을 0으로 만들기 때문이다.
Dropout은 거대한 Ensemble 모델을 동시에 학습하는것과 같다.
하지만 학습 후 테스트 중간 중간에 Random 요소를 넣어서 Dropout 시키는 것은 좋지 못하다. 오늘은 고양이로 분류되는것이 내일은 고양이가 아니게 분류되는 일이 일어날 수도 있다.
그래서 네트워크의 출력의 Dropout Probability를 곱하는 방법을 사용한다.
하지만 테스트 중간에 probability를 곱하는 과정 조차 컴퓨팅 파워를 소모하기 때문에 training 과정에서 probability를 미리 나눠준다.
Dropout은 학습 시간이 더 길지만 일반화 능력은 더 좋다고 할 수 있다.
Dropout을 사용하게 되면 Backprop시에 일부 Network만 사용하게 되어 학습 시간이 길어진다는데, 도대체 이게 뭔소릴까...
차라리 Random 값을 결정해야 한다거나, 여러 Network를 학습하게 되어서 시간이 늘어난다 하면 이해가 가는데 도대체 왜?!
Batch Normalization
Regularization 효과가 있다. Batch Noramalization 을 하면 Dropout은 하지 않는다.
Data Augmentation
Label은 그대로 두고 이미지를 무작위로 변환시켜서 학습함. Flip, Crop, Color Jittering(Contrast나 Brightness를 바꾸는것), Rotate, Stretch, Shearing ...등등 여러가지 방법이 있다.
DropConnect
Activation이 아니라 Weight Matrix를 0으로 만들어주는 방법이다.
Fractional Maxpooling
Pooling 연산을 랜덤 영역에서 수행한다.
Stochastic Depth
Train 할 때 일부 Layer를 날려서 학습하고 Test시에 전체 layer로 테스트
Transfer Learning
CNN에서 적은 데이터를 사용할 수 있게 해준다.
ImageNet같은 큰 데이터셋으로 먼저 학습시키고, 일부 Layer를 제외한 나머지 Layer는 Freeze시킨다음에 Freeze되지 않은 layer만 학습한다.
데이터셋의 크기가 클수록 Freeze 하지 않는 Layer의 수를 늘려서 여러 Layer를 학습시켜볼 수 있다.
데이터셋의 크기에 따라 아래 방법들을 적용해볼 수 있다.