두 메서드가 부품과 계산을 나눠 맡아
keras.Model을 상속한 Python 클래스는 일을 두 메서드로 나눠. __init__()에서는 모델이 사용할 레이어를 모두 만들어 self에 저장하고, call()에서는 입력 텐서를 그 레이어에 통과시켜 출력을 만들어. 이 두 부분만 올바르게 정의하면 compile(), fit(), evaluate(), save() 같은 Keras 기능을 기본 모델과 똑같이 사용할 수 있어.
레이어 생성과 텐서 계산을 섞지 마
__init__()의 레이어는 model = MyModel()을 실행할 때 한 번 만들어지고 Keras가 그 가중치를 추적해. 반면 call()은 배치마다 순전파를 할 때마다 실행돼. 레이어를 call() 안에서 만들면 매 단계마다 학습되지 않은 새 가중치가 생기고, 텐서 계산을 __init__()에 넣으면 아직 입력 텐서가 없어 실행할 수 없지. call()의 training 인자는 Dropout과 BatchNormalization이 학습과 추론 동작을 구분하는 스위치이므로 관련 하위 레이어에 빠짐없이 전달해야 해.