graph 로도 부족할 때 — call() 안에 조건부 흐름이 필요하거나, shape 가 dynamic 하거나, custom training step 필요하거나 — keras.Model 또는 keras.layers.Layer 를 subclass 해. *그냥 Python 으로 써버리겠다* 의 escape hatch. 대가: 자동 introspection (model.summary(), plot_model) 이 subclass 부분에서는 X-ray 시야 잃는다.
탈출구, 그리고 그 비용
Sequential / Functional API 는 model 을 *정적 graph* 로 그려 — 데이터가 흐르기 전에 layer 배선이 다 정해져. 그 graph 덕분에 model.summary(), shape 추론, plot_model() 이 돌아가는 거야: Keras 가 한 번도 실행 안 하고 전체 topology 를 읽거든. Subclass 는 그 graph 를 *그냥 Python* 으로 바꿔. call() 을 평범한 메서드처럼 쓰면 forward 가 네 코드가 하는 모든 것이 돼 — 정적 graph 가 표현 못 하는 것까지 포함해서.
꺼내 쓸 때:
- forward 가 입력 자체로 분기할 때 — tree-structured net, mixture-of-experts routing, 데이터가 경로를 정하는 모든 것
- forward 안에 진짜 Python 제어 흐름 (
if/else, 가변 횟수 loop) 이 필요할 때 - architecture 가 연구하면서 계속 움직여서, graph 재배선 말고 로직만 고치고 싶을 때
- 계산이 애초에 정적 DAG 가 아닐 때 — recurrent state machine, custom autoregressive decoding
비용을 똑바로 보면
Subclass model 은 config dict 만으로 복원 안 되고, 실제 데이터로 한 번 call 하기 전엔 graph 로 들여다볼 수 없고, 중간 activation 도 Functional 만큼 깔끔하게 안 줘. 그러니 질문은 '어느 API 가 더 나아?' 가 아니라 '내 model 중 *진짜로* Python 이 필요한 부분이 얼마나 돼?' 야.
권장 패턴이 이 긴장을 풀어: 동적인 조각만 *layer* 로 subclass 하고, 그 layer 들을 Functional API 로 정적 뼈대에 엮어. introspection 비용은 그럴 만한 몇 개 block 에만 내고, 나머지 model 은 X-ray 로 보여. 다음 lesson 들이 정확히 이걸 쌓아 — 먼저 raw subclass 기계장치, 그 다음 두 API 가 만나는 seam.