728x90
수치미분
1. 미분 (derivative)
- 미분이란 순간변화율 or 접점의 기울기
- 입력변수 x가 미세하게 변할때, 함수 f(x)는 얼마나 변하는가?
- f(x) = x^2 일 경우 f`(x) = 2x
- f(3) = 9 해석 ==> x = 3 에서 출력은 9임을 의미
- f `(3) = 6해석
- 입력 x= 3 을 미세하게 변화시킬때 함수는 현재 입력 값의 2배인 6배 변화를일으킴을 의미\
머신러닝에서 자주 사용되는 함수의 미분공식
f(x) = 3 ==> f`(x) = 0
f(x) = x^n ==> f`(x) = nx^(n-1)
f(x) = e^x ==> f`(x) = e^x
f(x) = lnx ==> f`(x) = 1/x
f(x) = e^(-x) ==> f`(x) = -e^(-x)
2. 편미분 (partial derivative)
편미분은 입력변수가 하나 이상인 다변수 함수에서, 미분하고자 하는 변수 하나를 제외한 나머지 변수들을 상수로 취급하고, 해당 변수를 미분하는것
편미분 예시1
f(x, y) = 2x + 3xy + y^3 , 변수 x에 대하여 편미분
f'(x, y) = x + 3y
편미분 예시2
f(x, y) = 2x + 3xy + y^3 , 변수 y에 대하여 편미분
f'(x, y) = 3x + 3y^2
3. 연쇄법칙 (chain rule)
합성함수란 여러 함수로 구성된 함수로서, 이러한 합성함수를 미분하려면 합성함수를 구성하는 각 함수의 미분의 곱
으로 나타내는 chain rule이용
합성함수 예시1
f(x) = e^(3x^2) 일때, t = 3x^2로 치환하여 ==> f(t) = e^t 가 됨
f(t) = e^t 를 x에 대하여 미분을 진행하기 위해 chain rule을 사용
4. 코드
import numpy as np
def numerical_derivative(f, x): # 수치미분 debug version
delta_x = 1e-4
# [2] 각각의 편미분 결과값을 넣어줄 grad 준비
grad = np.zeros_like(x)
# 함수의 모든 입력값
print("debug 1. initial input variable =", x)
# 결과를 담아줄 배열
print("debug 2. initial grad =", grad)
print("=======================================")
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
# [3] 2 * 2 행렬이 들어오면 1,1=> 1,2 => 2,1 => 2,2 순서대로
# 편미분 하고 grad 에 결과값을 넣어둠
idx = it.multi_index
print("debug 3. idx = ", idx, ", x[idx] = ", x[idx])
tmp_val = x[idx]
x[idx] = float(tmp_val) + delta_x
fx1 = f(x) # f(x+delta_x)
x[idx] = tmp_val - delta_x
fx2 = f(x) # f(x-delta_x)
grad[idx] = (fx1 - fx2) / (2*delta_x) # 미분 공식
print("debug 4. grad[idx] = ", grad[idx]) # 편미분 출력값
print("debug 5. grad = ", grad)
print("=======================================")
x[idx] = tmp_val
it.iternext()
return grad
# 입력변수 4 개인 함수
# f(w,x,y,z) = wx + xyz + 3w + zy^2
# input_obj 는 행렬
def func1(input_obj):
w = input_obj[0, 0]
x = input_obj[0, 1]
y = input_obj[1, 0]
z = input_obj[1, 1]
return ( w*x + x*y*z + 3*w + z*np.power(y,2) )
# 입력을 2X2 행렬로 구성함
input = np.array([ [1.0, 2.0], [3.0, 4.0] ])
# [1] 함수 func1와 input를 준비
numerical_derivative( func1, input )
# 입력값과 편미분 결과를 넣어줄 배열
debug 1. initial input variable = [[1. 2.]
[3. 4.]]
debug 2. initial grad = [[0. 0.]
[0. 0.]]
=======================================
debug 3. idx = (0, 0) , x[idx] = 1.0
debug 4. grad[idx] = 5.000000000023874
debug 5. grad = [[5. 0.]
[0. 0.]]
=======================================
debug 3. idx = (0, 1) , x[idx] = 2.0
debug 4. grad[idx] = 13.00000000000523
debug 5. grad = [[ 5. 13.]
[ 0. 0.]]
=======================================
debug 3. idx = (1, 0) , x[idx] = 3.0
debug 4. grad[idx] = 32.00000000006753
debug 5. grad = [[ 5. 13.]
[32. 0.]]
=======================================
debug 3. idx = (1, 1) , x[idx] = 4.0
debug 4. grad[idx] = 15.000000000000568
debug 5. grad = [[ 5. 13.]
[32. 15.]]
=======================================
func1함수 내에서 w, x, y, z를 (0,0), (0,1), (1,0), (1,1)로 정의했다
그래서 numerical_derivative의 while문을 돌때마다 idx값이 0,0부터 시작해서 1,1까지 진행하는데 w부터 편미분을 진행해서 z까지 끝낸 결과를 grad 배열에 넣어준다.
728x90
'Data Science > 머신러닝' 카테고리의 다른 글
딥러닝 기초 나만의 정리 2 (0) | 2020.09.16 |
---|---|
딥러닝 기초 나만의 정리 (0) | 2020.07.08 |
LSTM으로 IMDB 리뷰 감성 분류하기 (0) | 2020.07.02 |
Logistic Regression(Classification) 나만의 정리 (0) | 2020.06.28 |
Linear Regression 나만의 정리 (2) | 2020.06.27 |
지도학습과 비지도학습 나만의 정리 (0) | 2020.06.26 |
matplotlib 라이브러리 (0) | 2020.06.25 |
numpy 라이브러리 (1) | 2020.06.24 |