신경망 학습의 목적은 무엇일까? 이는 손실 함수의 값을 낮추는 매개변수를 찾는 것이다. 매개변수의 최적값을 찾는 과정을 최적화라고 한다. 변수는 레이어가 많아질수록 증가하고 적합한 매개변수를 우연히 찾는 것은 불가능에 가깝다. 최적의 매개변수를 찾기 위해서 매개변수의 기울기를 이용했고 기울기에 따라 값을 갱신하여 최적 값을 찾아내었다. 이 기본적인 방법을 확률적 경사 하강법(SGD)라고 한다.
(1) 확률적 경사 하강법
$$W → W - \eta\frac{\delta L}{\delta W}$$
class SGD:
def __init__(self, lr=0.01):
self.lr = lr
def update(self, params, grads):
for key in params.keys():
params[key] -= self.lr * grads[key]
기울어진 방향으로 일정거리만큼 움직이면서 최적값을 찾는 방법이다.
(2) 모멘텀 (Momentum)
$$ v ← \alpha v - \eta\frac{\delta L}{\delta W} $$
속도를 적용하여 기울기 방향으로 가속한다.
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_like(val)
for key in params.keys():
self.v[key] = self.momentum*self.v[key] - self.lr*grads[key]
params[key] += self.v[key]
(3) AdaGrad
여태는 학습률을 임의로 정해주었는데 이 값은 엄청 중요하다. 때문에 적절하게 학습률을 정해주는 기술이 있다. 각각의 매개변수에 맞게 학습률을 맞춤형으로 정해준다.
$$ h ← h + \frac{\delta L}{\ delta W} \odot \frac{\delta L}{\delta W} $$
$$ W ← W - \eta\frac{1}{\sqrt[]{h}}\frac{\delta L}{\delta W} $$
class RMSprop:
def __init__(self, lr=0.01, decay_rate = 0.99):
self.lr = lr
self.decay_rate = decay_rate
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] *= self.decay_rate
self.h[key] += (1 - self.decay_rate) * grads[key] * grads[key]
params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
(4) Momentum + AdaGrad = Adam
솔직히 무슨 말인지 이해안감. 그냥 속도 + 값에 따른 학습률 조정
class Adam:
def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
self.lr = lr
self.beta1 = beta1
self.beta2 = beta2
self.iter = 0
self.m = None
self.v = None
def update(self, params, grads):
if self.m is None:
self.m, self.v = {}, {}
for key, val in params.items():
self.m[key] = np.zeros_like(val)
self.v[key] = np.zeros_like(val)
self.iter += 1
lr_t = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)
for key in params.keys():
#self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key]
#self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2)
self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key])
params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)
#unbias_m += (1 - self.beta1) * (grads[key] - self.m[key]) # correct bias
#unbisa_b += (1 - self.beta2) * (grads[key]*grads[key] - self.v[key]) # correct bias
#params[key] += self.lr * unbias_m / (np.sqrt(unbisa_b) + 1e-7)
'Python > DeepLearning' 카테고리의 다른 글
TensorFlow 교육 - 1일차 (0) | 2019.05.13 |
---|---|
신경망 학습의 핵심 개념 - 오버피팅 (0) | 2019.04.26 |
역.전.파의 기본 개념 (0) | 2019.04.25 |
Tensorflow(keras)를 이용해 MNIST digits 분류해보기 (0) | 2019.04.24 |
List에 값을 append했을 때 List 전체 값이 변하는 현상 (0) | 2019.04.23 |