Interested in advertising?

Contact us

Stay updated

News & Insights
Lib Comparison
Targets by TransformFAQ
API Reference

Setting Probabilities for Transforms in Augmentation Pipelines ๐Ÿ”—

Each augmentation in Albumentations has a parameter named p that controls the probability of applying that augmentation to input data. Understanding how probabilities work is essential for creating effective and predictable augmentation pipelines.

Quick Reference ๐Ÿ”—

Key Concepts:

  • p=1.0: Transform is always considered for application
  • p=0.0: Transform is never considered for application
  • p=0.5: Transform has a 50% chance of being considered
  • Pipeline probability: Overall chance the entire pipeline runs
  • Nested probabilities: How probabilities combine in composition blocks like OneOf

Basic Probability Mechanics ๐Ÿ”—

Individual Transform Probability ๐Ÿ”—

Setting p=1 means the transform will always be considered for application, while p=0 means it will never be considered. A value between 0 and 1 represents the chance it will be considered.

Some transforms default to p=1, while others default to p=0.5. Since default values can vary, it is recommended to explicitly set the p value for each transform in your pipeline to ensure clarity and avoid unexpected behavior.

Probability in Practice ๐Ÿ”—

import albumentations as A
import numpy as np

# Create a simple example
transform = A.Compose([
    A.HorizontalFlip(p=0.5),        # 50% chance to flip
    A.RandomBrightnessContrast(p=0.8),  # 80% chance to adjust brightness/contrast
    A.GaussianBlur(p=0.3),         # 30% chance to blur
])

# Each transform runs independently based on its p value
image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
transformed = transform(image=image)

Complex Probability Example ๐Ÿ”—

Let's examine a more complex pipeline to understand how probabilities interact:

import albumentations as A
import numpy as np

# Define probabilities for clarity
prob_pipeline = 0.95
prob_rotate = 0.85
prob_oneof_noise = 0.75

# Define the augmentation pipeline
transform = A.Compose([
    A.RandomRotate90(p=prob_rotate),     # 85% chance to be considered
    A.OneOf([
        A.GaussNoise(p=0.9),             # 90% weight within OneOf block
        A.ISONoise(p=0.7),               # 70% weight within OneOf block
    ], p=prob_oneof_noise)               # 75% chance for OneOf block to run
], p=prob_pipeline,                      # 95% chance for entire pipeline to run
  seed=137)                             # Seed for reproducibility

# Apply the transform
image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
transformed = transform(image=image)
transformed_image = transformed['image']

print("Transformation applied:", not np.array_equal(image, transformed_image))

How Different Probability Levels Work ๐Ÿ”—

Pipeline Probability (prob_pipeline) ๐Ÿ”—

The p parameter in A.Compose determines if any augmentations within it are applied:

  • p=0.0: Pipeline never runs, input is always returned unchanged
  • p=1.0: Pipeline always runs, inner transforms get a chance based on their own probabilities
  • 0 < p < 1: Pipeline runs with that specific probability

In our example (prob_pipeline = 0.95), the pipeline runs 95% of the time.

Individual Transform Probability (prob_rotate) ๐Ÿ”—

Once the pipeline runs, each transform has its own probability:

  • RandomRotate90 with p=0.85 has an 85% chance of being applied
  • This is independent of other transforms in the pipeline

Composition Block Probability (prob_oneof_noise) ๐Ÿ”—

Composition utilities like OneOf have their own probability layer:

  • OneOf block with p=0.75 has a 75% chance to run
  • If it runs, it executes exactly one of its contained transforms

Probability Calculations in OneOf ๐Ÿ”—

How Selection Works ๐Ÿ”—

When a OneOf block runs, it normalizes the probabilities of inner transforms to determine selection weights:

Example transforms in OneOf:

  • GaussNoise(p=0.9)
  • ISONoise(p=0.7)

Normalization process:

  1. Sum of probabilities: 0.9 + 0.7 = 1.6
  2. Normalized probability for GaussNoise: 0.9 รท 1.6 = 0.5625 (56.25%)
  3. Normalized probability for ISONoise: 0.7 รท 1.6 = 0.4375 (43.75%)

Selection Results ๐Ÿ”—

If the OneOf block runs:

Overall Probability Calculations ๐Ÿ”—

The actual probability of each transform being applied to the original image is the product of all probability layers:

Mathematical Breakdown ๐Ÿ”—

TransformCalculationFinal Probability
RandomRotate900.95 ร— 0.8580.75%
GaussNoise0.95 ร— 0.75 ร— 0.562540.08%
ISONoise0.95 ร— 0.75 ร— 0.437531.15%

Formula Pattern ๐Ÿ”—

Final Probability = Pipeline_p ร— Block_p ร— Normalized_Transform_p

Edge Cases: When p=1 Doesn't Change the Image ๐Ÿ”—

Even when a transform is applied (p=1 or probability check succeeds), the image might not visually change in certain cases:

Identity Operations ๐Ÿ”—

Transforms with identity operations in their selection:

Identity Parameter Sampling ๐Ÿ”—

Geometric transforms can sample identity parameters:

Example:

# This always applies identity transformation
A.Affine(rotate=0, scale=1, translate_px=0, p=1)

# This might randomly sample identity parameters
A.Affine(rotate=(-10, 10), scale=(0.9, 1.1), p=1)

Key Point: The p parameter controls whether a transform runs, but the transform's internal logic determines whether that execution visually changes the image.

Best Practices ๐Ÿ”—

Probability Setting Guidelines ๐Ÿ”—

  1. Be Explicit: Always set p values explicitly rather than relying on defaults
  2. Consider Independence: Remember that transform probabilities are independent within Compose
  3. Calculate Overall Effects: Use the multiplication rule to understand final probabilities
  4. Test Your Pipeline: Verify that your probability settings achieve the desired augmentation frequency

Common Patterns ๐Ÿ”—

# Light augmentation (conservative)
light_transform = A.Compose([
    A.HorizontalFlip(p=0.3),
    A.RandomBrightnessContrast(p=0.2),
    A.GaussianBlur(p=0.1),
])

# Moderate augmentation (balanced)
moderate_transform = A.Compose([
    A.HorizontalFlip(p=0.5),
    A.OneOf([
        A.RandomBrightnessContrast(p=1.0),
        A.HueSaturationValue(p=1.0),
    ], p=0.3),
    A.GaussianBlur(p=0.2),
])

# Heavy augmentation (aggressive)
heavy_transform = A.Compose([
    A.HorizontalFlip(p=0.7),
    A.RandomBrightnessContrast(p=0.6),
    A.OneOf([
        A.GaussianBlur(p=1.0),
        A.MedianBlur(p=1.0),
        A.MotionBlur(p=1.0),
    ], p=0.4),
])

Where to Go Next? ๐Ÿ”—

Understanding probabilities is crucial for controlling your augmentation pipelines. Now you can: