편미분(partial derivative) → 입력 변수(독립변수)가 2개 이상인 다변수함수(f(x, y)=x²+2xy+y)에서 미분을 하려면 미분하려는 변수를 제외한 나머지 변수를 상수로 취급하고 해당 변수를 미분하는 방법.
f(x, y)를 변수 x에 대해서 편미분을 하는 경우 ∂(라운드 d)라는 표현을 써요
∂f(x,y) / ∂x
f(x, y) = 2x + 3xy + y³
x 에 대해서 편미분 ∂f(x,y) / ∂x : 2 + 3y + 0 y는 상수기때문에 미분하면 0
y 에 대해서 편미분∂f(x,y) / ∂y : 3x + 3y² x는 상수기때문에 미분하면 0
연쇄 법칙(Chain Rule) : 일반적으로 합성함수(여러 함수로 구성된 함수)를 미분할 때 연쇄 법칙(Chain Rule)을 이용해요.
합성함수를 미분하려면 합성함수를 구성하고 있는 각각의 함수를 미분하고, 그 결과를 다 곱해서 결과를 도출
f(x) = e^3x²3x² → tfunction e^t , function t= 3x²
↓ darivative
∂x/∂f = ∂t/∂f * ∂x/∂t = e^t * 6x = 6x * e^3x²
f(x)=e^-x -x=t
function e^t , function t = -x
↓ darivative
e^t * -1 → -e^t = -e^-x
다변수 함수의 수치미분 코드를 구현해 보아요!!
f(x,y) = 2x+3xy+y³
다변수함수(입력 변수 2개)이기 때문에 수치기 미분을 2번 해야 해요.
f'(1.0,2.0)
1. x=1.0 에서의 미분계수(미분값)를 구해요. y=2.0을 상수로 대입해서 편미분2 +3y = 8
2. y =2.0 에서의 미분계수(미분값)를 구해요. x = 1.0을 상수로 대입해서 편미분
3 + 6y = 15
f'(1.0,2.0) = (8.0, 15.0)
이제 프로그램으로 만들어 보아요!
import numpy as np
# 수치미분 최종함수
# 다변수 함수에 대한 수치미분
# 수치미분을 수헹할 다변수 함수
# f(x,y) = 2x + 3xy + y^3
#f'(1.0, 2,0) => (8.0, 15.0)
# 1. 수치미분을 수행할 함수
def numerical_derivative(f, x):
#f : 미분을 하려고 하는 함수
#x : 모든 독립변수의 값을 포함하고 있는 ndarray(차원에 무관하게 처리할 수 있어야 해요)
delta_x = 1e-4
derivative_x = np.zeros_like(x) # [0.0 0.0]
#iter를 이용해 반복해줘야 차원에 상관없이 반복할 수 있어요
it = np.nditer(x, flags=['multi_index'])
while not it.finished:
idx = it.multi_index
# tmp를 준비하는 이유는 편미분 할 때 값이 변경되지 않아야 하기 때문에 준비해요.
tmp = x[idx] # x : [1.0 2.0] , tmp - 1.0 ,2번반복때 tmp - 2.0
# 중앙차분으로 수치미분하는 식 : (f(x+deltax) - f(x-deltax) / 2 * delta_x)
x[idx] = tmp + delta_x # x : [1.0001 2.0]
fx_plus_deltax = f(x)
x[idx] = tmp - delta_x # x : [0.9999 2.0]
fx_minus_deltax = f(x)
derivative_x[idx] = (fx_plus_deltax - fx_minus_deltax) / (2 * delta_x)
# 현재 데이터(x)가 편미분으로 변했어요! tmp로 원상복귀
x[idx] = tmp # x : [ 1.0 2.0] 으로 원상복귀
it.iternext()
return derivative_x
# 2. 미분할 함수
# 모든 독립변수가 포함된 인자를 받아서 내부에서 분할해서 처리해야 해요!
def my_func(input_value): #함수니까 인자를 2개 받아야 하지만 input_value로 하나로 받아요 #(1.0,2.0)라고 가정
x = input_value[0]
y = input_value[1]
return 2*x + 3*x*y + np.power(y,3)
# 3. 다변수 함수에 대한 수치미분을 실행
# f'(1.0, 2.0)
result = numerical_derivative(my_func,np.array([1.0, 2.0]))
print(result)
#[ 8. 15.00000001]
문제2. 다변수 함수에 대한 수치미분
# 수치미분을 수행할 다변수 함수
# f(a,b,c,d) = 2ab + 3a^2bc + 5cd + 2bd^2
# f'(1.0, 2.0, 3.0, 4.0) ?? => (.. , .. , .. , ..)
# 1. 수치미분을 수행할 함수
def numerical_derivative(f, x):
# f : 미분을 하려고 하는 함수
# x : 모든 독립변수의 값을 포함하고 있는 ndarray(차원에 무관하게 처리할 수 있어야 해요!)
delta_x = 1e-4
derivative_x = np.zeros_like(x) # [0.0 0.0]
it = np.nditer(x, flags=['multi_index'])
while not it.finished:
idx = it.multi_index
tmp = x[idx] # x : [1.0 2.0] , tmp = 1.0
# 중앙차분으로 수치미분하는 식 : (f(x + delta_x) - f(x-delta_x)) / 2 * delta_x
x[idx] = tmp + delta_x # x : [1.0001 2.0]
fx_plus_deltax = f(x)
x[idx] = tmp - delta_x # x : [0.9999 2.0]
fx_minus_deltax = f(x)
derivative_x[idx] = (fx_plus_deltax - fx_minus_deltax) / (2 * delta_x)
x[idx] = tmp # x : [1.0 2.0]
it.iternext()
return derivative_x
# 2. 미분할 함수
# 모든 독립변수가 포함된 인자를 받아서 내부에서 분할해서 처리해야 해요!
# f(a,b,c,d) = 2ab + 6a^bc + 5cd + 2bd^2
# a,b,c,d로 2차원 array를 mapping 시켜 쓸 거예요.(1차원으로 해도 돼요)
def my_func1(input_value):
a = input_value[0,0]
b = input_value[0,1]
c = input_value[1,0]
d = input_value[1,1]
return 2*a*b + 6*np.power(a,2)*b*c + 5*c*d + 2*b*np.power(d,2)
# 3. 다변수 함수에 대한 수치미분을 실행
# f'(1.0, 2.0)
result = numerical_derivative(my_func1,np.array([[1.0, 2.0],
[3.0, 4.0]]))
print(result)
#[[76. 52.]
# [32. 47.]]
'머신러닝 딥러닝' 카테고리의 다른 글
0827Machine Learning에서Linear Regression (0) | 2021.08.27 |
---|---|
0826 회귀(regression ) (0) | 2021.08.26 |
0825 수치미분 (0) | 2021.08.25 |
0825 Machine Learning Process (0) | 2021.08.25 |
0825 지도학습(Supervised Learning) (0) | 2021.08.25 |
댓글