딥러닝 직접 구현하기 프로젝트 1-1차시 - Gradient Descent의 구현
* 모든 코드는 제 깃허브 (cdjs1432/DeepLearningBasic: Deep Learning from scratch)에서 확인할 수 있습니다.
import numpy as np
import ComputeGrad
data = np.array([[1, 2, 3], [4, 6, 8]]) # y=2x+2 --> w=2, b=2
train_x = data[0]
train_y = data[1]
w = 1
b = 1
learning_rate = 0.1
epoch = 10000
w, b = ComputeGrad.GradientDescent(train_x, train_y, b, w, learning_rate, epoch)
print(w)
print(b)
일단 가장 먼저 할 것은, 간단한 Linear Regression 및 Gradient Descent의 구현입니다.
어차피 설명할 부분이 적으니, 코드로 바로 들어가도록 하겠습니다.
data = np.array([[1, 2, 3], [4, 6, 8]]) # y=2x+2 --> w=2, b=2
train_x = data[0]
train_y = data[1]
w = 1
b = 1
learning_rate = 0.1
epoch = 10000
우선 처음 시작은 이렇게 간단한 데이터로 하겠습니다.
이정도로 간단한 데이터라면 분명 Gradient Descent를 통해 w=2, b=2라는 정답을 찾아낼 수 있을 겁니다.
위 코드를 통해 train_x에는 [1, 2, 3]이, train_y에는 [4, 6, 8]이 들어가게 됩니다.
또, w값과 b값은 초기 값을 1로 설정하고, learning rate와 epoch까지 설정했습니다.
def GradientDescent(x, y, b, w, learning_rate=0.01, epoch=10000):
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):
pred = x.dot(w) + b # y = w1x1 + w2x2 + ... + wmxm + b
"""
err = 1/m * ((Wx1 + b - y1)^2 + (Wx2 + b - y2)^2 + ... + (Wxm + b - ym)^2)
to minimize err --> differentiate w and b
dw = 2/m * ((Wx1 + b - y1) * x1 + (Wx2 + b - y2) * x2 + ... + (Wxm + b - ym) * xm)
db = 2/m * ((Wx1 + b - y1) * 1 + (Wx2 + b - y2) * 1 + ... + (Wxm + b - ym))
"""
dw = ((pred - y) * x).mean(0)
db = (pred - y).mean()
dw = dw.reshape(dw.shape[0], 1)
w -= dw * learning_rate
b -= db * learning_rate
if epochs % 1000 == 0:
err = np.mean(np.square(pred - y)) # err = 1/m * (w1x1 + w2x2 + ... + wmxm + b - y)^2
print("error : ", err)
return w, b
다음은 Gradient Descent 부분 코드입니다.
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)
원래 Multi Variable Linear Regression을 먼저 만들 생각이었기에, w와 x의 값을 행렬곱에 적합한 형태로 바꾸어 주어야 합니다.
for epochs in range(epoch):
pred = x.dot(w) + b # y = w1x1 + w2x2 + ... + wmxm + b
"""
err = 1/m * ((Wx1 + b - y1)^2 + (Wx2 + b - y2)^2 + ... + (Wxm + b - ym)^2)
to minimize err --> differentiate w and b
dw = 2/m * ((Wx1 + b - y1) * x1 + (Wx2 + b - y2) * x2 + ... + (Wxm + b - ym) * xm)
db = 2/m * ((Wx1 + b - y1) * 1 + (Wx2 + b - y2) * 1 + ... + (Wxm + b - ym))
"""
dw = ((pred - y) * x).mean(0)
db = (pred - y).mean()
dw = dw.reshape(dw.shape[0], 1)
w -= dw * learning_rate
b -= db * learning_rate
if epochs % 1000 == 0:
err = np.mean(np.square(pred - y)) # err = 1/m * (w1x1 + w2x2 + ... + wmxm + b - y)^2
print("error : ", err)
return w, b
다음은 훈련 과정입니다.
우선, Linear Regression에서의 예측값을 pred, loss값을 err로 설정해 두었습니다.
계산 과정은 주석으로 달아놨지만, 조금 더 자세히 써보도록 하겠습니다.
우선 err값은 1/m * ((Wx1 + b - y1)^2 + (Wx2 + b - y2)^2 + ... + (Wxm + b - ym)^2)으로 설정해 두었습니다.
하지만 지금은 multi variable gradient descent가 아니므로, w와 x는 값을 각 한개씩을 가지게 됩니다.
따라서 err값은 $ err = 1/m * (wx + b - y)^2 $ 로 설정이 됩니다.
이제 이 err 값을 w와 b에 대하여 미분해 보면,
$$ \frac{\partial{err}}{{\partial{w}}} = 2/m * (wx + b - y) * x$$
$$ \frac{\partial{err}}{{\partial{b}}} = 2/m * (wx + b - y)$$
가 됩니다.
따라서, 이를 코드로 구현하면,
dw = ((pred - y) * x).mean(0)
db = (pred - y).mean()
가 됩니다.
(2를 곱하지 않은 이유는, 딱히 중요한 이유가 있는게 아니라 코드에 2 곱하는 코드 있으면 더러워 보여서 그런겁니다.)
그리고, 아까 위에서 잠깐 언급했듯, 위 코드는 Multi Variable일때도 작동합니다.
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.GradientDescent(train_x, train_y, 3, w)
print(ans_w)
print(w)
print(ans_b)
print(b)
위의 코드가 바로 그 Multi Variable일 경우의 코드입니다.
train_x와 ans_w, ans_b를 각각 만들어 주어 ans_w * train_x + b의 값으로 y를 만들어 주었고,
w와 b의 초기값을 랜덤으로 설정해 두며 Gradient Descent를 작동시켰습니다.
마지막의 결과값을 보면 ans_w와 w, ans_b와 b가 서로 비슷해져 있는 모습을 볼 수 있습니다.
'인공지능 > 딥러닝 직접 구현하기 프로젝트' 카테고리의 다른 글
딥러닝 직접 구현하기 프로젝트 2-1차시 - Single-Layer Gradient Descent 구현하기 (0) | 2020.06.16 |
---|---|
딥러닝 직접 구현하기 프로젝트 1-4차시 - Softmax Classification & Cross-Entropy Loss구현하기 (8) | 2020.06.14 |
딥러닝 직접 구현하기 프로젝트 1-3차시 - Logistic Regression 구현하기 (0) | 2020.06.12 |
딥러닝 직접 구현하기 프로젝트 1-2차시 - Stochastic Gradient Descent 구현하기 (0) | 2020.06.12 |
딥러닝 직접 구현하기 프로젝트 0차시 - 프로젝트 설명 (0) | 2020.05.30 |