SGD

* 모든 코드는 제 깃허브 (cdjs1432/DeepLearningBasic: Deep Learning from scratch)에서 확인할 수 있습니다.

 

이번 차시에서는 Stochastic Gradient Descent, 줄여서 SGD를 구현해 보도록 하겠습니다.

 

 

일단 SGD가 뭔지 아주 짤막하게만 설명하자면, 기존 Gradient Descent에서 약간의 mini-batch만을 뽑아서 학습시키는 방법입니다.

이 방법을 사용하면 조금 학습이 불안정해지지만, 더욱 빠른 시간에 꽤 괜찮은 값으로 수렴하게 됩니다.

 

import numpy as np
import ComputeGrad
train_x = np.random.uniform(-5, 5, (100, 10))
ans_w = np.random.uniform(-5, 5, (10, 1))
ans_b = 3
train_y = train_x.dot(ans_w) + ans_b
w = np.random.uniform(-5, 5, (10, 1))
b = np.random.uniform(-5, 5, (1, 1))


w, b = ComputeGrad.SGD(train_x, train_y, 3, w)

print(ans_w)
print(w)

print(ans_b)
print(b)

일단 테스트를 돌리는 코드는 저번 시간과 크게 다르지 않습니다.

그렇다면, SGD는 어떻게 생겼을지 확인해 봅시다.

 

 

def SGD(x, y, b, w, learning_rate=0.01, epoch=1000, batch_size=16):
    if type(w) != np.ndarray:
        w = float(w)
        w = np.reshape(w, (1, 1))
    if x.size == x.shape[0]:
        x = x.reshape(x.shape[0], 1)
    if y.size == y.shape[0]:
        y = y.reshape(y.shape[0], 1)

    for epochs in range(epoch):
        batch_mask = np.random.choice(x.shape[0], batch_size)
        x_batch = x[batch_mask]
        y_batch = y[batch_mask]

        pred = x_batch.dot(w) + b
        dw = ((pred - y_batch) * x_batch).mean(0)
        dw = dw.reshape(dw.shape[0], 1)
        db = (pred - y_batch).mean()
        w -= dw * learning_rate
        b -= db * learning_rate
        if epochs % (epoch / 10) == 0:
            pred = x.dot(w) + b
            err = np.mean(np.square(pred - y))
            print("error : ", err)
    return w, b

...라고는 해도, 저번 Gradient Descent와 크게 달라지지 않았습니다.

어떤 부분이 달라졌는지 확인해 봅시다.

 

 

 

우선, 함수에 batch_size와 batch_mask라는 변수가 생겼습니다.

batch_size는 말 그대로 mini-batch의 크기를 정해 주고, batch_mask는 mini-batch를 만드는 역할을 해 주는데요,

 

위에서 np.random.choice 함수는 0부터 x.shape[0]-1까지의 랜덤한 숫자를 batch_size만큼 뽑아주는 역할을 합니다.

그러므로, x[batch_mask]를 하게 되면, 랜덤하게 골라진 batch_size개의 인덱스를 참조하여 mini-batch를 만들게 됩니다.

 

 

그리고, 이 과정이 전부입니다.

저번 Gradient Descent 코드에서 크게 달라진 부분은 없으니, 쉽게 이해가 되실 거라 믿습니다.

+ Recent posts