티스토리 뷰
공부 : 밑바닥부터 시작하는 딥러닝 1 chapter 6.1
이전에는 매개변수 갱신을 경사 강하법(SGD)을 이용해 구현하였습니다.
SGD 이외의 방법에 대해서도 알아봅시다.
매개변수 갱신은 매개변수의 손실함수의 기울기를 최소화하는 방향으로 이루어져야 합니다. 이를 하는 방법에는 SGD, Momentum, AdaGrad, Adam 등이 있습니다.
1. SGD : 확률적 경사 강하법
가장 구현이 쉬운 방법입니다. 하지만 속도가 느리고 경우에 따라 다른 최적화 방법보다 성능이 떨어지기도 합니다.
하지만 아직 많이 사용 중입니다.
식과 코드는 다음과 같습니다.
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]
W가 매개변수이고, 에타는 학습률, dL/dW는 W에 대한 손실함수의 기울기입니다.
SGD의 단점 : SGD는 비등방성 함수 (방향에 따라 성질이 달라지는 함수)에서는 경로 탐색 (손실함수의 기울기 최소화 과정)에서 비효율적입니다.
( 책의 예 : f(x, y) = (x^2)/20 + y^2 )
2. Momentum
모멘텀은 운동량을 뜻하는 물리 용어입니다. 기울기 방향으로 물체가 가속된다는 것을 이용한 것입니다.
식과 코드는 다음과 같습니다.
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
AdaGrad는 기존의 SGD는 학습률을 정하여 계산한 것과 다르게, 매개변수의 학습률을 조절하면서 기울기를 갱신합니다.
식과 코드는 다음과 같습니다. ( dot 연산은 행렬의 원소 별 곱을 나타낸 것)
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)
4. Adam
새로운 기법으로, AdaGrad와 Momentum을 합친 것입니다. 책에 식이 따로 나와있지 않아 코드만 나타내겠습니다.
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] += (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)
'딥러닝' 카테고리의 다른 글
가중치 설정 (0) | 2021.01.17 |
---|---|
매개변수 갱신 방법 성능 비교 (0) | 2021.01.15 |
오차역전파법 구현 (0) | 2021.01.14 |
오차역전파법 - Affine, Softmax 구현 (0) | 2021.01.14 |
오차역전파법 - 활성화 함수 계층 구현하기 (0) | 2021.01.14 |