Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Keras Administrator & Developer Guide

Generated May 2026 from keras-team/keras at b800fdf

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Keras 3.15.0 — Multi-backend deep learning framework for Python. Build models once and run them on TensorFlow, JAX, PyTorch, NumPy, or OpenVINO without changing a single line of model code.

This guide covers architecture internals, configuration, deployment patterns, performance tuning, security, and developer workflows. For installation, everyday usage, and model-building tutorials, see the User Guide.


1. Architecture Overview

Keras 3 is a ground-up rewrite that decouples the high-level modeling API from any single computation backend. The architecture consists of five major subsystems: backend dispatch, layer/model hierarchy, training loop, serialization, and ops abstraction.

1.1 Backend Dispatch

Backend selection happens exactly once — at import keras time — and is immutable for the lifetime of the process. The selection logic in keras/src/backend/__init__.py follows this priority:

  1. KERAS_BACKEND environment variable (highest priority)
  2. "backend" key in ~/.keras/keras.json
  3. Default: "tensorflow"

Once resolved, the backend module (keras.src.backend.{name}) is loaded via wildcard import, making all backend-specific implementations available through a single namespace. Each backend implements a standardized set of modules:

Module Purpose
core.py Tensor creation, casting, basic operations
nn.py Neural network primitives (conv, pool, softmax)
numpy.py NumPy-compatible array operations
math.py Mathematical functions
image.py Image processing operations
linalg.py Linear algebra
random.py Random number generation
rnn.py Recurrent network operations
trainer.py Backend-specific training loop
layer.py Backend-specific layer behavior
export.py Model export to backend-native formats

JAX and TensorFlow backends additionally implement distribution_lib.py for multi-device distributed training. NumPy and OpenVINO backends set distribution_lib = None — these are inference-only backends that do not support training or distribution.

Note

When the active backend is anything other than TensorFlow, Keras automatically sets TF_FORCE_GPU_ALLOW_GROWTH=true to prevent TensorFlow (which may still be installed as a dependency) from pre-allocating all GPU memory. This is critical in environments where JAX or PyTorch needs GPU access.

1.2 Layer and Model Hierarchy

The class hierarchy is:

Operation
  └── Layer
        └── Model (also inherits Trainer)
              ├── Sequential
              └── Functional

Layer (keras/src/layers/layer.py) is the fundamental building block. It implements:

  • Deferred weight creation via build() — weights are allocated on first call when input shapes are known
  • Forward pass via call()
  • Automatic variable tracking through the Tracker utility (keras/src/utils/tracking.py), which wraps Python containers (TrackedList, TrackedDict, TrackedSet, TrackedOrderedDict) to monitor attribute mutations
  • Serialization via get_config() / from_config()
  • Quantization via quantize(mode) and LoRA via enable_lora(rank)
  • Name scoping via keras.name_scope for hierarchical naming

Model (keras/src/models/model.py) adds training capabilities. Its __new__ method inspects the active backend at instantiation time and returns a backend-specific Trainer subclass (JAX Trainer, TF Trainer, Torch Trainer, NumPy Trainer, or OpenVINO Trainer). This is transparent to user code.

Three model construction patterns:

Pattern Class How It Works
Subclassing Model Override call(), imperative style
Sequential Sequential Linear layer stack via add() / pop()
Functional Functional DAG from Input() → layer calls → Model(inputs, outputs)

Sequential validates that each layer accepts a single positional argument and auto-creates an InputLayer when batch_shape is provided. Functional builds a directed acyclic graph and uses _run_through_graph() for graph traversal, supporting optional inputs.

1.3 Operations System

The keras/src/ops/ package provides backend-agnostic mathematical operations. These are not thin wrappers — each op has a symbolic path (for graph tracing) and a concrete path (for eager execution):

  • core.py: Control flow — scan, while_loop, cond, fori_loop, stop_gradient, custom_gradient, vectorized_map
  • numpy.py: Full NumPy-compatible API (200+ functions)
  • nn.py: Neural network operations — convolutions, pooling, activations, normalization
  • math.py: Mathematical operations beyond NumPy
  • image.py: Image processing (resize, crop, affine transforms)
  • linalg.py: Linear algebra (solve, SVD, cholesky, etc.)
  • einops.py: Einstein notation operations (rearrange)

The Operation base class (keras/src/ops/operation.py) tracks computation graphs via Node objects (keras/src/ops/node.py). The Function class (keras/src/ops/function.py) traces operations into a reusable computation graph.

1.4 Trainer System

