Optimization
사전적 의미 : 최적화, 가장 효과적인 상태
사전적 의미처럼 optimization은 최적화를 시키는 것으로, loss가 0인 지점을 찾아나가는 것이다.
임의로 가중치 W를 선택하여 이 가중치에 대한 loss를 계산하는 것.
def eval_numerical_gradient(f, x):
fx = f(x)
grad = np.zeros(x.shape) # x차원만큼 gradient를 담기위해 0으로 초기화
h = 0.00001 # 한발자국 움직일 h의 크기를 정해준다.
# np.nditer를 이용해 iterater객체를 만듬
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not il.finished:
ix = it.multi_index # 현재 index를 ix에 저장
old_value = x[ix] # 현재 x값을 old_value에 저장
x[ix] = old_value + h # x[ix]에 x축에서 h만큼 이동한 값을 저장
fxh = f(x) # x+h일 때, 함수값을 구해서 fxh에 저장
x[ix] = old_value # 앞서 old_value에 저장했던 기존x좌표를 보관
grad[ix] = (fxh-fx)/h # grad배열이 현재 index에 구한 gradient값을 저장
it.iternext() # 다음 차원으로 넘어가면서 이를 반복.
return grad # grad라는 배열을 통해 각 차원에 대한 gradient를 구할 수 있다.
np.nditer 참고
https://numpy.org/doc/stable/reference/arrays.nditer.html#arrays-nditer
https://numpy.org/doc/stable/reference/generated/numpy.nditer.html
gradient의 반대방향으로 파라미터를 업데이트하는 것
w = initialize_weights() # W(weight)를 초기화, 어떻게 초기화하냐에 따라 결과나 과정이 달라짐
for t in range(num_steps):
dw = compute_gradient(loss_fn, data, w) #
w -= learning_rate * dw
w = initialize_weights()
for t in range(num_steps):
minibatch = sample_data(data, batch_size)
dw = compute_gradient(loss_fn, minibatch, w)
w -= learning_rate * dw
What if loss changes quickly in one direction and slowly in another?
loss가 한 방향으로 빠르게 변하고 다른 방향으로 천천히 변하면 어떻게 될까?
What does gradient descent do?
경사 하강은 어떤 작용을 합니까?
얕은 치수를 따라 매우 느린 진행, 가파른 방향을 따라 조금씩 움직인다.
Gradient Descent가 지그재그를 그리며 진행되어 더 많은 step이 소요된다는 점이다. 이 때문에 SGD는 Full Batch보다 Overshoot문제에도 더 취약하다.
What if the loss function has a local minimum or saddle point?
loss 함수에 국소 최소점 또는 안장 포인트가 있는 경우 어떻게 됩니까?
경사가 0이고, 경사 하강이 고착된다.
Local Minimum에 빠질 위험이 높으며 고차원의 데이터에서는 gradient가 0인 saddle point에 위치해서 학습이 크게 지연될 수 있다.
SGD는 애초에 일부 데이터로만 학습을 진행하기에 Loss Function에서의 W의 궤적이 항상 Loss의 기울기를 따르는 것이 아니라 거꾸로 돌아가기도 하는 등의 노이즈가 끼는 경우가 많다.
gradient가 오직 속도(velocity)에만 직접적으로 영향을 주고 속도가 위치값(position)에 영향을 줄 것을 제안하고 있다.
# SGD
for t in range(num_steps):
dw = compute_gradient(loss_fn, data, w) #
w -= learning_rate * dw
# SGD + Momentum
v = 0
for t in range(num_steps):
dw = compute_gradient(w)
v = rho * v + dw
w -= learning_rate * v
# rho : friction 혹은 decay rate라고 부른다.
1. SGD + Momentum
v = 0
for t in range(num_steps):
dw = compute_gradient(w)
v = rho * v - learning_rate * dw
w += v
2. SGD + Momentum
v = 0
for t in range(num_steps):
dw = compute_gradient(w)
v = rho * v + dw
w -= learning_rate * v
SGD+Momentum이 서로 다른 방식으로 공식화된 것을 볼 수 있지만, 동일한 x 시퀀스를 제공한다.
v = 0
for t in range(num_steps):
dw = compute_gradient(w)
old_v = v
v = rho * v - learning_rate * dw
w -= rho * old_v - (1 + rho) * v
grad_squared = 0
for t in range(num_steps):
dw = compute_gradient(w)
grad_squared += dw * dw
w -= learning_rate * dw / (grad_squared.sqrt() + 1e-7)
What happens with AdaGrad?
Progress along “steep” directions is damped;
progress along “flat” directions is accelerated
# AdaGrad
grad_squared = 0
for t in range(num_steps):
dw = compute_gradient(w)
grad_squared += dw * dw
w -= learning_rate * dw / (grad_squared.sqrt() + 1e-7)
# RMSProp
grad_squared = 0
for t in range(num_steps):
dw = compute_gradient(w)
grad_squared = decay_rate * grad_squared + (1 - decay_rate) * dw * dw
w -= learning_rate * dw / (grad_squared.sqrt() + 1e-7)
moment1 = 0
moment2 = 0
for t in range(num_steps):
dw = compute_gradient(w)
moment1 = beta1 * moment1 + (1-beta1) * dw
moment2 = beta2 * moment2 + (1-beta2) * dw
w -= learning_rate * moment1 / (moment2.sqrt() + 1e-7)
What happens at t=0? (Assume beta2 = 0.999)
참고 강의
https://www.youtube.com/watch?v=f3gMzIt_d-A&feature=youtu.be
참고 사이트
https://kmiiiaa.tistory.com/14?category=907348
https://github.com/aikorea/cs231n/blob/master/optimization-1.md
http://aikorea.org/cs231n/neural-networks-3/
https://kmiiiaa.tistory.com/14
https://fabj.tistory.com/49
내 기준에 이해하기 쉬웠던 블로그 1 🌟🌟
내 기준에 이해하기 쉬웠던 블로그 2 🌟🌟🌟