Sampling¶
Sampling operates on a DatasetQuery. For filtering, sorting, and slicing examples
that define the input set for sampling, see Search and Filter.
Provides the user python interface to sampling bound to sample ids.
Sampling ¶
Sampling(dataset_id: UUID, session: Session, input_sample_ids: Iterable[UUID])
Smart sampling interface.
The Sampling class allows to select a subset of samples from a given set of input
samples. There are many different strategies to select samples, e.g. diversity based
on embeddings or weighting based on numeric metadata. Multiple strategies can be
combined to form more complex sampling strategies.
The result of a sampling is stored as a tag on the selected samples in the database.
The sampling_result_tag_name must be a tag name that is not used yet, with one
exception: reusing the preselected_tag_name adds the newly selected samples to
that tag, which lets a selection grow over repeated runs.
Creation of a Sampling instance.¶
Creation of an instance of this is easiest via the DatasetQuery class. By using
a match() first, the samples to select from can be filtered down.
from lightly_studio.core.dataset_query import ImageSampleField
# Select from all samples in the dataset.
sampling = dataset.query().sampling()
# Select only from samples with width < 256.
query_narrow_images = dataset.query().match(ImageSampleField.width < 256)
sampling_among_narrow_images = query_narrow_images.sampling()
DatasetQuery.match() documentation for more information on filtering.
By creating the Sampling instance, the query is executed. Further changes to the
query do not affect the sampling instance.
Performing single-strategy samplings.¶
Once a Sampling instance is created, different sampling strategies can be
applied to select samples. Single-strategy samplings are performed by calling
the respective method on the Sampling instance. All methods take the number of
samples to select and a tag name for the sampling result as mandatory arguments.
# Select 100 diverse samples based on embeddings
sampling.diverse(
n_samples_to_select=100,
sampling_result_tag_name="diverse sampling",
)
# Select 50 samples weighted by numeric metadata "difficulty"
sampling.metadata_weighting(
n_samples_to_select=50,
sampling_result_tag_name="weighted sampling",
metadata_key="difficulty",
)
# Select 100 samples with balanced annotation classes (e.g. uniform distribution)
sampling.annotation_balancing(
n_samples_to_select=100,
sampling_result_tag_name="balanced sampling",
target_distribution="uniform",
)
# Select 100 samples balanced over the values of the "weather" metadata
sampling.metadata_balancing(
n_samples_to_select=100,
sampling_result_tag_name="balanced weather sampling",
metadata_key="weather",
target_distribution="uniform",
)
Performing multi-strategy samplings.¶
More complex sampling strategies can be formed by combining multiple sampling
strategies. This is done via the multi_strategies() method, which takes a
list of sampling strategies as an argument.
from lightly_studio.sampling.sampling_config import (
EmbeddingDiversityStrategy,
MetadataWeightingStrategy
)
# Select 75 samples that are diverse and weighted by "difficulty"
sampling.multi_strategies(
n_samples_to_select=75,
sampling_result_tag_name="diverse and weighted sampling",
sampling_strategies=[
EmbeddingDiversityStrategy(),
MetadataWeightingStrategy(metadata_key="difficulty"),
],
)
Video sequence sampling.¶
On video frame collections, diverse() can select whole frame sequences by setting
selected_sequence_length to the number of frames per sequence; leaving it as None
selects individual frames. n_samples_to_select still counts frames and must be a
multiple of the sequence length. Only diversity strategies support sequences.
frames.query().sampling().diverse(
n_samples_to_select=100,
sampling_result_tag_name="sequence_clips",
selected_sequence_length=50,
)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
UUID
|
Dataset in which the sampling is performed. |
required |
session
|
Session
|
Database session to resolve sampling dependencies. |
required |
input_sample_ids
|
Iterable[UUID]
|
Candidate sample ids considered for sampling. The iterable is consumed immediately to capture a stable snapshot. |
required |
annotation_balancing ¶
annotation_balancing(
n_samples_to_select: int,
sampling_result_tag_name: str,
target_distribution: AnnotationClassToTarget | Literal["uniform"] | Literal["input"],
preselected_tag_name: str | None = None,
) -> None
Select a subset using annotation class balancing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
target_distribution
|
AnnotationClassToTarget | Literal['uniform'] | Literal['input']
|
Can be 'uniform', 'input', or a dictionary mapping class names to target ratios. |
required |
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
deduplicate ¶
deduplicate(
n_samples_to_select: int,
sampling_result_tag_name: str,
stopping_condition_minimum_distance: float,
embedding_model_name: str | None = None,
preselected_tag_name: str | None = None,
) -> None
Select a deduplicated subset using embeddings.
Removes near-duplicates by selecting samples that are spread out in
embedding space and stopping once the closest remaining sample would be
nearer than stopping_condition_minimum_distance to the already selected
samples. Fewer than n_samples_to_select samples may be selected if the
stopping condition is reached first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Maximum number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
stopping_condition_minimum_distance
|
float
|
Minimum embedding distance between selected samples. Selection stops once no remaining sample is at least this far from the already selected samples. |
required |
embedding_model_name
|
str | None
|
Optional embedding model name. If None, uses the only available model or raises if multiple exist. |
None
|
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
diverse ¶
diverse(
n_samples_to_select: int,
sampling_result_tag_name: str,
embedding_model_name: str | None = None,
preselected_tag_name: str | None = None,
selected_sequence_length: int | None = None,
) -> None
Select a diverse subset using embeddings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
embedding_model_name
|
str | None
|
Optional embedding model name. If None, uses the only available model or raises if multiple exist. |
None
|
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
selected_sequence_length
|
int | None
|
Number of frames per selected sequence, at least
2. |
None
|
metadata_balancing ¶
metadata_balancing(
n_samples_to_select: int,
sampling_result_tag_name: str,
metadata_key: str,
target_distribution: MetadataValueToTarget | Literal["uniform"] | Literal["input"],
preselected_tag_name: str | None = None,
) -> None
Select a subset using categorical metadata balancing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
metadata_key
|
str
|
Metadata key to balance. Must be categorical (string or boolean values). |
required |
target_distribution
|
MetadataValueToTarget | Literal['uniform'] | Literal['input']
|
Can be 'uniform', 'input', or a dictionary mapping metadata values to target ratios. The values of a boolean key are named with True and False or with the lowercase strings 'true' and 'false'. Values without a ratio share the ratio remaining to 1.0. |
required |
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
metadata_weighting ¶
metadata_weighting(
n_samples_to_select: int,
sampling_result_tag_name: str,
metadata_key: str,
preselected_tag_name: str | None = None,
) -> None
Select a subset based on numeric metadata weights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
metadata_key
|
str
|
Metadata key used as weights (float or int values). |
required |
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
multi_strategies ¶
multi_strategies(
n_samples_to_select: int,
sampling_result_tag_name: str,
sampling_strategies: list[SamplingStrategy],
preselected_tag_name: str | None = None,
selected_sequence_length: int | None = None,
) -> None
Select a subset based on multiple strategies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
sampling_strategies
|
list[SamplingStrategy]
|
Strategies to compose for sampling. |
required |
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
selected_sequence_length
|
int | None
|
Number of frames per selected sequence, at least
2. |
None
|
subpart_diversity ¶
subpart_diversity(
n_samples_to_select: int,
sampling_result_tag_name: str,
embedding_model_name: str | None = None,
annotation_source: str | None = None,
preselected_tag_name: str | None = None,
) -> None
Select a diverse subset based on the embeddings of annotated subparts (crops).
Each parent image contributes the embeddings of all its annotation crops. Sampling maximizes diversity across those crop embeddings so that selected images collectively cover a broad range of objects, not just a broad range of scene-level appearance.
When annotation_source is omitted, crops from all annotation sources
are merged. Pass annotation_source to restrict to one specific annotation source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples_to_select
|
int
|
Number of samples to select. |
required |
sampling_result_tag_name
|
str
|
Tag name for the sampling result. |
required |
embedding_model_name
|
str | None
|
Name of the embedding model to use for crop samples. If None, uses the only available model or raises if multiple exist. |
None
|
annotation_source
|
str | None
|
Optional annotation source name. When set, only crops from that annotation source contribute embeddings. When omitted, crops from all annotation sources are merged. |
None
|
preselected_tag_name
|
str | None
|
Optional tag containing samples that should be treated
as already selected. These samples are excluded from the result tag.
Pass the same name as |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |