개선된 Variable 클래스를 사용하여 실제로 미분을 해봅시다. 7단계에서와 똑같은 코드를 실행해보겠습니다.
A = Square()
B = Exp()
C = Square()
x = Variable(np.array(0.5))
a = A(x)
b = B(a)
y = C(b)
# 역전파
y.grad = np.array(1.0)
y.backward()
print(x.grad)
3.297442541400256
결과도 이전과 똑같습니다. 이상으로 '재귀'에서 '반복문'으로 구현 방식을 전환했습니다. 반복문 방식의 이점은 15단계에서 알 수 있습니다. 15단계에서는 복잡한 계산 그래프를 다루는데, 받금 전환한 구현 덕분에 부르럽게 확장할 수 있습니다. 처리효율도 반복문 방식이 뛰어납니다.
재귀는 함수를 재귀적으로 호출할 때마다 중간 결과를 메모리에 유지하면서(스택에 쌓으면서)처리를 이어갑니다. 일반적으로 반복문 방식이 효율이 더 좋은 이유입니다. 그러나 요즘 컴퓨터는 메모리가 넉넉한 편이라서 조금 더 사용한느 건 그리 문제가 되지 않습니다 또한 '꼬리 재귀(tail recursion)'기법을 이용하여 재귀를 반복문처럼 실행할 수 있는 경우도 있습니다.
이상으로 역전파 구현의 기반은 완성했습니다. 앞으로는 더욱 복잡한 계산도 가능하도록 현재의 DeZero를 확장해나갈 것입니다. 하지만 그전에 다음 단계에서 DeZero의 '사용자 편의성'부터 개선하겠습니다.
댓글 없음:
댓글 쓰기