model(x)의 내부 — __call__이 forward를 불러요 ★★★
그런데 이상한 점이 있어요. 우리는 model(x)라고만 썼는데 forward가 실행됐어요. 왜일까요?
MyModel에는 __call__이 없어요. 하지만 부모 nn.Module에 __call__이 이미 정의되어 있고 우리는 그것을 상속받았어요. 그래서 model(x)는 부모의 __call__을 실행하고, 그 안에서 forward(x)를 불러요. 4-8에서 본 AffineFunction의 진짜 버전이에요.

| 순서 | 일어나는 일 |
|---|---|
| 1 | model(x) — 객체에 괄호를 붙여 불러요 |
| 2 | 부모(nn.Module)에서 상속받은 __call__(x)가 실행돼요 |
| 3 | 그 안에서 ① hook 실행(따로 정의한 경우만), ② 그 밖의 상태 관리 처리, ③ 자식이 정의한 forward(x) 실행 |
| 4 | forward가 돌려준 값이 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~4주차 · Week03_Class_for_PyTorch(pdf, ipynb 업데이트본) · 빅데이터03(3주차)·빅데이터04(4주차) 녹취