The training loop (keras/src/trainers/trainer.py) implements compile(), fit(), evaluate(), and predict(). Compilation binds a loss function, optimizer, and metrics to the model via compile_utils.py.

Data flows through data adapters (keras/src/trainers/data_adapters/), which normalize different input formats into a consistent iterator interface:

Adapter Input Type
ArrayDataAdapter NumPy arrays, lists
TFDatasetAdapter tf.data.Dataset
TorchDataLoaderAdapter torch.utils.data.DataLoader
PyDatasetAdapter keras.utils.PyDataset (multiprocessing)
GeneratorDataAdapter Python generators
GrainDatasetAdapter Grain datasets (JAX ecosystem)

The EpochIterator (epoch_iterator.py) manages epoch/step iteration, calling the appropriate data adapter and yielding batches.

1.5 Serialization Architecture

Keras uses a layered serialization system in keras/src/saving/:

  • .keras format (saving_lib.py): A zip archive containing config.json (model topology + layer configs) and model.weights.h5 (weights in HDF5). This is the primary save format.
  • Object serialization (serialization_lib.py): Converts arbitrary Keras objects to/from JSON-safe dictionaries using a class registry. Custom objects must be registered via @keras.saving.register_keras_serializable.
  • Object registration (object_registration.py): Global registry mapping class names to implementations.
  • File editor (file_editor.py): Allows in-place editing of saved model files without full deserialization.
  • Orbax integration (orbax_util.py): JAX checkpointing via the Orbax library.
  • Legacy (keras/src/legacy/saving/): HDF5 format support for backward compatibility.

1.6 Export Subsystem

The export system (keras/src/export/) converts trained models to deployment-ready formats:

Format Module Requirements
TF SavedModel saved_model.py TensorFlow backend or installed
LiteRT (TFLite) litert.py TensorFlow backend required
ONNX onnx.py, tf2onnx_lib.py tf2onnx package
OpenVINO IR openvino.py openvino package
Neptune neptune_model_export_archive.py Neptune SDK

The TFSMLayer class (tfsm_layer.py) enables loading a TF SavedModel back as a Keras layer, enabling interop with non-Keras TensorFlow models.

1.7 Quantization Architecture

Keras supports post-training quantization through keras/src/quantizers/:

Mode Implementation Description
int8 quantizers.py 8-bit integer quantization
int4 quantizers.py 4-bit integer quantization
float8 quantizers.py 8-bit floating point
awq awq.py, awq_core.py, awq_config.py Activation-aware weight quantization
gptq gptq.py, gptq_core.py, gptq_config.py Post-training quantization (GPT-Q)

LoRA (Low-Rank Adaptation) is supported on Dense, EinsumDense, and Embedding layers via enable_lora(rank). LoRA is incompatible with GPTQ quantization and certain kernel constraints.

1.8 Distribution System

Multi-device training is implemented in keras/src/distribution/distribution_lib.py with backend-specific implementations:

  • JAX: keras/src/backend/jax/distribution_lib.py — uses JAX's pjit and mesh-based sharding
  • TensorFlow: keras/src/backend/tensorflow/distribution_lib.py — uses tf.distribute strategies

NumPy and OpenVINO backends do not support distribution.

1.9 Knowledge Distillation

The keras/src/distillation/ module provides:

  • distiller.py: Distiller class — a training wrapper that takes a teacher model and student model, training the student to match the teacher's outputs
  • distillation_loss.py: Custom loss combining student task loss with teacher-student divergence

2. System Requirements

2.1 Python Version

Keras 3.15.0 requires Python 3.9+. The pyproject.toml specifies requires-python = ">= 3.9".

2.2 Backend-Specific Dependencies

Each backend has its own requirements file. Install only the backend(s) you need:

TensorFlow backend:

pip install keras tensorflow
# GPU (CUDA):
pip install keras -r requirements-tensorflow-cuda.txt
# TPU:
pip install keras -r requirements-tensorflow-tpu.txt

On non-macOS systems, tensorflow-cpu is sufficient for CPU-only workloads. On macOS, use tensorflow (which includes Metal acceleration).

JAX backend:

pip install keras jax[cpu] flax
# GPU (CUDA):
pip install keras -r requirements-jax-cuda.txt
# TPU:
pip install keras -r requirements-jax-tpu.txt

PyTorch backend:

pip install keras torch
# GPU (CUDA):
pip install keras -r requirements-torch-cuda.txt

torch-xla is additionally required on non-macOS platforms for XLA compilation support.

NumPy backend (inference only):

pip install keras numpy

OpenVINO backend (inference only):

pip install keras openvino

Important

The NumPy and OpenVINO backends support inference only — model.fit() and model.train_on_batch() will raise errors. Use these backends strictly for model.predict() and model() calls.

2.3 Common Dependencies

The requirements-common.txt file lists shared dependencies across all backends. These are pulled in automatically when installing Keras via pip.

2.4 Optional Dependencies

Package Feature
pydot keras.utils.plot_model() visualization
tf2onnx ONNX export
openvino OpenVINO export (separate from OpenVINO backend)
ai-edge-litert LiteRT (TFLite) export

3. Configuration Reference

3.1 Config File

Keras reads configuration from ~/.keras/keras.json at import time. The config directory can be overridden with the KERAS_HOME environment variable. If the home directory is not writable, Keras falls back to /tmp.

Example keras.json:

{
    "floatx": "float32",
    "epsilon": 1e-7,
    "backend": "tensorflow",
    "image_data_format": "channels_last",
    "nnx_enabled": false
}

3.2 Configuration Parameters

All configuration is managed through module-level globals in keras/src/backend/config.py with getter/setter pairs:

Parameter Default Getter Setter Description
_FLOATX "float32" floatx() set_floatx(value) Default float dtype for weights and computations
_EPSILON 1e-7 epsilon() set_epsilon(value) Small constant for numerical stability
_IMAGE_DATA_FORMAT "channels_last" image_data_format() set_image_data_format(value) "channels_last" (NHWC) or "channels_first" (NCHW)
_BACKEND "tensorflow" backend() — (immutable after import) Active computation backend
_NNX_ENABLED False is_nnx_enabled() set_nnx_enabled(value) Enable Flax NNX features for JAX backend
_MAX_EPOCHS None max_epochs() set_max_epochs(value) Cap on training epochs (debugging)
_MAX_STEPS_PER_EPOCH None max_steps_per_epoch() set_max_steps_per_epoch(value) Cap on steps per epoch (debugging)

Important

The backend cannot be changed after import keras. To switch backends, set the environment variable before importing: os.environ["KERAS_BACKEND"] = "jax" must come before import keras. Alternatively, set it in the shell: KERAS_BACKEND=jax python train.py.

3.3 Environment Variables

Variable Purpose Default
KERAS_BACKEND Select backend: tensorflow, jax, torch, numpy, openvino tensorflow
KERAS_HOME Override config directory location ~/.keras
KERAS_MAX_EPOCHS Cap training epochs (useful for CI/debugging) None (unlimited)
KERAS_MAX_STEPS_PER_EPOCH Cap steps per epoch None (unlimited)
KERAS_NNX_ENABLED Enable Flax NNX integration ("true") "false"
TF_FORCE_GPU_ALLOW_GROWTH Auto-set by Keras when backend ≠ tensorflow —

3.4 Runtime Configuration

Configuration can be changed at runtime through the Python API:

import keras

# Change float precision
keras.config.set_floatx("float16")

# Change image data format
keras.config.set_image_data_format("channels_first")

# Change epsilon for numerical stability
keras.config.set_epsilon(1e-5)

# Limit training for debugging
keras.config.set_max_epochs(2)
keras.config.set_max_steps_per_epoch(10)

# Enable Flax NNX (JAX backend only)
keras.config.set_nnx_enabled(True)

3.5 Mixed Precision

Keras supports mixed precision training through dtype policies (keras/src/dtype_policies/):

keras.mixed_precision.set_global_policy("mixed_float16")

This configures layers to use float16 for computations while keeping float32 for weight storage, reducing memory usage and improving throughput on GPUs with Tensor Cores.


4. Deployment & Scaling

4.1 Model Export for Production

Keras does not include a serving runtime — it is a library for building and training models. Deployment involves exporting to a format consumed by a serving system.

TF SavedModel (recommended for TensorFlow Serving):

model.export("./saved_model_dir")
# Or with format specification:
model.export("./saved_model_dir", format="tf_saved_model")

LiteRT / TFLite (mobile and edge):

model.export("model.tflite", format="tflite")

This requires the TensorFlow backend and the ai-edge-litert package.

ONNX (cross-platform):

model.export("model.onnx", format="onnx")

Requires tf2onnx. The export goes through TF SavedModel as an intermediate step.

OpenVINO IR (Intel hardware):

model.export("model_dir", format="openvino")

Tip

