tensorflow — Cursor rule: what it does, how to install
This rule guides TensorFlow work in Python, steering model code toward tf.keras and input pipelines toward tf.data. It also covers graph compilation and reproducible runs.
.cursor/rules/tensorflow.mdcWhat tensorflow does
The rule applies to **/*.py files. For models, it points to tf.keras: the Functional API for complex architectures and Sequential for straightforward stacks. For input data, it recommends tf.data pipelines that transform and batch records, with shuffling and prefetching shown in the examples.
For custom training steps, the guidance uses @tf.function; for repeatable experiments, it sets random seeds across TensorFlow, NumPy, and Python. It also recommends type annotations and a project virtual environment using venv or conda. Python side effects inside @tf.function may not behave as expected, so the rule recommends tf.print for output during graph execution.
What it helps with
- define TensorFlow models with
tf.keras - stream training data through
tf.data - compile a custom training step with
@tf.function - set random seeds across TensorFlow, NumPy, and Python
- add type annotations to tensor-processing functions
Example prompts for the agent
- Refactor this Python model to use
tf.kerasand feed its inputs throughtf.data. - Review this TensorFlow training step and show where
@tf.functionbelongs. - Add seed-setting code for TensorFlow, NumPy, and Python to this training script.
How to install tensorflow
Manually: put the files in place
.cursor/rules/tensorflow.mdcFrontmatter: description, globs, alwaysApply
Manually: put the files in place
.claude/rules/tensorflow.mdThe paths frontmatter field limits the files: move globs from the source into paths
AGENTS.md
Codex reads AGENTS.md: paste the rule text there
Manually: put the files in place
.github/instructions/tensorflow.instructions.mdThe applyTo field sets which files it applies to: move globs from the source into applyTo
Manually: put the files in place
.devin/rules/tensorflow.mdManually: put the files in place
.clinerules/tensorflow.mdStep by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules
Questions about tensorflow
How do I install the tensorflow rule in Cursor?
Create .cursor/rules/tensorflow.mdc in the project and add the rule contents to that file.
What does the tensorflow rule do?
It guides TensorFlow Python code toward tf.keras models and tf.data input pipelines, and covers @tf.function for training steps.
How does the rule handle training data pipelines?
It recommends tf.data.Dataset pipelines with transformations, shuffling, batching, and prefetching. Its examples also use parallel calls with map().
Source text
tensorflow.mdc · CC0-1.0
---
description: This guide defines the definitive best practices for writing TensorFlow code, focusing on `tf.keras` for models, `tf.data` for input pipelines, and `@tf.function` for performance, ensuring reproducible, scalable, and production-ready ML systems.
globs: **/*.py
---
# tensorflow Best Practices
This document outlines our team's definitive guidelines for writing TensorFlow code. Adhering to these practices ensures maintainable, performant, and reproducible machine learning systems.
## 1. Code Organization and Structure
Always structure your TensorFlow projects for clarity and modularity. Separate concerns into distinct files or functions.
### 1.1. Model Definition: Use `tf.keras`
Always define models using the `tf.keras` API. It's the high-level, declarative standard for TensorFlow. Prefer the Functional API for complex models and `Sequential` for simple stacks.
❌ BAD: Raw `tf.Variable` and custom loops for model architecture.
```python
import tensorflow as tf
class BadCustomModel:
def __init__(self):
self.w1 = tf.Variable(tf.random.normal([784, 128]))
self.b1 = tf.Variable(tf.zeros([128]))
# ... more manual variables
```
✅ GOOD: `tf.keras.Model` or `tf.keras.Sequential`.
```python
import tensorflow as tf
def build_model(input_shape: tuple[int, ...], num_classes: int) -> tf.keras.Model:
inputs = tf.keras.Input(shape=input_shape)
x = tf.keras.layers.Flatten()(inputs)
x = tf.keras.layers.Dense(128, activation='relu')(x)
x = tf.keras.layers.Dropout(0.2)(x)
outputs = tf.keras.layers.Dense(num_classes, activation='softmax')(x)
return tf.keras.Model(inputs=inputs, outputs=outputs)
# Usage:
model = build_model((28, 28), 10)
```
### 1.2. Data Pipelines: Use `tf.data`
Always use the `tf.data` API for building robust and efficient input pipelines. This is critical for scaling to large datasets and optimizing I/O.
❌ BAD: Loading all data into memory or using `numpy` arrays for large datasets.
```python
import numpy as np
# ... load huge_data into numpy array
# x_train, y_train = np.load('huge_data.npy')
# model.fit(x_train, y_train, batch_size=32) # Inefficient for large data
```
✅ GOOD: Stream data with `tf.data.Dataset`.
```python
import tensorflow as tf
import tensorflow_datasets as tfds
def create_dataset(split: str, batch_size: int) -> tf.data.Dataset:
ds = tfds.load('mnist', split=split, as_supervised=True)
ds = ds.map(lambda img, label: (tf.cast(img, tf.float32) / 255.0, label))
ds = ds.shuffle(1024).batch(batch_size).prefetch(tf.data.AUTOTUNE)
return ds
# Usage:
train_ds = create_dataset('train', 128)
test_ds = create_dataset('test', 128)
```
## 2. Common Patterns and Anti-patterns
### 2.1. Performance Critical Code: Use `@tf.function`
Always wrap pure TensorFlow operations and custom training loops in `@tf.function` to enable graph compilation and performance optimizations (e.g., XLA). Understand its graph-building semantics.
❌ BAD: Relying solely on eager execution for production training/inference.
```python
# Slower due to Python overhead per operation
for epoch in range(epochs):
for x_batch, y_batch in train_ds:
with tf.GradientTape() as tape:
logits = model(x_batch, training=True)
loss = loss_fn(y_batch, logits)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
```
✅ GOOD: Compile with `@tf.function`.
```python
import tensorflow as tf
@tf.function
def train_step(model: tf.keras.Model, optimizer: tf.keras.optimizers.Optimizer,
loss_fn: tf.keras.losses.Loss, x_batch: tf.Tensor, y_batch: tf.Tensor):
with tf.GradientTape() as tape:
logits = model(x_batch, training=True)
loss = loss_fn(y_batch, logits)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
# Usage in training loop:
# for epoch in range(epochs):
# for x_batch, y_batch in train_ds:
# train_step(model, optimizer, loss_fn, x_batch, y_batch)
```
### 2.2. Reproducibility: Pin Random Seeds
Always set global and operational random seeds to ensure reproducibility across runs. This is non-negotiable for reliable experimentation.
❌ BAD: Not setting any seeds, leading to non-deterministic results.
```python
# Results will vary between runs
model = tf.keras.Sequential([...])
```
✅ GOOD: Set all relevant seeds.
```python
import tensorflow as tf
import numpy as np
import random
def set_all_seeds(seed: int = 42):
np.random.seed(seed)
random.seed(seed)
tf.random.set_seed(seed)
# For CUDA operations, if applicable
# os.environ['TF_DETERMINISTIC_OPS'] = '1'
set_all_seeds(42)
model = tf.keras.Sequential([...])
```
## 3. Performance Considerations
### 3.1. Data Preprocessing: Optimize `tf.data`
Leverage `tf.data` features like `cache()`, `prefetch()`, and `num_parallel_calls` for `map()` to prevent I/O bottlenecks.
✅ GOOD: Efficient `tf.data` pipeline.
```python
import tensorflow as tf
def optimized_dataset(filepaths: list[str], batch_size: int) -> tf.data.Dataset:
ds = tf.data.TFRecordDataset(filepaths) # Or from_tensor_slices, etc.
ds = ds.map(parse_example_fn, num_parallel_calls=tf.data.AUTOTUNE)
ds = ds.cache() # Cache data after initial processing
ds = ds.shuffle(buffer_size=10000)
ds = ds.batch(batch_size)
ds = ds.prefetch(tf.data.AUTOTUNE) # Preload next batch
return ds
```
## 4. Common Pitfalls and Gotchas
### 4.1. `tf.function` Side Effects
Avoid Python side effects (e.g., printing, appending to lists) within `@tf.function` decorated functions if you expect them to execute every time. Graph compilation can hoist or ignore them.
❌ BAD: Expecting Python `print` to execute on every graph call.
```python
@tf.function
def my_func(x):
tf.print("Tracing or executing once!") # Only prints on first call/trace
return x + 1
```
✅ GOOD: Use `tf.print` for debugging inside graphs.
```python
@tf.function
def my_func(x):
tf.print("This prints every time the graph executes:", x)
return x + 1
```
## 5. Type Hints
Always use Python type hints for all function signatures and variables. This improves code readability, maintainability, and enables static analysis. Use `tf.Tensor` for TensorFlow tensors.
❌ BAD: Untyped functions.
```python
def process_data(data, label):
return data / 255.0, label
```
✅ GOOD: Fully type-hinted functions.
```python
import tensorflow as tf
def process_data(data: tf.Tensor, label: tf.Tensor) -> tuple[tf.Tensor, tf.Tensor]:
"""Scales image data and returns it with the label."""
return tf.cast(data, tf.float32) / 255.0, label
```
## 6. Virtual Environments
Always use a virtual environment (`venv` or `conda`) for every project. This isolates dependencies and prevents conflicts.
✅ GOOD: Project-specific virtual environment.
```bash
python -m venv .venv
source .venv/bin/activate
pip install tensorflow mlflow
```
## 7. Packaging and Experiment Tracking
### 7.1. Project Packaging
Structure your project as a Python package (`src/my_project/`). Use `pyproject.toml` for dependency management and `setuptools` for packaging.
✅ GOOD: Standard Python package structure.
```
my_project/
├── src/
│ └── my_project/
│ ├── __init__.py
│ ├── models.py
│ ├── data_pipeline.py
│ └── train.py
├── tests/
│ ├── test_models.py
│ └── test_data.py
├── pyproject.toml
└── README.md
```
### 7.2. Experiment Tracking with MLflow
Always integrate MLflow for experiment tracking. Log parameters, metrics, and model artifacts. This is crucial for reproducibility and collaboration.
✅ GOOD: MLflow integration.
```python
import mlflow
import tensorflow as tf
# Configure MLflow tracking URI (e.g., local, remote server)
mlflow.set_tracking_uri("http://localhost:5000")
mlflow.set_experiment("mnist_classification")
with mlflow.start_run():
# Log hyperparameters
mlflow.log_param("epochs", 5)
mlflow.log_param("optimizer", "adam")
model = tf.keras.models.Sequential([...])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# Use MLflow Keras callback for automatic metric logging
mlflow.tensorflow.autolog() # Enables auto-logging of metrics, params, model
model.fit(train_ds, epochs=5, validation_data=test_ds)
# Evaluate and log final metrics if not using autolog
# results = model.evaluate(test_ds)
# mlflow.log_metric("test_loss", results[0])
# mlflow.log_metric("test_accuracy", results[1])
# Save the model
# mlflow.tensorflow.log_model(model, "mnist_model")
```
## 8. Testing Approaches
Always implement comprehensive testing for your TensorFlow code.
### 8.1. Unit Tests
Write unit tests for custom layers, preprocessing functions, and utility modules. Use `tf.test.TestCase` for tests involving TensorFlow operations.
✅ GOOD: Unit test for a custom layer.
```python
import tensorflow as tf
from tensorflow.python.platform import test
class MyCustomLayer(tf.keras.layers.Layer):
def call(self, inputs):
return inputs * 2
class MyCustomLayerTest(test.TestCase):
def test_output_shape(self):
layer = MyCustomLayer()
input_tensor = tf.zeros((10, 5))
output_tensor = layer(input_tensor)
self.assertEqual(output_tensor.shape, (10, 5))
def test_output_values(self):
layer = MyCustomLayer()
input_tensor = tf.constant([1.0, 2.0, 3.0])
output_tensor = layer(input_tensor)
self.assertAllEqual(output_tensor, tf.constant([2.0, 4.0, 6.0]))
if __name__ == '__main__':
test.main()
```
### 8.2. Data Sanity Checks
Implement sanity checks for all input data sources to catch issues early.
✅ GOOD: Basic data validation.
```python
import tensorflow as tf
def validate_image_dataset(dataset: tf.data.Dataset, expected_shape: tuple, expected_dtype: tf.DType):
for images, labels in dataset.take(1):
tf.Assert(tf.equal(tf.shape(images)[1:], expected_shape), ["Image shape mismatch"])
tf.Assert(tf.equal(images.dtype, expected_dtype), ["Image dtype mismatch"])
tf.Assert(tf.reduce_all(images >= 0.0) and tf.reduce_all(images <= 1.0), ["Image pixel values out of range"])
tf.print("Data sanity check passed for one batch.")
# Usage:
# validate_image_dataset(train_ds, (28, 28, 1), tf.float32)
```
### 8.3. Integration Tests
Test the full data pipeline and model training loop end-to-end with small, representative datasets.
© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc