6.1 Optimization

#SGD(Stochastic Gradient Descent)

class SDG:
	def __init__(self, lr=0.01):
		self.lr = lr # 학습률을 의미한다.
	
	def update(self, param, grads):
		for key in params.keys():
			params[key] -= self.lr * grads[key] # 가중치 매개변수 -= 학습률 * 기울기

#Learning rate

#비효율적인 케이스과 대안

#Momentum

#모멘텀의 속성

  1. 공이 그릇의 바닥을 구르는 듯한 움직임으로 손실함수값이 갱신됩니다.
  2. av값은 물체가 아무런 힘을 받지 않을 때, 서서히 하강하게 만듭니다. (a값은 0.9 등의 상수로 설정합니다)

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 paras.items():
				self.v[key] =np.zeros_like(val) # update 시에 None 이면 매개변수와 같은 구조의 데이터로, 0을 채워서 생성
			
		for key in params.keys():
			# self.v[key]는 이전 update때 움직였던 가중치값(항상 마이너스)
			self.v[key] = self.momentum * self.v[key] - self.lr*grads[key]
			params[key] += self.v[key] 
			# self.v[key]는 음수로 시작. 이전에 많이 이동했다면(-가 크다면), 다음 update에도 많이 움직인다. 이전에 조금 이동했다면 다음 update에는 더 조금 움직이게 된다. 즉, 갑작스럽게 방향전환이 되지 않고 한 방향으로 이동하게 된다.

#AdaGard

#학습률을 점점 줄인다.

#어떻게?

class AdaGrad:
	def __init__(self, lr=0.01):
		self.lr = lr
		self.h = None
		
	def update(self, paras, 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]
			paras[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)			# 계속 제곱하다 보면 self.h[key]값이 0이 될 수 있기 때문에, 이를 막기 위해 1e-7을 더해준다.

#RMSprop

AdaGrad와 흡사하지만, 과거의 기울기를 계속 제곱하여 더해가지 않고, 먼 과거의 기울기는 서서히 잊고 새로운 기울기 정보를 반영하는 학습 방법

#Adam(Adaptive Moment Estimation))

RMSprop에 모멘텀을 도입한 학습 방법

#NAG(Nesterov Accelerated Gradient)

Momentum 방식의 경우 멈춰야 할 시점에서도 관성에 의해 훨씬 멀리 갈수도 있다는 단점이 존재하는 반면, NAG 방식의 경우 일단 모멘텀으로 이동을 반정도 한 후 어떤 방식으로 이동해야할 지를 결정한다.