본문 바로가기
프로그래밍/머신러닝

numpy에서 머신러닝 - 다변수 함수의 수치 미분

by 조이써니 2020. 9. 21.
반응형

1. 편미분

다변수 함수의 미분은 편미분을 사용한다. 편미분이란 미분 할 하나의 변수를 제외한 나머지 변수를 상수 취급해 미분하는 것이다. \( \frac{\partial f}{\partial x}  \)는 x가 변함으로써 함수 f가 얼마나 변하는 변화량을 보여준다. 편미분에서는 \( dx \)대신에 \(\partial x \)를 사용한다. 예시로 \(f(x) = x^2 + y^3 \) 함수에 대해 (1, 2)에서의 미분하는 과정을 보겠다.

 

$$ \frac{\partial f}{\partial x}(x, y) = 2x $$$$ \frac{\partial f}{\partial x}(1, 2) = 2  $$ $$ \frac{\partial f}{\partial y}(x, y) = 3y^2$$$$\frac{\partial f}{\partial y}(1, 2) = 12  $$

참고 동영상을 보면 편미분에 대해 자세히 알 수 있다. 외국자료이지만 한국어 자막이 있어서 부담없다.

 

편미분 코드

import numpy as np

def fun1(input_value):
    x = input_value[0]
    y = input_value[1]
    return x**2 + y**3

def partial_derivative(f, x):
    dx = delta_x = 0.0001
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    grad = np.zeros_like(x)
    while not it.finished:
        ind = it.multi_index
        
        rep = x[ind]
        x[ind] = rep + dx
        fx1 = f(x)

        x[ind] = rep - dx
        fx2 = f(x)
        grad[ind] = (fx1 - fx2) / (2 * dx)
        
        x[ind] = rep
        it.iternext()
    return grad
    
x = np.array([1, 2], dtype=np.float64)
print(partial_derivative(fun1 , x))
print(x.dtype)

 

[ 2.         12.00000001]
dtype('float64')

해석적으로 편미분한 값이 (2, 12)가 나왔다. 수치미분으로 구한 값도 (2. ,12.00000001)이 나와 거의 동일하다.

 

np.nditer

np.nditer는 요소 하나하나의 접근해 설정의 따라 값을 알려주는 함수다. 공식 문서에 가면 자세한 설명을 찾을 수 있다. multi_index 함수를 통해 array요소의 인덱스 값을 구할 수 있다. 위 코드에 접근한 인덱스에서 편미분 방정식을 구한다. 방정식을 구하면 iternext 함수를 사용해 다음 인덱스로 이동한다. 인덱스가 있으면 True 더 이상 없으면 False 값을 반환한다. iternext와 반대로 finished함수는 다음 인덱스가 있으면 False 없으면 True값을 반환한다. 

 

데이터 타입

x = np.array([1, 2])
print(partial_derivative(fun1 , x))
print(x.dtype)

 

[5000, 35000]
int32

array를 생성할 때 정수만 입력하게 되면 요류가 발생한다. 이유는 정수만 입력하게 되면 데이터 타입이 in32로 설정되 정수만 계산되기 때문이다. 이를 해결하려면 array를 생성할 때 dtype='float64'를 입력하거나 [1.0, 2.0]처럼 뒤에 .0을 입력해주면 데이터 타입이 float64로 설정된다.

반응형

댓글