페이지

2022년 8월 19일 금요일

15.2 현재의 DeZero

 우리 DeZero는 어떻게 구현되어 있는지 살펴보겠습니다. [그림 15-4]의 순서로 연전파하고 있을 까요? 다음 Variable 클래스의 현재 모습입니다. 음영 부분만 주목해보죠.


눈여겨 볼 대상은 funcs리스트입니다. while 블럭의 마지막 줄을 보면 처리할 함수의 후보를 funcs 리스트의 끝에 추가하고 있습니다(funcs.apppend(x.creator)). 그리고 다음에 처리할 함수를 그 리스트의 끝에서 꺼냅니다(funcs.pop()). 이코드대로 진행하면 역전파의 흐름이 [그림 15-5]처럼 됩니다.


[그림 15-5]와 같이 함수의 처리 순서는 D, C, A, B, A가 됩니다. C다음에 A로 바로 이어지는 게 문제군요. 그리고 함수 A의 역전파가 두 번일어나는 것도 문제입니다. 왜 이런 문제가 일어나는지 앞의 코드와 비교하면서 살펴보겠습니다.


가장 먼저 funcs리스트에 D가 추가되어 [D]상태로 시작됩니다. 여기에서 함수 D가 꺼내지고, 그런 다음 D의 입력 변수(D.input)의 창조자인 B와 C가 functions리스트에 추가됩니다(그림 15-6).


이 시전에서는 funcs리스트는 [B, C]입니다. 그런 다음 리스트의 마지막 원소인 C가 꺼내집니다. 그리고 C의 입력 변수의 창조자인 A가 리스트에 추가됩니다. 이 시점의 funcs리스트는 [B, A] 입니다(그림 15-7).


이어서 다시 마지막 원소인 A가 꺼내집니다. 여기서 바로 문제를 일으키는 부분입니다. 원래는 B를 꺼내야 하는데 A를 꺼낸 것이죠.


지금까지 우리는 한줄로 나열된 계산 그래프를 다뤘습니다. 그래서 리스트에서 원소(함수)를 꺼내 처리하는 순서를 고려하지 않아도 괜찮습니다. 리스트에서 원소를 꺼낼 때는 항상 원소가 하나뿐이었기 때문입니다.

댓글 없음: