What changed with Keras 3, and what does its multi-backend design mean for a team standardized on TensorFlow?
Quick Answer
Keras 3 became a standalone multi-backend framework running on TensorFlow, JAX, or PyTorch. For TF-standardized teams: the Keras API stays familiar, but saving formats split (.keras vs exported SavedModel), some tf.* idioms inside custom layers break backend portability, and JAX becomes an easy performance experiment.
Detailed Answer
Keras 3 (the 'keras' package, replacing tf.keras as the default in TF 2.16+) reimplemented Keras on a backend-agnostic ops layer (keras.ops). Practical implications: (1) Model files — .keras is the native format for checkpoints; deployment to TF Serving goes through model.export(), and loading legacy TF SavedModels as Keras models needs keras.layers.TFSMLayer; (2) custom layers written with raw tf.* calls pin you to the TF backend — writing them with keras.ops keeps the door open to switching the backend to JAX (often free speedups on TPU) with an environment variable; (3) migration gotchas are real: behavior differences in some defaults and removed legacy APIs mean pinned versions and a regression suite matter during the 2.15 -> 2.16+ jump; (4) distribution — the Keras distribution API abstracts over tf.distribute and JAX sharding. Teams commonly stay on the TF backend for serving-stack stability while gaining the option value.
Code Example
# Backend selected before import, no code change
# KERAS_BACKEND=jax python train.py
import keras
class MyLayer(keras.layers.Layer):
def call(self, x):
return keras.ops.relu(x) * keras.ops.sqrt(2.0) # portable, not tf.*Interview Tip
The .keras-vs-export split and TFSMLayer are the concrete details that prove you've actually done the 2.16 migration rather than read the announcement.