For maximum portability, export to ONNX. For best performance on Intel hardware, export to OpenVINO IR. For the TensorFlow ecosystem (TF Serving, TFX), export to SavedModel.

4.2 Distributed Training

Distributed training is supported on JAX and TensorFlow backends via the distribution API:

import keras
from keras.distribution import DeviceMesh, LayoutMap, ModelParallel

# Create a device mesh
devices = keras.distribution.list_devices()
mesh = DeviceMesh(shape=(2, 4), axis_names=["batch", "model"], devices=devices)

# Define how tensors map to devices
layout_map = LayoutMap(mesh)
layout_map[".*dense.*kernel"] = ("model", None)
layout_map[".*dense.*bias"] = ("model",)

# Apply distribution strategy
distribution = ModelParallel(mesh, layout_map=layout_map)
keras.distribution.set_distribution(distribution)

# Build and train model as usual
model = create_model()
model.compile(optimizer="adam", loss="mse")
model.fit(dataset)

4.3 Quantization for Deployment

Reduce model size and improve inference speed:

# Post-training quantization
model.quantize("int8")  # or "int4", "float8"

# AWQ (requires calibration data)
model.quantize("awq")

# GPTQ (requires calibration data)
model.quantize("gptq")

# Save quantized model
model.save("quantized_model.keras")

Warning

Quantization is a one-way operation on the model instance. Always save your full-precision model before quantizing. The quantized model will have reduced numerical precision and may show degraded accuracy on some tasks.

4.4 Build System

Keras uses pip_build.py for wheel creation:

# Build wheel package
python3 pip_build.py
# Output: dist/keras-3.15.0-py3-none-any.whl

# Build and install locally
python3 pip_build.py --install

# Nightly build (appends dev version suffix)
python3 pip_build.py --nightly

# Release candidate
python3 pip_build.py --rc 1

The build process copies source to tmp_build_dir, excludes _test.py files, and runs python3 -m build. Package metadata is defined in pyproject.toml.


5. Operations

5.1 Pre-trained Applications

Keras ships with pre-trained model architectures in keras/src/applications/ (VGG, ResNet, EfficientNet, MobileNet, etc.). Weights are downloaded on first use and cached in KERAS_HOME/models/.

from keras.applications import ResNet50
model = ResNet50(weights="imagenet")

Weight files are fetched via keras.utils.get_file(), which supports SHA256/MD5 hash verification for integrity.

5.2 File Downloads and Caching

The get_file() utility (keras/src/utils/file_utils.py) manages file downloads:

  • Default cache directory: ~/.keras/ (overridden by KERAS_HOME)
  • Supports hash verification (SHA256, MD5) for downloaded files
  • Implements path traversal protection with symlink validation

5.3 Callbacks for Operational Monitoring

Keras provides built-in callbacks for monitoring training:

Callback Purpose
ModelCheckpoint Save model at intervals
EarlyStopping Stop training when metric plateaus
TensorBoard Log metrics for TensorBoard visualization
CSVLogger Log metrics to CSV file
ProgbarLogger Display progress bar
ReduceLROnPlateau Reduce learning rate on plateau
LearningRateScheduler Custom learning rate schedules
RemoteMonitor Send metrics to a remote server
BackupAndRestore Fault-tolerant training with checkpointing
TerminateOnNaN Stop on NaN loss
LambdaCallback Custom callback via lambdas
SwapEMAWeights Swap in EMA weights for evaluation

Note

BackupAndRestore is essential for long-running training jobs on preemptible instances. It saves training state (epoch, step) and restores automatically on restart.

5.4 Debugging Training Issues

Use the epoch/step capping environment variables to rapidly iterate:

# Run only 2 epochs with 10 steps each
KERAS_MAX_EPOCHS=2 KERAS_MAX_STEPS_PER_EPOCH=10 python train.py

Or set programmatically:

keras.config.set_max_epochs(2)
keras.config.set_max_steps_per_epoch(10)

Tip

These caps are ideal for CI pipelines where you want to verify the training loop runs without errors, but don't need convergence. They also work for debugging data loading and preprocessing pipelines.

5.5 Model Visualization

Generate architecture diagrams (requires pydot):

keras.utils.plot_model(
    model,
    to_file="model.png",
    show_shapes=True,
    show_layer_names=True,
    show_dtype=True,
    show_layer_activations=True,
    show_trainable=True,
)

The model_to_dot() function returns a pydot.Dot object for programmatic graph manipulation.

Image-specific visualization tools in keras/src/visualization/:

  • draw_bounding_boxes() — overlay boxes on images
  • draw_segmentation_masks() — overlay masks on images
  • plot_bounding_box_gallery(), plot_image_gallery(), plot_segmentation_mask_gallery() — gallery views

6. Performance

6.1 Backend Selection for Performance

Backend choice has significant performance implications:

Backend Best For Training GPU TPU
TensorFlow Production serving, TF ecosystem Yes Yes Yes
JAX Research, TPU workloads, functional style Yes Yes Yes
PyTorch Research, PyTorch ecosystem integration Yes Yes No
NumPy CPU inference, debugging No No No
OpenVINO Intel CPU/GPU/VPU inference No Intel only No

6.2 Mixed Precision Training

Enable float16 computation with float32 master weights:

keras.mixed_precision.set_global_policy("mixed_float16")

This typically provides 2-3x speedup on GPUs with Tensor Cores (NVIDIA Volta and later) with minimal accuracy impact. For TPUs, use "mixed_bfloat16".

6.3 Data Pipeline Performance

The data adapter system (keras/src/trainers/data_adapters/) abstracts input formats, but performance characteristics differ:

  • tf.data.Dataset (TFDatasetAdapter): Best for TensorFlow backend. Supports prefetching, parallel mapping, and interleaving.
  • torch.utils.data.DataLoader (TorchDataLoaderAdapter): Best for PyTorch backend. Supports multi-worker loading.
  • keras.utils.PyDataset (PyDatasetAdapter): Backend-agnostic multiprocessing data loading. Set workers and use_multiprocessing parameters.
  • GrainDatasetAdapter: For JAX ecosystem Grain datasets.

6.4 XLA Compilation

JAX uses XLA compilation by default. For TensorFlow, enable with:

model.compile(optimizer="adam", loss="mse", jit_compile=True)

XLA compilation fuses operations and optimizes memory layout, often providing 20-50% speedup for computation-bound models. However, it increases initial compilation time and may not support all operations.

6.5 Image Data Format

The image_data_format setting affects convolution and pooling layer behavior:

  • "channels_last" (NHWC): Default. Best performance on most GPUs via cuDNN.
  • "channels_first" (NCHW): May be faster on some older NVIDIA GPUs and is the PyTorch convention.
keras.config.set_image_data_format("channels_first")

6.6 Quantization Performance Impact

Mode Model Size Reduction Inference Speedup Accuracy Impact
int8 ~4x 2-4x (hardware dependent) Low
int4 ~8x Variable Moderate
float8 ~2x 1.5-2x Very low
awq ~4x 2-4x Low (activation-aware)
gptq ~4x 2-4x Low (calibration-based)

7. Security

7.1 Deserialization Safety

Keras implements a security boundary around model deserialization. By default, only known Keras classes can be deserialized. Two scenarios require explicit opt-in:

Lambda layers:

# Lambda layers contain arbitrary Python code
# Loading a model with Lambda layers requires:
keras.config.enable_unsafe_deserialization()
model = keras.models.load_model("model_with_lambda.keras")

Torch nn.Module wrappers:

# TorchModuleWrapper also carries arbitrary code
keras.config.enable_unsafe_deserialization()
model = keras.models.load_model("model_with_torch_module.keras")

Caution

enable_unsafe_deserialization() allows arbitrary code execution during model loading. NEVER call this on models from untrusted sources. A malicious .keras file with Lambda layers can execute arbitrary Python code on your system.

7.2 File Download Integrity

The get_file() utility supports cryptographic hash verification:

path = keras.utils.get_file(
    "weights.h5",
    "https://example.com/weights.h5",
    file_hash="abc123...",
    hash_algorithm="sha256"  # or "md5"
)

Always provide file_hash when downloading weights from external sources to verify integrity.

7.3 Path Traversal Protection

keras/src/utils/file_utils.py implements protections against path traversal attacks:

  • Symlink validation prevents following symbolic links outside expected directories
  • Path filtering rejects suspicious path components

7.4 Serialization Registry Validation

The serialization_lib.py module validates class names during deserialization against a registry of known safe classes. However, GitHub issue #22703 reports a gap where deserialize_keras_object accepts arbitrary registered_name values. Exercise caution when loading models from untrusted sources, even without enable_unsafe_deserialization().

Warning

Do not load .keras model files from untrusted sources without reviewing the config.json inside the archive first. You can inspect it by unzipping the .keras file (it is a standard zip archive) and examining the class references.

