# How to Use Anchor Generators for Object Detection in TensorFlow Models

> Learn to use anchor generators for object detection in TensorFlow Models. Create bounding-box templates efficiently using protobuf configuration and the anchor generator builder for your models.

- Repository: [tensorflow/models](https://github.com/tensorflow/models)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Anchor generators in TensorFlow Models create pre-defined bounding-box templates tiled over feature-map grids by reading a protobuf configuration, building a concrete generator via the anchor generator builder, and returning BoxList objects at runtime.**

The TensorFlow Models repository provides a flexible anchor generation system for object detection that converts static configuration into dynamic anchor boxes. This architecture supports multiple generator types—including grid, SSD, multiscale, and flexible-grid—to accommodate different detection backbones. Understanding how to configure and instantiate these generators is essential for customizing region-proposal networks (RPN) or downstream detection heads.

## What Are Anchor Generators?

**Anchor generators** produce **anchor boxes**, which are pre-defined bounding-box templates tiled across feature-map grids. In [`research/object_detection/core/anchor_generator.py`](https://github.com/tensorflow/models/blob/main/research/object_detection/core/anchor_generator.py), the abstract `AnchorGenerator` base class defines the public API, including the `generate()` method and `num_anchors_per_location()` property. Concrete implementations handle the geometric tiling logic, returning `BoxList` objects that networks use to propose object locations.

## Architecture of the Anchor Generator System

The system follows a three-tier architecture: configuration definition, builder instantiation, and runtime generation.

### Proto Configuration (`anchor_generator.proto`)

The `research/object_detection/protos/anchor_generator.proto` file declares the one-of options for four generator types: grid, SSD, multiscale, and flexible-grid. This protobuf serves as the single source of truth for anchor scales, aspect ratios, strides, and base sizes. Pipeline configuration files reference this proto to specify anchor behavior without modifying source code.

### The Builder Pattern ([`anchor_generator_builder.py`](https://github.com/tensorflow/models/blob/main/anchor_generator_builder.py))

The [`research/object_detection/builders/anchor_generator_builder.py`](https://github.com/tensorflow/models/blob/main/research/object_detection/builders/anchor_generator_builder.py) file implements the factory logic that converts protobuf messages into concrete generator instances. The `build()` function validates the proto, extracts the active one-of field, and maps parameters to the appropriate constructor. When the proto contains a `grid_anchor_generator` block, the builder instantiates `GridAnchorGenerator` with the specified scales and strides.

### Concrete Implementations

Four main implementations reside in `research/object_detection/anchor_generators/`:

- **GridAnchorGenerator**: Classic Faster R-CNN-style anchors with uniform scales and aspect ratios across the grid.
- **FlexibleGridAnchorGenerator**: Per-layer control over base sizes, strides, and aspect ratios for multi-scale detection.
- **MultiscaleAnchorGenerator**: Generates anchors at multiple feature-map scales simultaneously.
- **SSDAnchorGenerator**: SSD-specific anchor schemes with specialized tiling logic.

## Building an Anchor Generator from Configuration

To instantiate a generator programmatically, define a protobuf configuration and pass it to the builder.

```python
from object_detection.protos import anchor_generator_pb2
from object_detection.builders import anchor_generator_builder

# Define a GridAnchorGenerator configuration

grid_cfg = anchor_generator_pb2.AnchorGenerator()
grid_cfg.grid_anchor_generator.scales.extend([0.5, 1.0, 2.0])
grid_cfg.grid_anchor_generator.aspect_ratios.extend([0.5, 1.0, 2.0])
grid_cfg.grid_anchor_generator.height = 256
grid_cfg.grid_anchor_generator.width = 256
grid_cfg.grid_anchor_generator.height_stride = 16
grid_cfg.grid_anchor_generator.width_stride = 16

# Build the concrete generator

anchor_gen = anchor_generator_builder.build(grid_cfg)

```

As implemented in [`anchor_generator_builder.py`](https://github.com/tensorflow/models/blob/main/anchor_generator_builder.py) (lines 48-60), the builder extracts the `grid_anchor_generator` fields and constructs the class with matching constructor arguments.

## Generating Anchors for Feature Maps

At runtime, models pass feature-map shapes to the `generate()` method to receive tiled anchors.

```python

# Feature maps from the backbone: 8x8 and 4x4 spatial resolutions

feature_maps = [(8, 8), (4, 4)]

# Generate BoxList objects for each feature map

anchors_per_map = anchor_gen.generate(feature_maps)

# Inspect the first feature map's anchors

first_boxlist = anchors_per_map[0]
print("Anchors on first map:", first_boxlist.num_boxes())
print("First 3 boxes (y1, x1, y2, x2):", first_boxlist.get().numpy()[:3])

```

Under the hood, `GridAnchorGenerator._generate()` calls `tile_anchors()` (see [`grid_anchor_generator.py`](https://github.com/tensorflow/models/blob/main/grid_anchor_generator.py) lines 82-112) to create the `BoxList` and appends the `feature_map_index` field to track spatial origins.

## Advanced Usage: Flexible Grid Anchors

For architectures requiring per-layer anchor configurations, use `FlexibleGridAnchorGenerator` to specify unique parameters for each feature-map level.

```python
from object_detection.protos import anchor_generator_pb2
from object_detection.builders import anchor_generator_builder

flex_cfg = anchor_generator_pb2.AnchorGenerator()
flex_grid = flex_cfg.flexible_grid_anchor_generator

# Layer 0: small objects with fine stride

flex_grid.anchor_grid.add(
    base_sizes=[32.0, 64.0, 128.0],
    aspect_ratios=[0.5, 1.0],
    height_stride=8, width_stride=8,
    height_offset=4, width_offset=4)

# Layer 1: large objects with coarse stride

flex_grid.anchor_grid.add(
    base_sizes=[256.0, 512.0],
    aspect_ratios=[0.5, 1.0, 2.0],
    height_stride=16, width_stride=16,
    height_offset=8, width_offset=8)

anchor_gen = anchor_generator_builder.build(flex_cfg)

# Generate with normalization for 640x640 images

feature_maps = [(64, 64), (32, 32)]
anchors = anchor_gen.generate(feature_maps, im_height=640, im_width=640)

```

The flexible generator's `_generate()` method iterates over each layer configuration, invoking the shared tiling routine and optionally normalizing coordinates to [0, 1] when image dimensions are provided (see [`flexible_grid_anchor_generator.py`](https://github.com/tensorflow/models/blob/main/flexible_grid_anchor_generator.py) lines 82-134).

## Summary

- **Configuration**: Define anchor schemes in `anchor_generator.proto` using scales, aspect ratios, and strides.
- **Instantiation**: Use `anchor_generator_builder.build()` to convert protobuf configs into concrete generator objects.
- **Generation**: Call `generate(feature_map_shape_list)` at runtime to obtain `BoxList` objects tiled over each feature-map grid.
- **Flexibility**: Choose `GridAnchorGenerator` for uniform anchors or `FlexibleGridAnchorGenerator` for per-layer control.
- **Integration**: Generated anchors feed directly into RPN or detection heads via the `BoxList` API.

## Frequently Asked Questions

### What is the difference between GridAnchorGenerator and FlexibleGridAnchorGenerator?

**GridAnchorGenerator** applies uniform scales, aspect ratios, and strides across all feature-map levels, suitable for standard Faster R-CNN architectures. **FlexibleGridAnchorGenerator** allows independent configuration of base sizes, strides, and aspect ratios for each layer, enabling precise control for multi-scale detectors like feature pyramid networks.

### How do I normalize anchor coordinates to the image scale?

Pass the image dimensions (`im_height` and `im_width`) as keyword arguments to the `generate()` method. The flexible grid implementation automatically normalizes coordinates to [0, 1] when these parameters are provided, as implemented in [`flexible_grid_anchor_generator.py`](https://github.com/tensorflow/models/blob/main/flexible_grid_anchor_generator.py).

### Can I use multiple anchor generator types in the same model?

The protobuf uses a one-of constraint, so a single configuration block selects one generator type. However, you can instantiate multiple generator objects programmatically using separate protobuf configs and merge their output `BoxList` objects manually before feeding them to the detection head.

### Where does the builder map proto fields to constructor arguments?

In [`research/object_detection/builders/anchor_generator_builder.py`](https://github.com/tensorflow/models/blob/main/research/object_detection/builders/anchor_generator_builder.py), the `build()` function checks which one-of field is populated in the proto (e.g., `grid_anchor_generator`), then extracts lists of scales and aspect ratios and passes them to the matching class constructor, handling type conversion automatically.