Goldstein-Price 함수를 수식으로 표현하면 다음과 같습니다.
f(x, y) = [ 1 + ( x + y + 1) ** 2 * (19 - 14x + 3 * x ** 2 - 14 * y + 6 * x * y + 3 * y ** 2)]
[30 + ( 2 * x - 3 * y) ** 2 * (18 - 32 * x + 12 * x ** 2 + 48 * y - 36 * x * y + 27 * y ** 2)]
꽤 복잡해 보이지만 DeZero라면 어렵지 않게 표현할 수 있습니다. 직접 보시죠.
def goldstein(x, y):
z = ( 1 + ( x + y + 1) ** 2 * ( 19 - 14*x + 3*x**2 - 14*y + 6*x*y * 3*y**2)) * \
(30 + (2*x - 3*y)**2 * (18 - 32*x + 12*x**2 + 48*y - 36*x*y + 27*y**2))
return z
수식과 비교해가며 코드로 옮기면 금방 끝날 것입니다. 반면 이 연산자들을 사용하지 않고 코딩하기란 보통 사람에게는 불가능할지 모릅니다. 그럼 Goldstein-Price 함수를 미분해볼까요?
x =Variable(np.array(1.0))
y = Variable(np.array(1.0))
z = goldstein(x, y)
z.backward()
print(x.grad, y.grad)
variable(-10074.0) variable(60336.0)
x에 대한 미분은 -5376.0이 나왔고, y에 대한 미분은 8064.0이 나왔습니다. 물론 올바른 결과입니다. 보다시피 DeZero는 Goldstein-Price 함수와 같은 복잡한 계산도 훌륭하게 미분할 수 있답니다! 또한 이 결과가 맞는지는 기울기 확인으로 검증할 수 있습니다. 이것으로 두 번째 고지도 무사이 정복했습니다.
이번 제2고지에서 DeZero가 크게 성장했습니다. 고지 점령을 시작할 무렵의 DeZero는 간단한 계산밖에 할 수 없었지만 지금은 복잡한 계산도 가능하게 되었습니다.(엄밀히 말하면 아무리 복잡하게 '연결'된 계산 그래프라도 올바르게 역전파할 수 있습니다). 또한 연산자를 오버로드한 덕에 보통의 파이썬 프로그래밍처럼 코드를 작성할 수 있습니다. 일반적인 파이썬 연산자를 이용해도 미분을 자동으로 계산할 수 있기 때문에 DeZero는 '일반적인 프로그래밍'을 '미분 가능'하게 만들었다고 표현할 수도 있습니다.
이제 DeZero의 기초는 충분히 닦았습니다. 다음 단계부터는 더 고급 계산도 처리할 수 있도록 DeZero를 확장해갈 것입니다.
댓글 없음:
댓글 쓰기