시험공부빅데이터분석
← 보드클래스와 상속 · 10/12

model(x)의 내부 — __call__이 forward를 불러요 ★★★

그런데 이상한 점이 있어요. 우리는 model(x)라고만 썼는데 forward가 실행됐어요. 왜일까요?

MyModel에는 __call__이 없어요. 하지만 부모 nn.Module에 __call__이 이미 정의되어 있고 우리는 그것을 상속받았어요. 그래서 model(x)는 부모의 __call__을 실행하고, 그 안에서 forward(x)를 불러요. 4-8에서 본 AffineFunction의 진짜 버전이에요.

model(x)에서 forward까지의 호출 과정
교수님 슬라이드 — model(x) → nn.Module.__call__(x) → ① hook ② 상태관리 함수 ③ model.forward(x) → 출력 Tensor
순서일어나는 일
1model(x) — 객체에 괄호를 붙여 불러요
2부모(nn.Module)에서 상속받은 __call__(x)가 실행돼요
3그 안에서 ① hook 실행(따로 정의한 경우만), ② 그 밖의 상태 관리 처리, ③ 자식이 정의한 forward(x) 실행
4forward가 돌려준 값이 y(출력 Tensor)가 돼요. forward를 안 만들어 두었으면 에러
하지 말아야 할 두 가지

① model.forward(x)를 직접 호출하지 않아요. hook 등 __call__ 안의 부가 처리를 모두 건너뛰어요. ② __call__을 다시 정의(재정의)하지 않아요. nn.Module의 호출 기능이 정상 동작하지 않을 수 있어요. 올바른 사용은 연산은 forward()에 정의하고, 호출은 항상 y = model(x)예요. (계산 결과는 둘 다 나오지만 부가 기능이 빠지는 것이 문제예요.)

시험엔 이렇게 써요 — 이렇게 고르세요

model(x)는 nn.Module에서 상속받은 __call__()의 처리(hook, 상태 관리)를 거쳐 자식 class에서 정의한 forward()를 실행한다. 그래서 forward()를 직접 호출하거나 __call__()을 재정의하지 않고 항상 model(x) 형태로 호출한다. forward()가 없으면 에러가 발생한다.

잠깐 확인 — MyModel에는 __call__이 없는데 model(x)가 동작하는 이유는?

부모 nn.Module에 __call__이 정의되어 있고 MyModel이 그것을 상속받았기 때문이에요. 그 __call__이 forward를 불러요.

다음 카드 → 시험 샘플 3번 풀기 — 빈칸 (A), (B)와 호출 과정 ★★★

자료: 3~4주차 · Week03_Class_for_PyTorch(pdf, ipynb 업데이트본) · 빅데이터03(3주차)·빅데이터04(4주차) 녹취