Your ad could be here - Reach CV/ML engineers
Contact for advertisingContactInterested in advertising?
Contact usStay updated
News & InsightsSetting 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 applicationp=0.0
: Transform is never considered for applicationp=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 unchangedp=1.0
: Pipeline always runs, inner transforms get a chance based on their own probabilities0 < 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
withp=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 withp=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:
- Sum of probabilities:
0.9 + 0.7 = 1.6
- Normalized probability for
GaussNoise
:0.9 รท 1.6 = 0.5625
(56.25%) - Normalized probability for
ISONoise
:0.7 รท 1.6 = 0.4375
(43.75%)
Selection Results ๐
If the OneOf
block runs:
GaussNoise
is selected 56.25% of the timeISONoise
is selected 43.75% of the time
Overall Probability Calculations ๐
The actual probability of each transform being applied to the original image is the product of all probability layers:
Mathematical Breakdown ๐
Transform | Calculation | Final Probability |
---|---|---|
RandomRotate90 | 0.95 ร 0.85 | 80.75% |
GaussNoise | 0.95 ร 0.75 ร 0.5625 | 40.08% |
ISONoise | 0.95 ร 0.75 ร 0.4375 | 31.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:
RandomRotate90
: Can select 0ยฐ rotation (no change)D4
: Can select identity transformationRandomGridShuffle
: Might shuffle back to original positions
Identity Parameter Sampling ๐
Geometric transforms can sample identity parameters:
Affine(rotate=(-10, 10))
: Might sample rotation = 0ยฐShiftScaleRotate
: Could sample shift=0, scale=1, rotate=0
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 ๐
- Be Explicit: Always set
p
values explicitly rather than relying on defaults - Consider Independence: Remember that transform probabilities are independent within
Compose
- Calculate Overall Effects: Use the multiplication rule to understand final probabilities
- 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:
- Review Pipelines: See how probabilities function within different composition utilities like
Compose
,OneOf
,SomeOf
, andSequential
. - Visually Explore Transforms: Experiment with different augmentations, their parameters, and consider the impact of their
p
values. - See Basic Usage Examples: Look at practical code applying pipelines with specific probabilities for different tasks.
- Learn How to Pick Augmentations: Get insights into choosing appropriate transforms and their probabilities.
- Understand Reproducibility: Learn how seeds interact with probabilities to ensure consistent results when needed.