27.1 sin 함수 구현
sin함수의 미분은 y = sin(x)일 때, 그 미분은 ∂y/∂x = 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.sin, np.cos함수를 사용해 구현했습니다.
x = Variable(np.array(np.pi / 4))
y = sin(x)
y.backward()
print(y.data)
print(x.grad)

실제 실행해보니 y값과 x의 미분 모두 0.7071067811865476입니다
1 / np.sqrt(2)와 거의 일치합니다.
27.2 테일러 급수 이론
sin함수의 미분을 다른 방법으로 계산하려고 하는데 그 방법이 테일러 급수를 이용한 방법입니다.
테일러 급수란 어떤 함수를 다항식으로 근사하는 방법입니다.

위의 수식에서 a는 임의의 값이고 f(a)는 점 a에서 f(x)의 값입니다.
f'은 1차 미분, f''는 2차 미분, f'''은 3차 미분을 뜻합니다.
그리고 ! 기호는 팩토리얼을 말하고 n!은 1에서 n까지 모든 정수의 곱을 말합니다.
테일러 급수에 의해 f(x)는 점 a를 기점으로 1차 미분, 2차 미분, 3차 미분...으로 항이 무한히 계속되지만 어느시점에서 중단하면 f(x)의 값을 근사할 수 있습니다. 항이 많아질수록 근사의 정확도가 높아집니다.
a = 0이면
f(x) = f(0) + f'(0)x + 1/2!f''(0)x**2 + 1/3!f'''(0)x**3 + ...
이렇게 되는데 더 간단한 수식이 되었습니다.
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이기 때문에

위의 식을 이끌어낼 수 있습니다.
sin 함수는 x의 거듭제곱으로 이루어진 항들이 무한히 계속되는 형태로 표현됩니다.

n이 커질수록 근사 정밀도가 좋아집니다. n이 커지면 절댓값이 작아지고 이 값을 참고해서 n의 값(반복 횟수)을 적절히 결정할 수 있습니다.
27.3 테일러 급수 구현
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
x = Variable(np.array(np.pi / 4))
y = my_sin(x) # , threshold=1e-150)
y.backward()
print(y.data)
print(x.grad)
for 문 안에서 i번째에 추가할 항목을 t로 하고 임계값을 threshold로 지정하고, t의 절댓값이 threshold보다 낮아지면 for 문을 빠져나오게 합니다.
즉, threshold로 근사치의 정밀도를 조정하는 겁니다.
위의 코드를 돌려보면 아래의 결과가 나옵니다.

위아래의 값이 오차가 굉장히 작아서 거의 같은 결과를 얻을 수 있다고 볼 수 있습니다.
* 테일러 급수의 임계값을 작게 할수록 이론상으로는 근사 정밀도가 좋아지지만 컴퓨터가 하는 계산에서는 '자릿수 누락'이나 '반올림'등이 발생할 수 있습니다.
27.4 계산 그래프 시각화
x.name = 'x'
y.name = 'y'
plot_dot_graph(y, verbose=False, to_file='my_sin.png')

현재 threshold = 0.0001일 때 my_sin 함수의 계산 그래프는 위와 같습니다.
threshold값으로 계산 그래프의 복잡성을 제어하기때문에 threshold = 1e-150으로 설정하고 계산 그래프를 시각화해보겠습니다.
아래처럼 깊은 계산 그래프가 그려집니다. 파이썬의 제어 구문만으로 만들어졌습니다.

'Study 공부할레나' 카테고리의 다른 글
| [스터디/밑시딥3] 제 3고지 고차미분계산_29. 뉴턴 방법으로 푸는 최적화(수동 계산) (0) | 2023.09.09 |
|---|---|
| [스터디/밑시딥3] 제 3고지 고차미분계산_28. 함수 최적화 (1) | 2023.09.06 |
| [스터디/밑시딥3] 제 3고지 고차미분계산_26. 계산 그래프 시각화(2) (0) | 2023.09.03 |
| [스터디/밑시딥3] 제 3고지 고차미분계산_25. 계산 그래프 시각화(1) (1) | 2023.09.03 |
| [스터디/밑시딥3] 제 2고지 자연스러운 코드로_24. 복잡한 함수의 미분 (0) | 2023.08.30 |