본문 바로가기
AI/딥러닝 프레임워크 개발

27단계) 테일러 급수 미분

by 채채씨 2021. 6. 29.
728x90
반응형

이번에는 DeZero를 사용하여 sin 함수의 미분 문제를 풀어볼 것이다. sin 의 미분은 해석적으로 풀리지만 정공법으로 sin 함수를 DeZero로 구현하고 그 미분을 테일러 급수를 이용해서 계산할 것이다.

1. sin 함수 구현

y = sin(x) 일때 그 미분은 y'=cos(x) 이다.

import numpy as np from dezero import Function class Sin(Function): def forward(self, x): y = np.sin(x) return y def backward(self, gy): x = self.inputs[0].data gx = gy * np.cos(x) return gx def sin(x): return Sin()(x)

넘파이가 제공하는 np.sinnp.cos 함수를 사용하여 구현하였다. x = π / 4 에서 y=sin(x) 를 미분하면 다음과 같다.

from dezero import Variable x = Variable(np.array(np.pi/4)) y = sin(x) y.backward() print(y.data) #0.7071067811865476 print(x.grad) #0.7071067811865476


y값과 x의 미분값이 똑같고 1/np.sqrt(2) 와 거의 일치한다. sin(π / 4) = cos(π / 4) = 1/루트2 이므로 올바른 결과이다.


2. 테일러 급수 이론

이번에는 sin 함수의 미분을 테일러 급수(Taylor Series)를 이용하여 계산할 것이다. 테일러 급수란 어떤 함수를 다항식으로 근사하는 방법으로 수식은 다음과 같다.

테일러 급수


위의 식은 점 a 에서 f(x) 의 테일러 급수이다. 테일러 급수에 의해 f(x) 는 점 a 를 기점으로 위의 식처럼 나타낼 수 있다. 1차 미분, 2차 미분, 3차 미분 , ... 식으로 항이 무한히 계속되지만 어느 시점에서 f(x)의 값을 근사할 수 있다. 항이 많아질 수록 근사의 정확도는 높다.


a = 0일 때의 테일러 급수를 매클로린 전개(Maclaurin's series)라고도 한다.

매클로린 전개


이제 f(x) = sin(x) 함수를 위의 매클로린 전개식에 적용해볼 것이다. f'(x) = cos(x), f''(x) = -sin(x), f'''(x) = -cos(x), f''''(x) = sin(x), ... 의 형태가 반복되며 sin(0) = 0, cos(0) = 1이므로 다음과 같은 식을 도출할 수 있다.


i가 커질 수록 근사 정밀도는 좋아지며, 시그마 내 식의 절대값은 작아진다. 0에 수렴하도록 지그재그가 그려지며 결국 어느 순간에는 더 추가해도 함수에 영향을 미치지 않는다. 이를 참고하여 i의 값을 적절히 결정해야 한다.


3. 테일러 급수 구현
import math def my_sin(x, threshold=0.0001): y = 0 for i in range(100000): c = (-1) ** i / math.factorial(2 * i + 1) t = c * x ** (2 * i + 1) y = y + t if abs(t.data) < threshold: break return y

threshold로 임곗값을 지정하고 t의 절댓값이 thredhold보다 낮아지면 for문을 빠져나오게 한다. thredhold가 작을수록 정밀도가 높다.

x = Variable(np.array(np.pi/4)) y = my_sin(x) y.backward() print(y.data) #0.7071064695751781 print(x.grad) #0.7071032148228457

해석적으로 계산한 미분값과 비교하면 오차는 무시할 정도로 작고 sin함수와 거의 같은 결과이다.

728x90
반응형

댓글