๋ฐ์ํ
๋๋ณด๊ธฐ
๊ธฐ์กด ๋ถ์บ ๋ ๋
ธ์
์ ๊ฐ์ธ์ ์ผ๋ก ์ ๋ฆฌํ ๊ฒ์ ๊ณต๋ถํ ๊ฒธ ์์ฑํ ๊ธ์
๋๋ค.
๊ฐ์ธ์ ์ผ๋ก ํด์ํด์ ์์ฑํฉ๋๋ค. (ํ๋ฆด ์ ์์. ์ ์ ์์ฒญ ์๋งใ
)
** ๊ฐ์์๋ฃ๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค **
** ์์
์ ์ด์ฉ์ ๊ธ์งํฉ๋๋ค **
Today's Keyword
๋ฏธ๋ถ, ๊ธฐ์ธ๊ธฐ, ๊ฒฝ์ฌํ๊ฐ๋ฒ, ํธ๋ฏธ๋ถ, gradient vector
๋ฏธ๋ถ (Differentiation)
- ๋ณ์์ ์์ง์์ ๋ฐ๋ฅธ ํจ์๊ฐ์ ๋ณํ ์ธก์
- ์ต์ ํ์์ ๋ง์ด ์ฌ์ฉ
- ๋ฏธ๋ถ == ์ ์ ์ ๊ธฐ์ธ๊ธฐ
- ํจ์์ ๋ชจ์์ด ๋งค๋๋ฌ์์ผ ํ๋ค (์ฐ์)
- ํ ์ ์์ ์ ์ ์ ๊ธฐ์ธ๊ธฐ๋ฅผ ์๋ฉด
- ์ฆ๊ฐ : ๋ฏธ๋ถ ๊ฐ ๋ํ๊ธฐ
- ๊ฐ์ : ๋ฏธ๋ถ ๊ฐ ๋นผ๊ธฐ
- ๋ฏธ๋ถ๊ฐ์ด ์์(์ข๋ก ์์นํ๋ ํํ) = x+f'(x) < x ๋ ์ผ์ชฝ์ผ๋ก ์ด๋ํ์ฌ ํจ์๊ฐ์ด ์ฆ๊ฐ
- ๋ฏธ๋ถ๊ฐ์ด ์์(์ฐ๋ก ์์นํ๋ ํํ) = x+f'(x) > x ๋ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ์ฌ ํจ์๊ฐ์ด ๊ฐ์
- sympy.sym.diff() : ๋ก ๊ฐ๋จํ๊ฒ ๋ฏธ๋ถ ๊ณ์ฐ ๊ฐ๋ฅ (import sympy as sym)
๊ฒฝ์ฌ์์น ํ๊ฐ ๋ฒ
- Gradient Ascent +
- ๋ฏธ๋ถ๊ฐ์ ๋ํ๊ธฐ
- ํจ์์ ๊ทน๋๊ฐ์ ์์น
- ์ ์ผ ๋์ ๊ณณ ์ฐพ๊ธฐ
- Gradient Descent -
- ๋ฏธ๋ถ๊ฐ์ ๋นผ๊ธฐ
- ํจ์์ ๊ทน์๊ฐ์ ์์น
- ์ ์ผ ๋ฎ์ ๊ณณ ์ฐพ๊ธฐ
- ๊ทน ๊ฐ์ ๋๋ฌํ๋ฉด ๋ฉ์ถค (= ๋ฏธ๋ถ ๊ฐ์ด 0)
์ฝ๋๋ก ๋ด๋ณผ๊น
#init ์์์ , lr : ํ์ต๋ฅ , eps : ์๊ณ ๋ฆฌ์ฆ ์ข
๋ฃ์กฐ๊ฑด
var = init # ์์์
grad = gradient(var) # ๋ฏธ๋ถ๊ณ์ฐํ๋ ํจ์
while (abs(grad)>eps): # 0๊ณ์ฐ ๋ชปํ๋ ์ ์์ ๋ฉ์ถค
var = var - lr * grad # ํ์ต๋ฅ ๋ก ์๋ ์กฐ์
grad = gradient(var) # ๊ณ์ ๋ฏธ๋ถ๊ฐ ์
๋ฐ์ดํธ
ํจ์ f(x) = x^2 + 2x + 3 ๊ฒฝ์ฌํ๊ฐ๋ฒ์ผ๋ก ์ฐพ๊ธฐ
import sympy as sym
import numpy as np
from sympy.abc import x
def func(val): # 2์ฐจํจ์ ์ ์
fun = sym.poly(x**2 + 2*x + 3)
return fun.subs(x, val), fun
def func_gradient(fun, val): # ๋ฏธ๋ถ ๊ณ์ฐ ํ๋ ํจ์
_, function = fun(val)
diff = sym.diff(function, x)
return diff.subs(x, val), diff # x, val์ ๋ฏธ๋ถ ์ฐจ์ด / ๋ฏธ๋ถ๊ฐ
def gradient_descent(fun, init_point, lr_rate=1e-2, epsilon=1e-5):
cnt=0
val = init_point
diff, _ = func_gradient(fun, init_point)
while np.abs(diff) > epsilon:
val = val - lr_rate*diff
diff, _ = func_gradient(fun, val)
cnt+=1
print("ํจ์: {}, ์ฐ์ฐํ์: {}, ์ต์๊ฐ: ({}, {})".format(fun(val)[1], cnt, val, fun(val)[0]))
gradient_descent(fun=func, init_point=np.random.uniform(-2,2))
ํธ๋ฏธ๋ถ (partial Differentiation) : ๋ฒกํฐ๊ฐ ์ ๋ ฅ์ธ ๋ค๋ณ์ ํจ์
- ์ด๋ ๊ฒ ๋ค๋ณ์ ํจ์์ ๊ฒฝ์ฐ ๊ฐ ๋ณ์ ๋ณ๋ก ๊ณ์ฐํ gradient vector๋ฅผ ์ด์ฉ.
- e_i ๋ก i๋ง 1์ด๊ณ ๋๋จธ์ง 0 ๋๋ฆฐ ๋จ์ ๋ฒกํฐ ์ด์ฉํ๋ ์
import sympy as sym
from sympy.abc import x, y
# ํจ์ ์ ์์ ํธ๋ฏธ๋ถ
sym.diff(sym.poly(x**2 + 2*x*y + 3) + sym.cos(x + 2*y), x)
Gradient Vector
- ๋ฒกํฐํ ๋๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ทน์ ์ผ๋ก ๊ฐ๋ ๋ฐฉํฅ์ฑ์ด ์๊น.
- +๋ฉด ๊ฐ์ฅ ๋นจ๋ฆฌ ์ฆ๊ฐํ๋ ๋ฐฉํฅ. - ๋ฉด ๊ฐ์ฅ ๋นจ๋ฆฌ ๊ฐ์ํ๋ ๋ฐฉํฅ !
์ฝ๋๋ก ๋ณด๋ฉด....
- ๋ฒกํฐ๋ ์ ๋๊ฐ ๋์ norm ์ด์ฉํ๊ธฐ์ ๊ทธ ๋ถ๋ถ๋ง ๋ฐ๊พธ์ด ์ค๋ค.
- while(norm(grad)>eps):
- f(x) = x^2 + 2y^2 ์ผ ๋ ๊ฒฝ์ฌํ๊ฐ๋ฒ์ผ๋ก ์ต์์ ์ฐพ๊ธฐ
import sympy as sym
import numpy as np
from sympy.abc import x, y
# Multivariate Gradient Descent
def eval_(fun, val): # ํจ์๊ฐ์ ๊ณ์ฐ
val_x, val_y = val
fun_eval = fun.subs(x, val_x).subs(y, val_y)
return fun_eval
def func_multi(val): # ํจ์ ์ ์
x_, y_ = val
func = sym.poly(x**2 + 2*x*y + 2)
return eval_(func, [x_, y_]), func
def func_gradient(fun, val): # gradient vector
x_, y_ = val
_, function = fun(val)
diff_x = sym.diff(function, x)
diff_y = sym.diff(function, y)
grad_vec = np.array([eval_(diff_x, [x_, y_]), eval_(diff_y, [x_, y_])], dtype=float)
return grad_vec, [diff_x, diff_y]
def gradient_descent(fun, init_point, lr_rate=1e-2, epsilon=1e-5):
cnt=0
val = init_point
diff, _ = func_gradient(fun, val)
while np.linalg.norm(diff) > epsilon:
val = val - lr_rate*diff
diff, _ = func_gradient(fun, val)
cnt+=1
print("ํจ์: {}, ์ฐ์ฐํ์: {}, ์ต์๊ฐ: ({}, {})".format(fun(val)[1], cnt, val, fun(val)[0]))
# ์คํ
pt = [np.random.uniform(-2, 2), np.random.uniform(-2, 2)]
gradient_descent(fun=func_multi, init_point=pt)
๋ฐ์ํ
'AI ๊ณต๋ถ ํญ์ํ์ > ๊ด๋ จ ์ด๋ก ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Math] ํ๋ ฌ์ ์์๋ณด์ (1) | 2024.12.02 |
---|---|
[Math] ๋ฒกํฐ๋ฅผ ์์๋ณด์ (1) | 2024.11.22 |