GD와 SGD 비교
SGD 코드
# Stochastic Gradient Descent
while True:
weights_grad = evalute_gradient(loss_fun, data, weights) # mini-batch에서 loss 계산
weights += step_size * weights_grad # gradient 반대방향으로 parameter 업데이트
Mini batch를 통해 학습시킬 때 최적의 값을 찾아가는 방향이 뒤죽박죽이다.
Local minimum, Saddle point
SGD의 단점을 개선하는 방법 - 방향 중심
모멘텀
class Momentum: def __init__(self, lr = 0.01, momentum = 0.9): self.lr = lr self.momentum = momentum self.v = None def update(self, params, grads): if self.v is None: self.v = {} for key, val in params.items(): self.v[key] = np.zeros_list(val) for key in params.keys(): self.v[key] = self.momentum * self.v[key] - self.lr * self.grads[key] self.params[key] += self.v[key]
적용 결과
Nesterov Momentum(NAG)
SGD의 단점을 개선하는 방법 - 보폭 중심
AdaGrad
class AdaGrad: def __init__(self, lr = 0.01): self.lr = lr self.h = None def update(self, params, grads): if self.h is None: self.h = {} for key, val in params.items(): self.h[key] = np.zeros_like(val) for key in params.keys(): self.h[key] += grads[key] * grads[key] params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
RMSProp
def rmsprop(f, gfx, x, ir=100, h=np.array([0.1, 0.1]), gamma=0.001, lamb=0.1, rho = 0.5, th=0.00001): h = h.copy() log = np.array([]) for i in range(ir): log = np.append(log, x) gx = gfx(x) h = rho*h + (1 - rho)*gx**2 xNew = x-lamb*gx/(h**(1/2)) if(sum(abs(x-xNew)) <th): break x = xNew log = log.reshape(len(log)//2, 2) return x, i, log x = np.array([0,0]) xm, _, log = rmsprop(fx, gfx, x, rho=0.8,ir=1000) plotLog(log)
Adam
- 그 외