sympy
모듈의 sympy.diff
를 사용해 미분 계산 가능import sympy as sym
from sympy.abc import x # 라틴-그리스 문자 중 x 사용
sym.diff(sym.poly(x**2 + 2*x + 3), x) # 첫 인자 : 수식, 두번째 인자 : 미분 대상
# Poly(2𝑥+2,𝑥,𝑑𝑜𝑚𝑎𝑖𝑛=ℤ)
sympy
는 파이썬에서 제공하는 기호 처리 모듈이다. LaTeX
수식을 지원하기 때문에 여러 수식이나 문자에 대해 처리해준다. 또한 sympy
로 함수를 얻고 numpy
로 처리하는 식으로 함께 사용한다.# gradient : 미분 계산 함수
# init : 시작점, lr : 학습률, eps : 알고리즘 종료조건
var = init
grad = gradient(var)
while (abs(grad) > eps):
var = var - (lr * grad)
grad = gradient(var)
변수가 벡터라면? (변수가 여러개)
벡터가 입력인 다변수 함수의 경우 편미분 사용
편미분
- 단위 벡터를 이용해서 특정 벡터 원소만 변화율을 구함
- 특정 변수만 변수 취급하고 나머지는 상수 취급하여 미분
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)
# 2𝑥+2𝑦−sin(𝑥+2𝑦)
각 변수별로 편미분을 계산한 그레디언트 (gradient) 벡터를 이용하여 경사하강/상승법에 사용할 수 있음
그레디언트 벡터를 사용한 경사하강법 알고리즘
# 위에 있는 변수 하나에 대한 경사하강법과 거의 같음, 그레디언트 벡터는 절대값을 씌울 수 없기 때문에 norm (크기) 를 구함
# gradient : 그레디언트 벡터를 계산하는 함수
# init : 시작점, lr : 학습률, eps : 알고리즘 종료조건
var = init
grad = gradient(var)
while (norm(grad) > eps):
var = var - (lr * grad)
grad = gradient(var)
# norm : L2-노름을 계산하는 함수
# lr : 학습률, T : 학습횟수, beta : 예측값
for t in range(T):
error = y - X @ beta
grad = - transpose(X) @ error
beta = beta - lr * grad
import numpy as np
X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
y = np.dot(X, np.array([1, 2])) + 3
lr = 0.01
beta_gd = [10.1, 15.1, -5] # [1, 2, 3] 이 정답
X_ = np.array([np.append(x, [1]) for x in X]) # intercept 항 추가
for t in range(5000):
error = y - X_ @ beta_gd
# error = error / np.linalg.norm(error)
grad = - np.transpose(X_) @ error
beta_gd = beta_gd - lr * grad
print(beta_gd)
데이터를 전체가 아닌 일부로 파라미터를 업데이트하기 때문에 연산자원을 좀 더 효율적으로 활용하는데 도움이 됨
원리 : 미니배치 연산
BoostCamp AI Tech