7.5 Security Checklist for Production

  1. Never call enable_unsafe_deserialization() in production serving pipelines
  2. Always verify file hashes when downloading pre-trained weights
  3. Audit config.json in .keras files before loading models from third parties
  4. Pin Keras and backend versions in production requirements.txt
  5. Use quantized/exported models (SavedModel, ONNX, OpenVINO IR) for serving — these have a smaller attack surface than .keras files with arbitrary Python

8. Developer Internals

8.1 API Generation System

The public API in keras/api/ is entirely auto-generated — never edit files in this directory manually. The generation system works as follows:

  1. Developers annotate classes and functions with @keras_export("keras.path.to.symbol") (defined in keras/src/api_export.py)
  2. The api_gen.py script copies source to a build directory and runs namex.generate_api_files(), which reads the export decorators and generates the keras/api/ tree
  3. A _tf_keras/ compatibility shim directory is created for backward compatibility with tf.keras imports
  4. The pre-commit hook (.pre-commit-config.yaml) runs shell/api_gen.sh automatically on every commit, followed by ruff for linting/formatting

To regenerate the API manually:

bash shell/api_gen.sh

Caution

Any manual edits to files under keras/api/ will be silently overwritten by the next API generation run (either via pre-commit hook or manual api_gen.sh execution). Always edit the source files under keras/src/ and add @keras_export decorators.

8.2 Adding a New Layer

  1. Create the implementation file in the appropriate keras/src/layers/ subdirectory
  2. Implement __init__, build, call, get_config
  3. Add the @keras_export("keras.layers.YourLayer") decorator
  4. Write tests in a *_test.py file alongside the implementation
  5. Run bash shell/api_gen.sh to regenerate the public API
  6. The pre-commit hook will also handle this automatically

8.3 Adding a New Op

  1. Add the symbolic class and function to the appropriate ops module (keras/src/ops/numpy.py, nn.py, etc.)
  2. Implement the backend-specific version in each backend's corresponding module
  3. Add @keras_export decorator
  4. Write tests covering all backends

8.4 Testing

Keras uses pytest with custom markers defined in conftest.py:

# Run all tests
pytest

# Run tests for a specific module
pytest keras/src/layers/core/dense_test.py

# Run only tests that don't require a trainable backend
pytest -m "not requires_trainable_backend"

# Run multi-device tests
pytest -m "multi_device"

Test configuration (conftest.py):

  • Registers pytest markers: requires_trainable_backend, multi_device
  • Disables TF32 for numerical accuracy in tests (TF32 introduces small numerical differences that cause test failures)
  • Handles OpenVINO-excluded tests

Tests are colocated with source — every foo.py has a corresponding foo_test.py in the same directory.

Integration tests (integration_tests/):

  • Basic flow validation
  • Custom training loops per backend (JAX, TF, Torch)
  • Model visualization
  • PyTorch export
  • Dataset tests

Benchmarks (benchmarks/):

  • Layer benchmarks
  • Model benchmarks (BERT, image classification)
  • Torch CTL (Custom Training Loop) benchmarks

8.5 Code Formatting

Keras uses ruff for both linting and formatting:

bash shell/format.sh

The pre-commit hook runs ruff automatically after API generation.

8.6 Key Internal Classes

Variable (keras/src/backend/common/variables.py): Wraps backend-specific tensor variables. Handles dtype casting, naming, and trainable/non-trainable distinction.

KerasTensor (keras/src/backend/common/keras_tensor.py): Symbolic tensor representation used during model building (before eager execution). Carries shape and dtype metadata for graph construction.

AutocastScope: Context manager that temporarily overrides the dtype policy, enabling mixed-precision scoping within specific model sections.

StatelessScope: Context manager for stateless execution — variables are provided as explicit arguments rather than read from the layer's internal state. Used by JAX's functional paradigm.

Tracker (keras/src/utils/tracking.py): Monitors attribute assignments on Layer objects. When you assign a Variable, Layer, Metric, or Optimizer to a layer attribute, Tracker automatically registers it in the appropriate collection (weights, layers, metrics, etc.).

Config: Frozen dict-like object used for layer configuration snapshots. Immutable after creation.

8.7 The __new__ Pattern in Model

Model.__new__ is a critical piece of the multi-backend architecture. When you write model = Model(...), __new__ inspects keras.backend.backend() and returns an instance of the appropriate backend-specific Trainer subclass. This means type(model) is not Model but rather JAXTrainer, TFTrainer, TorchTrainer, NumPyTrainer, or OpenVINOTrainer, depending on the active backend. All of these are transparent to user code since they share the Model interface.

