| name | tensorflow |
| description | Comprehensive deep learning framework for building, training, and deploying neural networks. TensorFlow provides tf.keras high-level API for model construction, tf.data for efficient data pipelines, and tf.function for graph-mode optimization. Use when working with: neural network training and inference, image classification/detection/segmentation, NLP/text processing with embeddings or transformers, time series forecasting, generative models (VAE, GAN), transfer learning with pretrained models, custom training loops with GradientTape, GPU/TPU accelerated computation, or any deep learning task. |
TensorFlow - Deep Learning Framework
TensorFlow is the most widely-used deep learning framework. TF 2.x uses eager execution by default for intuitive debugging, while @tf.function enables graph-mode compilation for production performance. tf.keras is the high-level API for model construction across all paradigms.
When to Use
- Building and training neural networks (classification, regression, generation).
- Image processing (CNN architectures, object detection, segmentation).
- Natural Language Processing (text classification, sequence-to-sequence, transformers).
- Time series forecasting with recurrent or convolutional architectures.
- Generative models (VAE, GAN, autoencoders).
- Transfer learning with pretrained models from
tf.keras.applications.
- Custom training loops with
tf.GradientTape for full control.
- Deploying models via TensorFlow Serving or TF Lite (mobile/edge).
- Multi-GPU / TPU distributed training.
- Any task requiring automatic differentiation and computational graphs.
Reference Documentation
Official docs: https://www.tensorflow.org/api_docs/python
Keras API: https://keras.io/api/
Tutorials: https://www.tensorflow.org/tutorials
GitHub: https://github.com/tensorflow/tensorflow
Search patterns: tf.keras.Model, tf.data.Dataset, tf.function, model.fit, tf.GradientTape
Core Principles
Eager Execution (Default in TF2)
Operations execute immediately, returning concrete values. Debugging is straightforward — print tensors, use standard Python control flow, inspect intermediate values at any point.
tf.function — Graph Mode Compilation
Decorating a function with @tf.function traces it into a computational graph, enabling 2–10x speedups. Use on training steps and inference in production. Never put Python side-effects (print, append) inside @tf.function — use tf.print instead.
Keras: Three Model-Building Paradigms
Sequential (linear stack), Functional API (DAG with multiple I/O), Model Subclassing (full Python control). All share compile → fit → predict. Choose based on architecture complexity.
tf.data for Data Pipelines
tf.data.Dataset is the standard for efficient input pipelines. Supports lazy evaluation, parallel preprocessing, and GPU prefetching — critical to prevent CPU bottlenecks during training.
Automatic Differentiation
tf.GradientTape records operations for backpropagation. model.fit() handles this internally; custom training loops require explicit tape management.
Quick Reference
Installation
pip install tensorflow
pip install tensorflow-cpu
Standard Imports
import tensorflow as tf
import numpy as np
from tensorflow.keras import layers
Basic Pattern — Sequential Classification
import tensorflow as tf
from tensorflow.keras import layers
import numpy as np
X_train = np.random.randn(1000, 28, 28, 1).astype(np.float32)
y_train = np.random.randint(0, 10, 1000)
model = tf.keras.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
history = model.fit(X_train, y_train, epochs=10, validation_split=0.2)
predictions = model.predict(X_train[:5])
Basic Pattern — Custom Training Loop
import tensorflow as tf
import numpy as np
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=(10,)),
tf.keras.layers.Dense(1)
])
optimizer = tf.keras.optimizers.Adam(1e-3)
loss_fn = tf.keras.losses.MeanSquaredError()
X = tf.constant(np.random.randn(100, 10).astype(np.float32))
y = tf.constant(np.random.randn(100, 1).astype(np.float32))
@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
y_pred = model(x, training=True)
loss = loss_fn(y, y_pred)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
return loss
for epoch in range(10):
loss = train_step(X, y)
tf.print("Epoch", epoch, "loss=", loss)
Critical Rules
✅ DO
- Use
@tf.function on training steps — Graph compilation gives 2–10x speedup over eager mode.
- Use
tf.data.Dataset for all data loading — Preferred over raw numpy arrays for any dataset beyond toy size.
- Always call
.prefetch(tf.data.AUTOTUNE) — Overlaps CPU preprocessing with GPU computation.
- Specify
input_shape in the first layer — Builds weights immediately; otherwise deferred until first call.
- Pass
validation_data or validation_split to model.fit() — Only way to detect overfitting.
- Freeze base model with
base_model.trainable = False — Standard practice for transfer learning.
- Cast inputs to
float32 — GPU optimized for float32; dtype mismatches cause silent errors or crashes.
- Use
tf.keras.callbacks — EarlyStopping + ModelCheckpoint is the minimum viable training setup.
- Call
model.summary() — Always inspect architecture and parameter count before training.
- Use
from_logits=True in loss — Numerically more stable than softmax + crossentropy separately.
❌ DON'T
- Don't put Python print/append inside
@tf.function — Executes only during tracing, not per call. Use tf.print.
- Don't use numpy ops inside
@tf.function — Use tf.* operations exclusively inside traced functions.
- Don't skip
.cache() before .shuffle() — Without cache, data is re-read from disk every epoch.
- Don't call
model.predict() in a loop per sample — Batch predictions; or use model(x) for single inference.
- Don't ignore GPU memory errors — Set
tf.config.set_memory_growth(gpu, True) at startup.
- Don't hardcode batch dimensions — Use
None; enables flexible batch sizes across train/eval/serve.
- Don't use softmax activation + categorical_crossentropy together — Use logits output +
from_logits=True.
- Don't forget
training=True/False in custom loops — Controls Dropout and BatchNormalization behavior.
Anti-Patterns (NEVER)
import tensorflow as tf
import numpy as np
@tf.function
def bad_step(x, y):
loss = compute_loss(x, y)
print(f"Loss: {loss}")
return loss
@tf.function
def good_step(x, y):
loss = compute_loss(x, y)
tf.print("Loss:", loss)
return loss
@tf.function
def bad_predict(x):
result = model(x)
return np.array(result)
@tf.function
def good_predict(x):
return model(x)
dataset = tf.data.Dataset.from_tensor_slices((X, y))
dataset = dataset.shuffle(100).batch(32)
dataset = (dataset
.cache()
.shuffle(1000)
.batch(32)
.prefetch(tf.data.AUTOTUNE))
results = []
sample test_data:
pred = model.predict(sample[np.newaxis])
results.append(pred)
results = model.predict(test_data)
gpus = tf.config.list_physical_devices()
gpu gpus:
tf.config.set_memory_growth(gpu, )
model = tf.keras.Sequential([
tf.keras.layers.Dense(, activation=)
])
model.(loss=)
model = tf.keras.Sequential([
tf.keras.layers.Dense()
])
model.(loss=tf.keras.losses.CategoricalCrossentropy(from_logits=))
Tensors and Variables
Tensors — Immutable Data
import tensorflow as tf
t1 = tf.constant([1.0, 2.0, 3.0])
t2 = tf.constant([[1, 2], [3, 4]])
t3 = tf.zeros((3, 4))
t4 = tf.ones((2, 3))
t5 = tf.random.normal((100, 50))
t6 = tf.random.uniform((10,), minval=0, maxval=1)
print(t2.shape)
print(t2.dtype)
print(t2.numpy())
a = tf.constant([1.0, 2.0, 3.0])
b = tf.constant([4.0, 5.0, 6.0])
c = a + b
d = a * b
e = tf.reduce_sum(a)
f = tf.reduce_mean(a)
g = tf.math.sqrt(a)
A = tf.constant([[1.0, 2.0], [3.0, ]])
B = tf.constant([[, ], [, ]])
C = tf.matmul(A, B)
D = tf.linalg.inv(A)
det = tf.linalg.det(A)
eigs = tf.linalg.eigh(A)
t = tf.constant([, , , , , ])
reshaped = tf.reshape(t, (, ))
expanded = tf.expand_dims(t, axis=)
squeezed = tf.squeeze(expanded)
t = tf.constant([, , , , ])
(t[:])
(t[-:])
(t[::])
Variables — Mutable State (Model Weights)
import tensorflow as tf
w = tf.Variable(tf.random.normal((3, 2)), name='weights')
b = tf.Variable(tf.zeros((2,)), name='bias')
w.assign(tf.random.normal((3, 2)))
w.assign_add(tf.ones_like(w) * 0.01)
w.assign_sub(tf.ones_like(w) * 0.001)
tf.data.Dataset — Efficient Data Pipelines
import tensorflow as tf
import numpy as np
X = np.random.randn(1000, 28, 28, 1).astype(np.float32)
y = np.random.randint(0, 10, 1000)
dataset = tf.data.Dataset.from_tensor_slices((X, y))
train_dataset = (
tf.data.Dataset.from_tensor_slices((X_train, y_train))
.cache()
.shuffle(buffer_size=1000)
.batch(32)
.map(augment_fn, num_parallel_calls=tf.data.AUTOTUNE)
.prefetch(tf.data.AUTOTUNE)
)
def normalize(x, y):
return x / 255.0, y
def augment(x, y):
x = tf.image.random_flip_left_right(x)
x = tf.image.random_brightness(x, max_delta=0.1)
x = tf.image.random_crop(x, size=tf.shape(x))
return x, y
dataset = dataset.map(normalize).map(augment)
dataset = dataset.filter(lambda x, y: y != 5)
first_100 = dataset.take()
after_100 = dataset.skip()
dataset = dataset.repeat()
dataset = dataset.repeat()
i, (x, y) dataset.():
i >= :
()
dataset = tf.data.TFRecordDataset(
tf.data.Dataset.list_files()
)
writer = tf.io.TFRecordWriter()
feature = {
: tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_bytes])),
: tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))
}
example = tf.train.Example(features=tf.train.Features(feature=feature))
writer.write(example.SerializeToString())
writer.close()
():
features = tf.io.parse_single_example(serialized, {
: tf.io.FixedLenFeature([], tf.string),
: tf.io.FixedLenFeature([], tf.int64)
})
image = tf.io.decode_jpeg(features[], channels=)
image = tf.image.resize(image, [, ])
image, features[]
dataset = (
tf.data.TFRecordDataset()
.(parse_tfrecord, num_parallel_calls=tf.data.AUTOTUNE)
.cache()
.shuffle()
.batch()
.prefetch(tf.data.AUTOTUNE)
)
Model Building
Sequential API — Linear Stack
Best for: simple architectures where each layer has one input and one output.
import tensorflow as tf
from tensorflow.keras import layers
model = tf.keras.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10)
])
model.summary()
print(f"Parameters: {model.count_params():,}")
Functional API — DAG of Layers
Best for: multiple inputs/outputs, skip connections, shared layers.
import tensorflow as tf
from tensorflow.keras import layers
inputs = tf.keras.Input(shape=(224, 224, 3), name='image')
x = layers.Conv2D(32, (3, 3), activation='relu')(inputs)
x = layers.MaxPooling2D((2, 2))(x)
x = layers.Conv2D(64, (3, 3), activation='relu')(x)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(128, activation='relu')(x)
x = layers.Dropout(0.3)(x)
outputs = layers.Dense(10, name='logits')(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
img_input = tf.keras.Input(shape=(224, 224, 3), name='image')
meta_input = tf.keras.Input(shape=(16,), name='metadata')
img_feat = layers.Conv2D(32, (3, 3), activation='relu')(img_input)
img_feat = layers.GlobalAveragePooling2D()(img_feat)
merged = layers.Concatenate()([img_feat, meta_input])
x = layers.Dense(64, activation='relu')(merged)
output = layers.Dense(1, activation='sigmoid')(x)
model = tf.keras.Model(inputs=[img_input, meta_input], outputs=output)
def residual_block(x, filters):
residual = x
x = layers.Conv2D(filters, (, ), padding=, activation=)(x)
x = layers.BatchNormalization()(x)
x = layers.Conv2D(filters, (, ), padding=)(x)
x = layers.BatchNormalization()(x)
x = layers.Add()([x, residual])
layers.Activation()(x)
Model Subclassing — Full Control
Best for: dynamic computation, research prototyping, conditional logic in forward pass.
import tensorflow as tf
from tensorflow.keras import layers
class Classifier(tf.keras.Model):
def __init__(self, num_classes, hidden_dim=128, **kwargs):
super().__init__(**kwargs)
self.dense1 = layers.Dense(hidden_dim, activation='relu')
self.dropout = layers.Dropout(0.3)
self.dense2 = layers.Dense(hidden_dim // 2, activation='relu')
self.head = layers.Dense(num_classes)
def call(self, x, training=False):
x = self.dense1(x)
x = self.dropout(x, training=training)
x = self.dense2(x)
return self.head(x)
model = Classifier(num_classes=10)
model.build(input_shape=(None, 784))
model.summary()
model.compile(
optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy']
)
model.fit(X_train, y_train, epochs=10, validation_split=0.2)
class MultiHead(tf.keras.Model):
():
().__init__()
.backbone = layers.Dense(, activation=)
.cls_head = layers.Dense(, name=)
.reg_head = layers.Dense(, name=)
():
shared = .backbone(x)
{
: .cls_head(shared),
: .reg_head(shared)
}
Training
Built-in Training — model.fit()
import tensorflow as tf
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy']
)
history = model.fit(
X_train, y_train,
epochs=50,
batch_size=32,
validation_split=0.2,
shuffle=True,
verbose=1
)
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
for ax, metric in zip(axes, ['loss', 'accuracy']):
ax.plot(history.history[metric], label='Train')
ax.plot(history.history[f'val_{metric}'], label='Val')
ax.set_ylabel(metric.capitalize())
ax.set_xlabel('Epoch')
ax.legend()
plt.tight_layout()
plt.show()
Custom Training Loop — GradientTape
import tensorflow as tf
optimizer = tf.keras.optimizers.Adam(1e-3)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_acc = tf.keras.metrics.SparseCategoricalAccuracy(name='train_acc')
val_acc = tf.keras.metrics.SparseCategoricalAccuracy(name='val_acc')
@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
logits = model(x, training=True)
loss = loss_fn(y, logits)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
train_loss.update_state(loss)
train_acc.update_state(y, logits)
@tf.function
def val_step(x, y):
logits = model(x, training=False)
val_acc.update_state(y, logits)
for epoch in range(num_epochs):
train_loss.reset_state()
train_acc.reset_state()
val_acc.reset_state()
for x_batch, y_batch in train_dataset:
train_step(x_batch, y_batch)
for x_batch, y_batch in val_dataset:
val_step(x_batch, y_batch)
tf.print(f"Epoch {epoch+1}: loss={train_loss.result():.4f}, "
f"train_acc={train_acc.result():.4f}, val_acc=")
Callbacks — Training Control
import tensorflow as tf
callbacks = [
tf.keras.callbacks.EarlyStopping(
monitor='val_loss', patience=5,
restore_best_weights=True, verbose=1
),
tf.keras.callbacks.ModelCheckpoint(
filepath='best_model.keras',
monitor='val_accuracy', save_best_only=True,
mode='max', verbose=1
),
tf.keras.callbacks.ReduceLROnPlateau(
monitor='val_loss', factor=0.5,
patience=3, min_lr=1e-6, verbose=1
),
tf.keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=1)
]
model.fit(X_train, y_train, epochs=100,
validation_split=0.2, callbacks=callbacks)
Common Architectures
CNN — Image Classification
import tensorflow as tf
from tensorflow.keras import layers
def build_cnn(input_shape, num_classes):
"""Standard CNN with BatchNorm and GlobalAvgPool."""
model = tf.keras.Sequential([
layers.Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=input_shape),
layers.BatchNormalization(),
layers.Conv2D(32, (3, 3), padding='same', activation='relu'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
layers.Conv2D(64, (3, 3), padding='same', activation='relu'),
layers.BatchNormalization(),
layers.Conv2D(64, (3, 3), padding='same', activation='relu'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
layers.Conv2D(128, (3, 3), padding='same', activation='relu'),
layers.BatchNormalization(),
layers.GlobalAveragePooling2D(),
layers.Dropout(0.5),
layers.Dense(, activation=),
layers.Dropout(),
layers.Dense(num_classes)
])
model
model = build_cnn((, , ), num_classes=)
model.summary()
RNN / LSTM — Sequence Modeling
import tensorflow as tf
from tensorflow.keras import layers
def build_lstm_text(vocab_size, embed_dim, max_length, num_classes):
return tf.keras.Sequential([
layers.Embedding(vocab_size, embed_dim, input_length=max_length),
layers.Bidirectional(layers.LSTM(128, return_sequences=True)),
layers.Bidirectional(layers.LSTM(64)),
layers.Dropout(0.3),
layers.Dense(64, activation='relu'),
layers.Dense(num_classes)
])
def build_lstm_timeseries(timesteps, num_features, forecast_horizon):
inputs = tf.keras.Input(shape=(timesteps, num_features))
x = layers.LSTM(128, return_sequences=True)(inputs)
x = layers.LSTM(64)(x)
x = layers.Dense(64, activation='relu')(x)
outputs = layers.Dense(forecast_horizon)(x)
return tf.keras.Model(inputs, outputs)
model = build_lstm_timeseries(timesteps=30, num_features=5, forecast_horizon=7)
Transformer Block
import tensorflow as tf
from tensorflow.keras import layers
class PositionalEncoding(tf.keras.layers.Layer):
"""Learnable positional embeddings."""
def __init__(self, max_length, embed_dim, **kwargs):
super().__init__(**kwargs)
self.pos_emb = layers.Embedding(max_length, embed_dim)
def call(self, x):
seq_len = tf.shape(x)[1]
positions = tf.range(seq_len)
return x + self.pos_emb(positions)
class TransformerBlock(tf.keras.layers.Layer):
"""Single transformer encoder block: self-attention + FFN with residuals."""
def __init__(self, embed_dim, num_heads, ff_dim, dropout=0.1, **kwargs):
super().__init__(**kwargs)
self.attn = layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim // num_heads)
self.ffn = tf.keras.Sequential([
layers.Dense(ff_dim, activation='relu'),
layers.Dense(embed_dim)
])
self.norm1 = layers.LayerNormalization(epsilon=1e-6)
self.norm2 = layers.LayerNormalization(epsilon=1e-6)
self.drop1 = layers.Dropout(dropout)
self.drop2 = layers.Dropout(dropout)
def call(self, x, training=):
attn_out = .attn(x, x, training=training)
x = .norm1(x + .drop1(attn_out, training=training))
ffn_out = .ffn(x)
x = .norm2(x + .drop2(ffn_out, training=training))
x
():
inputs = tf.keras.Input(shape=(max_length,))
x = layers.Embedding(vocab_size, embed_dim)(inputs)
x = PositionalEncoding(max_length, embed_dim)(x)
_ (num_blocks):
x = TransformerBlock(embed_dim, num_heads, ff_dim)(x)
x = layers.GlobalAveragePooling1D()(x)
x = layers.Dense(embed_dim, activation=)(x)
outputs = layers.Dense(num_classes)(x)
tf.keras.Model(inputs, outputs)
model = build_transformer_classifier(
vocab_size=, max_length=,
embed_dim=, num_heads=, ff_dim=,
num_classes=, num_blocks=
)
model.summary()
Transfer Learning
import tensorflow as tf
from tensorflow.keras import layers
base = tf.keras.applications.MobileNetV2(
weights='imagenet', include_top=False, input_shape=(224, 224, 3)
)
base.trainable = False
inputs = base.input
x = base(inputs, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(256, activation='relu')(x)
x = layers.Dropout(0.3)(x)
outputs = layers.Dense(num_classes, activation='softmax')(x)
model = tf.keras.Model(inputs, outputs)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_ds, validation_data=val_ds, epochs=5)
for layer in base.layers[-20:]:
layer.trainable = True
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5),
loss='categorical_crossentropy',
metrics=['accuracy']
)
model.fit(train_ds, validation_data=val_ds, epochs=10, callbacks=[
tf.keras.callbacks.EarlyStopping(patience=3, restore_best_weights=True)
])
Saving and Loading Models
import tensorflow as tf
model.save('my_model')
model.save('my_model.keras')
model.save('my_model.h5')
loaded = tf.keras.models.load_model('my_model')
loaded = tf.keras.models.load_model('my_model.keras')
model.save_weights('weights.tf')
model.load_weights('weights.tf')
checkpoint = tf.train.Checkpoint(optimizer=optimizer, model=model)
manager = tf.train.CheckpointManager(checkpoint, './ckpts', max_to_keep=3)
manager.save()
checkpoint.restore(manager.latest_checkpoint)
tf.saved_model.save(model, 'serving_model')
converter = tf.lite.TFLiteConverter.from_saved_model('my_model')
tflite_model = converter.convert()
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
Device Management
import tensorflow as tf
print("GPUs:", tf.config.list_physical_devices('GPU'))
print("CPUs:", tf.config.list_physical_devices('CPU'))
gpus = tf.config.list_physical_devices('GPU')
for gpu in gpus:
tf.config.set_memory_growth(gpu, True)
if gpus:
tf.config.set_logical_device_configuration(gpus[0], [
tf.config.LogicalDeviceConfiguration(memory_limit=4096)
])
with tf.device('/GPU:0'):
result = tf.matmul(a, b)
strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
model = build_model()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
model.fit(train_dataset, epochs=10)
print(f"Training on {strategy.num_replicas_in_sync} replicas")
Practical Workflows
1. Image Classification Pipeline (End-to-End)
import tensorflow as tf
from tensorflow.keras import layers
def build_image_pipeline(train_dir, val_dir, img_size=(224, 224), batch_size=32, num_classes=10):
"""Full pipeline: load → augment → pretrained model → train → checkpoint."""
train_ds = tf.keras.utils.image_dataset_from_directory(
train_dir, image_size=img_size, batch_size=batch_size, seed=42
)
val_ds = tf.keras.utils.image_dataset_from_directory(
val_dir, image_size=img_size, batch_size=batch_size
)
augmentation = tf.keras.Sequential([
layers.RandomFlip('horizontal'),
layers.RandomRotation(0.2),
layers.RandomZoom(0.2),
layers.RandomContrast(0.2),
])
def preprocess_train(x, y):
x = x / 255.0
x = augmentation(x, training=True)
return x, y
def preprocess_val(x, y):
return x / 255.0, y
train_ds = train_ds.map(preprocess_train).prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.map(preprocess_val).prefetch(tf.data.AUTOTUNE)
base = tf.keras.applications.EfficientNetB0(
weights='imagenet', include_top=False, input_shape=(*img_size, 3)
)
base.trainable = False
model = tf.keras.Sequential([
base,
layers.GlobalAveragePooling2D(),
layers.Dense(, activation=),
layers.Dropout(),
layers.Dense(num_classes, activation=)
])
model.(optimizer=, loss=, metrics=[])
history = model.fit(
train_ds, validation_data=val_ds, epochs=,
callbacks=[
tf.keras.callbacks.EarlyStopping(patience=, restore_best_weights=),
tf.keras.callbacks.ModelCheckpoint(, save_best_only=,
monitor=, mode=)
]
)
model, history
2. Text Classification with Embeddings
import tensorflow as tf
import numpy as np
def build_text_classifier(texts, labels, vocab_size=20000, max_length=200, num_classes=2):
"""Tokenize → Embed → BiLSTM → Classify."""
tokenizer = tf.keras.preprocessing.text.Tokenizer(num_words=vocab_size, oov_token='<OOV>')
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
padded = tf.keras.preprocessing.sequence.pad_sequences(
sequences, maxlen=max_length, padding='post', truncating='post'
)
split = int(0.8 * len(padded))
X_train, X_val = padded[:split], padded[split:]
y_train, y_val = np.array(labels[:split]), np.array(labels[split:])
activation = 'softmax' if num_classes > 2 else 'sigmoid'
loss = 'sparse_categorical_crossentropy' if num_classes > 2 else 'binary_crossentropy'
model = tf.keras.Sequential([
tf.keras.layers.Embedding(vocab_size, 128, input_length=max_length),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Dense(num_classes if num_classes > 2 else 1, activation=activation)
])
model.compile(optimizer=, loss=loss, metrics=[])
history = model.fit(
X_train, y_train, validation_data=(X_val, y_val),
epochs=, batch_size=,
callbacks=[tf.keras.callbacks.EarlyStopping(patience=, restore_best_weights=)]
)
model, tokenizer, history
3. Time Series Forecasting (CNN-LSTM Hybrid)
import tensorflow as tf
import numpy as np
def create_sequences(data, window_size, forecast_horizon):
"""Sliding window: input=[t-window..t], target=[t+1..t+horizon]."""
X, y = [], []
for i in range(len(data) - window_size - forecast_horizon + 1):
X.append(data[i:i + window_size])
y.append(data[i + window_size:i + window_size + forecast_horizon])
return np.array(X), np.array(y)
def build_timeseries_model(window_size, num_features, forecast_horizon):
"""1D-CNN extracts local patterns; LSTM captures temporal order."""
inputs = tf.keras.Input(shape=(window_size, num_features))
x = tf.keras.layers.Conv1D(64, kernel_size=3, padding='same', activation='relu')(inputs)
x = tf.keras.layers.Conv1D(32, kernel_size=3, padding='same', activation='relu')(x)
x = tf.keras.layers.LSTM(64, return_sequences=True)(x)
x = tf.keras.layers.LSTM(32)(x)
x = tf.keras.layers.Dense(64, activation='relu')(x)
outputs = tf.keras.layers.Dense(forecast_horizon)(x)
return tf.keras.Model(inputs, outputs)
4. Variational Autoencoder (VAE)
import tensorflow as tf
from tensorflow.keras import layers
class VAE(tf.keras.Model):
"""VAE with reparameterization trick."""
def __init__(self, latent_dim, input_dim, hidden_dim=256, **kwargs):
super().__init__(**kwargs)
self.encoder = tf.keras.Sequential([
layers.Dense(hidden_dim, activation='relu', input_shape=(input_dim,)),
layers.Dense(hidden_dim // 2, activation='relu'),
])
self.mean_net = layers.Dense(latent_dim)
self.logvar_net = layers.Dense(latent_dim)
self.decoder = tf.keras.Sequential([
layers.Dense(hidden_dim // 2, activation='relu', input_shape=(latent_dim,)),
layers.Dense(hidden_dim, activation='relu'),
layers.Dense(input_dim, activation='sigmoid')
])
self.latent_dim = latent_dim
def encode(self, x):
h = self.encoder(x)
return self.mean_net(h), self.logvar_net(h)
def reparameterize(self, mean, log_var):
"""z = mean + std * eps, where eps ~ N(0,1). Gradients flow through mean/std."""
eps = tf.random.normal(tf.shape(mean))
return mean + tf.exp(0.5 * log_var) * eps
():
.decoder(z)
():
mean, log_var = .encode(x)
z = .reparameterize(mean, log_var)
recon = .decode(z)
._mean, ._log_var = mean, log_var
recon
():
recon_loss = tf.reduce_mean(tf.keras.losses.binary_crossentropy(x, x_recon))
kl_loss = - * tf.reduce_mean( + ._log_var - tf.square(._mean) - tf.exp(._log_var))
recon_loss + kl_loss
vae = VAE(latent_dim=, input_dim=)
optimizer = tf.keras.optimizers.Adam()
():
tf.GradientTape() tape:
x_recon = vae(x, training=)
loss = vae.compute_loss(x, x_recon)
grads = tape.gradient(loss, vae.trainable_variables)
optimizer.apply_gradients((grads, vae.trainable_variables))
loss
z_samples = tf.random.normal((, ))
generated = vae.decode(z_samples)
5. Multi-Task Learning
import tensorflow as tf
from tensorflow.keras import layers
def build_multitask(input_shape, tasks):
"""
Shared backbone + task-specific heads.
tasks: dict — {'name': (num_outputs, activation, loss, weight)}
Example:
tasks = {
'category': (10, 'softmax', 'sparse_categorical_crossentropy', 1.0),
'sentiment': (3, 'softmax', 'sparse_categorical_crossentropy', 0.7),
'toxicity': (1, 'sigmoid', 'binary_crossentropy', 0.5),
}
"""
inputs = tf.keras.Input(shape=input_shape)
x = layers.Dense(256, activation='relu')(inputs)
x = layers.Dropout(0.3)(x)
shared = layers.Dense(128, activation='relu')(x)
outputs, losses, weights = {}, {}, {}
for name, (n_out, act, loss, w) in tasks.items():
head = layers.Dense(64, activation='relu')(shared)
outputs[name] = layers.Dense(n_out, activation=act, name=name)(head)
losses[name] = loss
weights[name] = w
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer='adam', loss=losses, loss_weights=weights,
metrics={name: 'accuracy' for name in tasks})
return model
tasks = {
'category': (10, 'softmax', 'sparse_categorical_crossentropy', 1.0),
'sentiment': (3, 'softmax', 'sparse_categorical_crossentropy', 0.7),
'toxicity': (, , , ),
}
model = build_multitask(input_shape=(,), tasks=tasks)
Performance Tips
tf.function and XLA
import tensorflow as tf
@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
loss = compute_loss(model(x, training=True), y)
optimizer.apply_gradients(zip(tape.gradient(loss, model.trainable_variables),
model.trainable_variables))
return loss
@tf.function(input_signature=[
tf.TensorSpec(shape=[None, 224, 224, 3], dtype=tf.float32),
tf.TensorSpec(shape=[None], dtype=tf.int32)
])
def typed_train_step(x, y):
pass
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', jit_compile=True)
Mixed Precision
import tensorflow as tf
policy = tf.keras.mixed_precision.Policy('mixed_float16')
tf.keras.mixed_precision.set_global_policy(policy)
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax', dtype='float32')
])
Dataset Pipeline Order
import tensorflow as tf
dataset = (
tf.data.TFRecordDataset(files)
.map(parse_fn, num_parallel_calls=tf.data.AUTOTUNE)
.cache()
.shuffle(buffer_size=10000)
.batch(64)
.map(augment, num_parallel_calls=tf.data.AUTOTUNE)
.prefetch(tf.data.AUTOTUNE)
)
Common Pitfalls and Solutions
Shape Mismatches
model = tf.keras.Sequential([tf.keras.layers.Dense(10, input_shape=(784,))])
pred = model(np.zeros(784))
pred = model(np.zeros((1, 784)))
pred = model.predict(np.zeros((1, 784)))
training Flag Forgotten
@tf.function
def bad_eval(x):
return model(x)
@tf.function
def good_train(x): return model(x, training=True)
@tf.function
def good_eval(x): return model(x, training=False)
Memory Leaks in Loops
losses = []
for batch in dataset:
loss = train_step(batch)
losses.append(loss)
loss_metric = tf.keras.metrics.Mean()
for batch in dataset:
loss = train_step(batch)
loss_metric.update_state(loss)
print(f"Average loss: {loss_metric.result().numpy()}")
Loss / Label Format Mismatch
model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True))
model.compile(loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True))
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True))
Retracing Performance
@tf.function
def predict(x):
return model(x)
predict(np.zeros((1, 10)))
predict(np.zeros((32, 10)))
predict(np.zeros((64, 10)))
@tf.function(input_signature=[tf.TensorSpec(shape=[None, 10], dtype=tf.float32)])
def predict(x):
return model(x)
TensorFlow's power comes from layering: tf.data for efficient pipelines, tf.keras for clean model definition across three paradigms, @tf.function for graph-mode speed, and tf.GradientTape for full training control. Master these four building blocks and you can tackle any deep learning task — from quick prototypes with model.fit() to production systems with custom loops and deployment.