티스토리 뷰

수치미분쪽으로 들어가자

 

미분에 대한 정의

  • 어떤 함수의 정의역 속 각 점에서, 독립 변수의 값의 변화량과 함수값의 변화량 비율의 극한 혹은 극한의 집합

  • 치역으로 가지는 새로운 함수

  • 이런 새로운 함수를 구할 수 있는데 이를 미분/ derivate라고 한다.

  • 이런 미분 함수 (도함수)를 구하는 작업을 미분법/ differentiation이라고 한다.

  • 미분은 함수에 있어서 특정 순간의 변화량을 의미한다.
    • x값 에서의 작은 변화가 함수 f(x)를 얼마나 변화시키는가

미분의 정의

  1. 중앙차분방법
    • 가장 정확한 값 도출
  2. 전진차분방법
  3. 후진차분방법

중앙 차분 미분법

 

<수치미분 코드를 Python으로 작성>

  • 입력으로 들어오는 x에서 아주 미세하게 값이 변화할 때 함수 f는 얼마나 변하는가 수치적으로 계산해서 return
  • 일변수 함수 -> 입력되는 값이 Scalar
  • 이변수 함수
  • Python은 일급함수를 지원한다. :

    • 하나의 함수를 다른 함수의 인자로 전달할 수 있다.
    • 일반적으로 외부에서 def, lambda를 이용해서 정의한다.
  • 중앙차분으로 미분을 수행한다.

    • delta_x는 0과 가까운 작은 값을 이용하고 1e-8 이하는 사용하면 안된다.
    • 컴퓨터의 반올림 오차 때문에 엉뚱한 값이 나오게 된다.
    • delta_x1e-4 ~ 1e-6 정도의 수로 설정하면 된다. (1e-4)
    • delta_x = 1e-4 # 0.0001

 

미분 공식 몇개

미분 공식들

 

편미분

편미분

 

연쇄법칙

연쇄 법칙

 

일변수 함수의 수치미분 코드

  • 입력으로 들어오는 x에서 아주 미세하게 값이 변화할 때 함수 f는 얼마나 변하는가 수치적으로 계산해서 return
# f(x) = x^2
# f'(5) = ?

def numerical_derivative(f, x):
    # f : 미분하려는 함수가 들어온다.
    # Python은 일급함수를 지원한다. : 
    # - 하나의 함수를 다른 함수의 인자로 전달할 수 있다.
    # - 일반적으로 외부에서 def, lambda를 이용해서 정의한다.

    # 중앙차분으로 미분을 수행한다.
    # - delta_x는 0과 가까운 작은 값을 이용하고 1e-8 이하는 사용하면 안된다.
    # - 컴퓨터의 반올림 오차 때문에 엉뚱한 값이 나오게 된다.
    # - delta_x는 1e-4 ~ 1e-6 정도의 수로 설정하면 된다. (1e-4)
    delta_x = 1e-4  # 0.0001

    return (f(x + delta_x) - f(x - delta_x)) / (2 * delta_x) 

# 미분하려는 함수를 만든다.
# f(x) = x^2
def my_func(x):
    return x**2

# 함수 f(x) = x**2에서 미분계수 f'(5)를 구한다.
result = numerical_derivative(my_func, 5)
print('result : {}'.format(result))  # 약 10

일변수 함수 미분

 

다변수 함수에 대한 수치미분 코드

  • 실제로 머신러닝, 딥러닝에 사용할 미분코드 작성

  • 다변수 함수인 경우 입력변수가 하나 이상이므로,

  • 이 입력변수들은 서로 독립이기 때문에 수치미분할 때 개별적으로 계산해줘야 한다.

  • f(x, y) = 2x + 3xy + y^3
  • f'(1.0, 5.0) = (8, 15)
# 실제로 머신러닝, 딥러닝에 사용할 미분코드 작성
# 다변수 함수에 대한 미분
# 다변수 함수인 경우 입력변수가 하나 이상이므로,
# 이 입력변수들은 서로 독립이기 때문에 수치미분할 때 개별적으로 계산해줘야 한다.

# f(x, y) = 2x + 3xy + y^3
# f'(1.0, 2.0) = (8, 15)

# 수치미분 최종 코드
import numpy as np

def numerical_derivative(f, x):
    # f: 미분하려고 하는 다변수 함수
    # x : 모든 변수를 포함하고 있어야 한다. ndarray (차원 상관 없이)

    delta_x = 1e-4
    derivative_x = np.zeros_like(x) # 미분한 결과를 저장하는 ndarray

    # iterator를 이용해서 입력변수 x에 대해 편미분을 수행
    it = np.nditer(x, flags=['multi_index'])

    while not it.finished:
        idx = it.multi_index # iterator의 현재 index를 추출
        # 현재 칸의 값을 어딘가에 잠시 저장한다.

        tmp = x[idx]

        x[idx] = tmp + delta_x
        fx_plus_delta = f(x) # f(x + delta_x)

        x[idx] = tmp - delta_x
        fx_minus_delta = f(x) # f(x - delta_x)

        derivative_x[idx] = (fx_plus_delta - fx_minus_delta) / (2 * delta_x)

        x[idx] = tmp # 데이터 원상 복구

        it.iternext()

    return  derivative_x


# 이렇게 구현된 수치미분 함수를 이용하여 일변수 함수 미분하기
def my_func(x):
    return x**2

## f(x) = x^2에서 f'(3) ??
result = numerical_derivative(my_func, np.array([3.0]))
print('일변수 함수 미분')
print('f(x) = x^2, f\'(5) = ?')
print('result: {}'.format(result))

print("=================================================")

# f(x, y) = 2x + 3xy + np.power(y, 3)
# 이렇게 구현된 수치미분 함수를 이용하여 이변수 함수 미분하기
def my_func(input_data):
    x = input_data[0]
    y = input_data[1]
    return 2*x + 3*x*y + np.power(y, 3)

result = numerical_derivative(my_func, np.array([1.0, 2.0]))
print('이변수 함수 미분')
print('f(x, y) = 2x + 3xy + np.power(y, 3)

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함