8.8 Tree Utilities

keras/src/tree/ provides a unified interface for traversing nested Python structures (lists, tuples, dicts). It wraps backend-specific implementations:

  • dmtree (Google DeepMind's tree library)
  • optree (JAX ecosystem)
  • torch.utils._pytree (PyTorch)

These are used extensively in the trainer and ops systems for handling nested inputs/outputs.


9. Integration Points

9.1 Backend Interoperability

Keras models can interoperate with native backend code:

JAX:

# Use JAX transformations on Keras models
import jax

@jax.jit
def predict(params, x):
    return model.stateless_call(params, {}, x)[0]

# Use JAX layers in Keras via JaxLayer/FlaxLayer
from keras.wrappers import JaxLayer, FlaxLayer

PyTorch:

# Wrap a torch.nn.Module as a Keras layer
from keras.wrappers import TorchModuleWrapper
keras_layer = TorchModuleWrapper(torch_module)

# Keras models are torch.nn.Module subclasses when using torch backend
# Standard PyTorch training loops work directly

TensorFlow:

# Load TF SavedModel as a Keras layer
from keras.export import TFSMLayer
layer = TFSMLayer("path/to/saved_model")

# Use tf.data.Dataset directly with model.fit()
model.fit(tf_dataset, epochs=10)

9.2 Scikit-learn Integration

keras/src/wrappers/ provides scikit-learn compatible wrappers:

from keras.wrappers import SKLearnClassifier, SKLearnRegressor

# Use with sklearn pipelines, cross-validation, grid search
from sklearn.model_selection import cross_val_score
estimator = SKLearnClassifier(build_fn=create_model)
scores = cross_val_score(estimator, X, y, cv=5)

9.3 Data Format Compatibility

Keras accepts data from multiple ecosystems without conversion:

Input Format Adapter Backend Affinity
NumPy arrays ArrayDataAdapter All
Python lists ArrayDataAdapter All
tf.data.Dataset TFDatasetAdapter TensorFlow
torch.utils.data.DataLoader TorchDataLoaderAdapter PyTorch
keras.utils.PyDataset PyDatasetAdapter All
Python generators GeneratorDataAdapter All
Grain datasets GrainDatasetAdapter JAX

9.4 Pre-trained Model Ecosystem

Keras includes pre-trained architectures in keras/src/applications/:

  • Classification: VGG16/19, ResNet50/101/152, InceptionV3, EfficientNetV2, MobileNetV2/V3, DenseNet, NASNet, ConvNeXt, Xception
  • Feature extraction: Use include_top=False to get feature maps

All weights are downloaded from the Keras model repository and cached in KERAS_HOME/models/.


Troubleshooting

Error: RuntimeError: Backend cannot be changed after import

Cause: KERAS_BACKEND was set or keras.config.set_backend() was called after import keras.

Solution:

  1. Set the environment variable before any Keras import:
    import os
    os.environ["KERAS_BACKEND"] = "jax"
    import keras
    
  2. Or set it in the shell before running your script:
    KERAS_BACKEND=jax python train.py
    

Prevention: Always set backend configuration before importing Keras. Use shell-level environment variables in production scripts.

Error: ValueError: Unknown backend: 'xyz'

Cause: Invalid value for KERAS_BACKEND or backend in keras.json.

Solution:

  1. Check your ~/.keras/keras.json file for typos
  2. Valid values: tensorflow, jax, torch, numpy, openvino

Prevention: Validate backend names against the five supported options.

Error: NotImplementedError during model.fit() with NumPy/OpenVINO backend

Cause: NumPy and OpenVINO are inference-only backends. Training operations are not implemented.

Solution:

  1. Switch to a trainable backend (TensorFlow, JAX, or PyTorch) for training
  2. Use NumPy/OpenVINO only for model.predict() or direct model() calls

Prevention: Choose a trainable backend for any workflow involving fit(), train_on_batch(), or gradient computation.

Error: ImportError: Lambda layers require unsafe deserialization

Cause: Loading a model containing Lambda layers without enabling unsafe deserialization.

Solution:

  1. If you trust the model source:
    keras.config.enable_unsafe_deserialization()
    model = keras.models.load_model("model.keras")
    
  2. If you do not trust the source, inspect the .keras file first:
    unzip -p model.keras config.json | python -m json.tool
    
    Look for Lambda or custom class references.

Prevention: Avoid Lambda layers in production models. Use named layers or subclassing instead.

Error: Gradient divergence between backends (e.g., TF vs Torch)

Cause: Numerical differences in gradient computation across backends. GitHub issue #22695 documents this for Conv1D + Flatten with channels_first. Issue #22697 reports similar divergence in recurrent WDCG.

Solution:

  1. Ensure image_data_format is consistent across backends
  2. Test numerical equivalence with channels_last format (better cross-backend consistency)
  3. Increase epsilon if losses involve division near zero
  4. Compare outputs layer-by-layer to isolate the divergent operation

Prevention: Run cross-backend numerical tests for critical models. Use channels_last as the default format for maximum compatibility.

Error: MelSpectrogram validation failure with symbolic inputs

Cause: GitHub issue #22535 — fft_length validation fails when input shapes are symbolic (during model building).

Solution:

  1. Provide explicit input_shape to the layer to avoid symbolic shape inference
  2. Check for updates in Keras releases that address this issue

Prevention: Pin to a Keras version where the fix is available. Test preprocessing layers with both symbolic and eager inputs.

Error: IntegerLookup OOV error with num_oov_indices=0

Cause: GitHub issue #22521 — validation logic incorrectly handles the case where num_oov_indices is set to 0.

Solution:

  1. Set num_oov_indices=1 (default) unless you specifically need to disable OOV handling
  2. Filter input data to ensure all values are in the vocabulary

Prevention: Test preprocessing layers with edge-case configurations before deploying.


Appendix A: Repository Structure

keras-team/keras/
├── keras/
│   ├── api/                    # AUTO-GENERATED public API (do not edit)
│   │   ├── activations/
│   │   ├── applications/
│   │   ├── backend/
│   │   ├── callbacks/
│   │   ├── config/
│   │   ├── constraints/
│   │   ├── datasets/
│   │   ├── distillation/
│   │   ├── distribution/
│   │   ├── dtype_policies/
│   │   ├── export/
│   │   ├── initializers/
│   │   ├── layers/
│   │   ├── losses/
│   │   ├── metrics/
│   │   ├── mixed_precision/
│   │   ├── models/
│   │   ├── ops/
│   │   ├── optimizers/
│   │   ├── preprocessing/
│   │   ├── quantizers/
│   │   ├── random/
│   │   ├── regularizers/
│   │   ├── saving/
│   │   ├── tree/
│   │   ├── utils/
│   │   ├── visualization/
│   │   ├── wrappers/
│   │   └── _tf_keras/         # TF-Keras compatibility shim
│   └── src/                    # Source implementation
│       ├── version.py          # __version__ = "3.15.0"
│       ├── api_export.py       # @keras_export decorator
│       ├── backend/            # Multi-backend dispatch
│       │   ├── config.py       # Configuration globals
│       │   ├── common/         # KerasTensor, Variable, dtypes
│       │   ├── jax/
│       │   ├── tensorflow/
│       │   ├── torch/
│       │   ├── numpy/
│       │   └── openvino/
│       ├── callbacks/
│       ├── distillation/
│       ├── distribution/
│       ├── dtype_policies/
│       ├── export/
│       ├── layers/
│       │   ├── layer.py        # Base Layer class
│       │   ├── core/           # Dense, Embedding, Input
│       │   ├── convolutional/
│       │   ├── normalization/
│       │   ├── attention/
│       │   ├── rnn/
│       │   └── preprocessing/
│       ├── models/             # Sequential, Functional, Model
│       ├── ops/                # Backend-agnostic operations
│       ├── optimizers/
│       ├── quantizers/         # AWQ, GPTQ, int8/int4/float8
│       ├── saving/             # .keras format, serialization
│       ├── trainers/           # Training loop, data adapters
│       ├── utils/
│       ├── visualization/
│       └── wrappers/           # sklearn, torch wrappers
├── integration_tests/
├── benchmarks/
├── shell/                      # api_gen.sh, format.sh
├── api_gen.py
├── pip_build.py
├── conftest.py
├── pyproject.toml
└── requirements*.txt           # Backend-specific requirements

Appendix B: Complete Configuration Quick Reference

{
    "floatx": "float32",
    "epsilon": 1e-7,
    "backend": "tensorflow",
    "image_data_format": "channels_last",
    "nnx_enabled": false
}
Setting Values Impact
floatx float16, float32, float64 Default dtype for all weights
epsilon Any small float Numerical stability floor
backend tensorflow, jax, torch, numpy, openvino Computation engine (immutable after import)
image_data_format channels_last, channels_first Tensor layout for image operations
nnx_enabled true, false Flax NNX features (JAX backend only)