메서드 두 개, 역할 두 개
Subclass model 은 keras.Model 을 상속하는 Python class 인데, 일을 정확히 두 메서드로 나눠. __init__() 은 *부품 목록* — model 이 가질 layer 를 전부 인스턴스화해서 self 에 붙여. call() 은 *조립* — 입력 tensor 를 받아서 그 layer 들을 통과시켜 출력을 만들어. 그 다음은 Keras 가 가져가 — call() 만 정의해두면 인스턴스가 built-in model 처럼 동작해서 compile(), fit(), evaluate(), save() 다 그대로 돌아가 (Code block 참고).
이 분리가 왜 중요해
이 분리는 취향 문제가 아니야. __init__() 에서 만든 layer 는 model = MyModel() 쓰는 순간 *한 번* 생성되고, 그 weight 가 그때부터 추적돼 — Keras 가 뭘 최적화할지 아는 게 이래서야. call() 은 *매* forward 마다, batch 당 한 번 돌아. 실수로 layer 생성을 call() 안에 넣으면 매 step 마다 학습 안 된 새 weight 가 조용히 만들어지고, tensor 연산을 __init__() 에 넣으면 아직 연산할 tensor 자체가 없어. call() 이 받는 training 인자는 Dropout / BatchNormalization 이 train 모드와 inference 모드를 가르는 스위치 — 신경 쓰는 sub-layer 마다 빠짐없이 넘겨줘.