fit() 은 happy path. training 이 optimizer 두 개 (GAN), gradient accumulation, dynamic loss weighting 필요한 순간 — train_step() override 하거나 tf.GradientTape / torch.autograd / jax.grad 로 manual loop 짠다. 네 backend 다 한 번씩 해본다.
fit() 은 계약이지 감옥이 아냐
대부분은 model.fit() 이면 끝이야. epoch loop, batching, metric 기록, callback, distribution strategy — 이 모든 인프라를 fit() 이 소유해. 이 track 의 목표는 그걸 버리는 게 아니라, 계약이 정확히 어디서 끝나는지 알아서 가장 작은 단위로만 끼어드는 거야. forward-loss-backward 기본 사이클로 표현이 안 되는 경우에만 custom 으로 가:
- GAN — generator / discriminator 번갈아, loss 둘, optimizer 둘
- distillation — teacher 출력을 함께 쓰는 custom loss
- research — gradient 조작, custom regularization, meta-learning
- gradient accumulation — memory 한계에서 큰 batch 흉내
비용 순서대로 세 단계
Keras 가 사다리를 줘. 아래부터 올라가: (1) train_step() override — custom 로직이 여전히 fit() 안에서 돌아. progress bar / callback / distribution 그대로 유지. (2) full manual loop — loop 구조 자체를 제어해야 할 때. (3) backend native API — raw tape 접근이 정말 필요한 드문 경우. 한 칸 올라갈 때마다 *공짜로 받던 인프라*를 *직접 유지해야 하는 제어*와 맞바꿔. track 전체가 결국 '문제를 푸는 가장 낮은 칸에서 멈추는 법'을 가르치는 거야.