머신러닝

[머신러닝] 수치 미분 - 편미분, 연쇄 법칙

jmkimmessi 2020. 7. 18. 16:47
반응형

 

수치 미분(Numerical Derivative)

이상적으로 주어진 함숫값을 이용하여 도함수의 근삿값을 구하는 것

 

편미분 (partial derivative)

편미분은 입력 변수가 하나 이상인 다변수 함수에서, 미분하고자 하는 변수 하나를 제외한 나머지 변수들은 상수로 취급하고, 해당 변수를 미분하는 것

 

ex) $ f(x, y) = 3x + 4xy + y^{2} $ , 변수 x에 대하여 편미분

$$\frac{∂f(x,y)}{∂x} = \frac{∂(3x + 4xy + y^{2})}{∂x} = 3 + 4y$$

 

연쇄 법칙(chain rule)

합성함수를 미분하려면 합성함수를 구성하는 각 함수의 미분의 곱으로 나타내는 연쇄 법칙(chain rule) 이용.

 

합성함수 예시)

$f(x) = e^{3x} \Rightarrow$ 함수 $e^{t}$ , 함수 $t = 3x$ 조합

 

$f(x) = e^{3x}$ 을 연쇄 법칙으로 미분하면, $t = 3x$ 로 놓으면 $f(x) = e^{t}$

 

$$\frac{\partial f}{\partial x} = \frac{\partial f}{\partial t} \frac{\partial t}{\partial x} = \frac{\partial (e^{t})}{\partial t} \frac{\partial (3x)}{\partial x} = (e^{t})(3) \\ =  (e^{3x})(3) = 3e^{3x}$$

 

 

 

변수가 하나인 식의 수치미분

$$f'(x) = \frac{df(x)}{dx}=\lim_{\Delta x\rightarrow 0} \frac{f(x+\Delta x) + f(x)}{\Delta x} \\ = \lim_{\Delta x\rightarrow 0}\frac{f(x+\Delta x) - f(x-\Delta x)}{2\Delta x}$$

 

이 식을 그대로 Python 코드로 구현을 하면 아래와 같은 코드가 나온다.

def numerical_derivative(f,x):
    delta_x = 1e-4
    return (f(x+delta_x) - f(x-delta_x)) / (2*delta_x)

def my_func1(x):
    return x**2

result = numerical_derivative(my_func1,3)

print("result ==", result)

$x^2$ 을 수치 미분하는 예제 코드

delta_x에 적당히 작은 수 1e-4를 넣는다.

수치 미분을 하면 result값은 6에 가까운 수가 나온다.


import numpy as np

def my_func2(x):

    return 3*x*(np.exp(x))

def numerical_derivative(f,x):
    delta_x = 1e-4
    return (f(x+delta_x) - f(x-delta_x)) / (2*delta_x)

result = numerical_derivative(my_func2,2)

print("result ==", result)

$3xe^x$ 를 수치 미분하는 예제 코드

result 값은 66.5에 가까운 수가 나온다.

 

변수가 둘 이상인 식의 수치 미분

입력 변수가 하나 이상인 다변수 함수의 경우, 입력 변수는 서로 독립적이기 때문에 수치 미분 또한

변수의 개수만큼 개별적으로 계산하여야 한다.

 

ex) $ f(x, y) = 3x + 4xy + y^{2} $ 이면, 입력 변수가 x, y 두 개 이므로 $\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}$ 각각 수치미분 수행.

$f'(2.0, 1.0)$ 값을 계산하기 위해서는, 

 

$\Rightarrow x = 2.0$ 에서의 미분계수는 변수 $ y=1.0$ 을 상수로 대입하여, $\frac{\partial f(x,1)}{\partial x}$ 를 수행

$\Rightarrow y = 1.0$ 에서의 미분계수는 변수 $ x=2.0$ 을 상수로 대입하여, $\frac{\partial f(2,y)}{\partial y}$ 를 수행

 

이를 코드로 구현하면, 아래와 같은 코드가 나온다.

import numpy as np

def numerical_derivative(f,x):
    delta_x = 1e-4
    grad = np.zeros_like(x)

    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])

    while not it.finished:
        idx = it.multi_index

        tmp_val = x[idx]
        x[idx] = float(tmp_val) + delta_x
        fx1 = f(x)

        x[idx] = tmp_val - delta_x
        fx2 = f(x)
        grad[idx] = (fx1 - fx2) / (2*delta_x)

        x[idx] = tmp_val
        it.iternext()

    return grad

문자가 둘 이상인 식인 수치 미분 코드

iterater가 문자의 개수만큼 돌 때, 그 문자에 대한 편미분을 통해 수치미분 값을 반환한다.

 

이 두 가지 종류의 코드들은 머신러닝을 할 때 중요하게 쓰이는 코드들이다.

 

반응형