writing-skills
writing-skills
Use when creating new skills, editing existing skills, or verifying skills work before deployment
tensorflow-deep-learningBest practices for building, training, evaluating, and deploying neural networks with TensorFlow and Keras. Use when writing tf.data input pipelines, defining or training a Keras model, configuring callbacks for checkpointing and early stopping, evaluating a trained model, or exporting a model for serving.
Independent GitHub snapshot · Automated classification · Original documentation governs
This skill covers project structure, model development, training, evaluation, and deployment practices for neural networks built with TensorFlow and Keras.
tf.data.Dataset for scalable, prefetching input processing; validate shapes, dtypes, label ranges, and class balance before writing any model code.ModelCheckpoint (save best by validation metric, not final epoch), EarlyStopping, a learning-rate schedule, and TensorBoard logging.model.export() or tf.saved_model.save() and define serving input signatures explicitly.data.py, model.py, train.py, evaluate.py, serve.py).artifacts/ or a configured output path), so they don't get swept into version control accidentally.project/
data.py # tf.data pipeline construction
model.py # Keras model definition
config.py # typed hyperparameter config
train.py # training loop / Keras fit orchestration
evaluate.py # metrics computation on held-out data
serve.py # export + inference smoke test
artifacts/ # checkpoints, logs, saved models (gitignored)
import tensorflow as tf
def build_dataset(file_pattern: str, batch_size: int, shuffle: bool) -> tf.data.Dataset:
files = tf.data.Dataset.list_files(file_pattern, shuffle=shuffle)
ds = files.interleave(
tf.data.TFRecordDataset,
cycle_length=tf.data.AUTOTUNE,
num_parallel_calls=tf.data.AUTOTUNE,
)
ds = ds.map(_parse_example, num_parallel_calls=tf.data.AUTOTUNE)
if shuffle:
ds = ds.shuffle(buffer_size=10_000)
ds = ds.batch(batch_size, drop_remainder=False)
return ds.prefetch(tf.data.AUTOTUNE)
def _parse_example(record: tf.Tensor) -> tuple[tf.Tensor, tf.Tensor]:
feature_spec = {
"features": tf.io.FixedLenFeature([32], tf.float32),
"label": tf.io.FixedLenFeature([], tf.int64),
}
parsed = tf.io.parse_single_example(record, feature_spec)
return parsed["features"], parsed["label"]
num_parallel_calls=tf.data.AUTOTUNE on .map()/.interleave() and always end the pipeline with .prefetch(tf.data.AUTOTUNE).tf.keras.Model, tf.keras.Sequential) unless a specific need requires lower-level tf.GradientTape control.tf.random.set_seed, numpy.random.seed) where reproducibility matters, but document that GPU execution can still be nondeterministic for some ops (e.g., certain cuDNN reductions).tf.keras.mixed_precision.set_global_policy("mixed_float16")) after validating numerical stability at full precision — some losses (e.g., ones involving log or exp) need loss scaling to avoid underflow.import tensorflow as tf
def build_model(input_dim: int, num_classes: int) -> tf.keras.Model:
inputs = tf.keras.Input(shape=(input_dim,), name="features")
x = tf.keras.layers.Dense(128, activation="relu")(inputs)
x = tf.keras.layers.Dropout(0.3)(x)
x = tf.keras.layers.Dense(64, activation="relu")(x)
outputs = tf.keras.layers.Dense(num_classes, activation="softmax", name="predictions")(x)
return tf.keras.Model(inputs=inputs, outputs=outputs, name="baseline_classifier")
import tensorflow as tf
model = build_model(input_dim=32, num_classes=10)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
callbacks = [
tf.keras.callbacks.ModelCheckpoint(
filepath="artifacts/checkpoints/best.keras",
monitor="val_accuracy",
save_best_only=True,
),
tf.keras.callbacks.EarlyStopping(
monitor="val_loss", patience=5, restore_best_weights=True,
),
tf.keras.callbacks.ReduceLROnPlateau(
monitor="val_loss", factor=0.5, patience=3, min_lr=1e-6,
),
tf.keras.callbacks.TensorBoard(log_dir="artifacts/logs"),
]
train_ds = build_dataset("data/train-*.tfrecord", batch_size=64, shuffle=True)
val_ds = build_dataset("data/val-*.tfrecord", batch_size=64, shuffle=False)
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=50,
callbacks=callbacks,
)
TensorBoard, or an experiment tracker) for every run.save_best_only=True), not just the weights from the final epoch — the final epoch is not necessarily the best one, especially with EarlyStopping.test_ds = build_dataset("data/test-*.tfrecord", batch_size=64, shuffle=False)
results = model.evaluate(test_ds, return_dict=True)
print(results) # {'loss': ..., 'accuracy': ...}
model.export("artifacts/saved_model/v1")
# Or with an explicit serving signature:
@tf.function(input_signature=[tf.TensorSpec(shape=[None, 32], dtype=tf.float32, name="features")])
def serve_fn(features):
return {"predictions": model(features, training=False)}
tf.saved_model.save(model, "artifacts/saved_model/v1", signatures={"serving_default": serve_fn})
tf.keras.layers.Normalization as part of the model) rather than duplicating logic in a separate serving-side script.SavedModel and runs inference on a handful of known sample inputs, asserting outputs are in the expected range/shape, before promoting a model to production.