backend before importKERAS_BACKEND must be set before import keras; it cannot change after
keras.ops, not tf.* or torch.*the one swap that keeps a custom layer portable across backends
built-ins are portable alreadya model of only built-in layers runs on all four backends unchanged
weights go in build()and without get_config() the layer cannot be reloaded
keras.random, not Python randomstateless RNG is what makes custom layers work under JAX tracing
.keras or .h5, never baresave("path") raises; export() is what makes a SavedModel
load_model can't read SavedModeluse keras.layers.TFSMLayer for that
from_logits must matcha softmax layer plus from_logits=True trains on nonsense, silently
loss_fn(y_true, y_pred)true label first
clipnorm is on the optimizernot in the training loop
metrics are statefulreset_state() each epoch or you average over all of training
adapt() on features onlypass ds.map(lambda x, y: x), not the whole dataset
augmentation layers self-disableactive in training, bypassed at inference — no flag needed
keras-preprocessing is archivedfinal release 1.1.2 (2020); in Keras 3 it survives only under _legacy
Tokenizer → TextVectorizationand it belongs inside the model, so the vocabulary can't drift
Sequence → PyDatasetsame two methods, new name, better multiprocessing
on torch, a layer IS an nn.Moduleso torch optimizers, DDP and state_dict() just work
torch backend needs zero_grad()gradients accumulate; forgetting it is the classic bug there
training=True, not model.train()the Keras kwarg is what switches Dropout and BatchNorm
a raw loop is never portableoverride compute_loss or train_step if you want to keep backends open
quantize, then enable_lorathat order is QLoRA; adapters stay full precision
don't load untrusted .h5Keras 3.12.3 was a security release hardening exactly that path