lightly-studio 0.3.2__py3-none-any.whl → 0.3.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lightly-studio might be problematic. Click here for more details.
- lightly_studio/__init__.py +1 -1
- lightly_studio/api/app.py +8 -4
- lightly_studio/api/db_tables.py +0 -3
- lightly_studio/api/routes/api/annotation.py +26 -0
- lightly_studio/api/routes/api/annotations/__init__.py +7 -0
- lightly_studio/api/routes/api/annotations/create_annotation.py +52 -0
- lightly_studio/api/routes/api/caption.py +30 -0
- lightly_studio/api/routes/api/dataset.py +3 -5
- lightly_studio/api/routes/api/embeddings2d.py +136 -0
- lightly_studio/api/routes/api/export.py +73 -0
- lightly_studio/api/routes/api/metadata.py +57 -1
- lightly_studio/api/routes/api/selection.py +87 -0
- lightly_studio/core/add_samples.py +138 -9
- lightly_studio/core/dataset.py +174 -63
- lightly_studio/core/dataset_query/dataset_query.py +5 -0
- lightly_studio/dataset/env.py +4 -0
- lightly_studio/dataset/file_utils.py +13 -2
- lightly_studio/dataset/loader.py +2 -62
- lightly_studio/dataset/mobileclip_embedding_generator.py +3 -2
- lightly_studio/db_manager.py +10 -4
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/0.B3oFNb6O.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/2.CkOblLn7.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/Samples.CIbricz7.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.7Ma7YdVg.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/{useFeatureFlags.CV-KWLNP.css → _layout.CefECEWA.css} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/transform.2jKMtOWG.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/-DXuGN29.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{Ccq4ZD0B.js → B7302SU7.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BeWf8-vJ.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Bqz7dyEC.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C1FmrZbK.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{DRZO-E-T.js → CSCQddQS.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CZGpyrcA.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CfQ4mGwl.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CiaNZCBa.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cqo0Vpvt.js +417 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cy4fgWTG.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D5w4xp5l.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DD63uD-T.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DQ8aZ1o-.js +3 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{Df3aMO5B.js → DSxvnAMh.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D_JuJOO3.js +20 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D_ynJAfY.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Dafy4oEQ.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{BqBqV92V.js → Dj4O-5se.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DmjAI-UV.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Dug7Bq1S.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Dv5BSBQG.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DzBTnFhV.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DzX_yyqb.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Frwd2CjB.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/H4l0JFh9.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/H60ATh8g.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/qIv1kPyv.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/sLqs1uaK.js +20 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/u-it74zV.js +96 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.BPc0HQPq.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.SNvc2nrm.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.5jT7P06o.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/1.Cdy-7S5q.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.C_uoESTX.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.DcO8wIAc.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.BIldfkxL.js +1012 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{3.w9g4AcAx.js → 3.BC9z_TWM.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{4.BBI8KwnD.js → 4.D8X_Ch5n.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.CAXhxJu6.js +39 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{6.CrbkRPam.js → 6.DRA5Ru_2.js} +1 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.WVBsruHQ.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.BuKUrCEN.js +20 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/9.CUIn1yCR.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/clustering.worker-DKqeLtG0.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/search.worker-vNSty3B0.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/version.json +1 -1
- lightly_studio/dist_lightly_studio_view_app/index.html +15 -14
- lightly_studio/examples/example.py +4 -0
- lightly_studio/examples/example_coco.py +4 -0
- lightly_studio/examples/example_coco_caption.py +24 -0
- lightly_studio/examples/example_metadata.py +4 -1
- lightly_studio/examples/example_selection.py +4 -0
- lightly_studio/examples/example_split_work.py +4 -0
- lightly_studio/examples/example_yolo.py +4 -0
- lightly_studio/export/export_dataset.py +73 -0
- lightly_studio/export/lightly_studio_label_input.py +120 -0
- lightly_studio/few_shot_classifier/classifier_manager.py +5 -26
- lightly_studio/metadata/compute_typicality.py +67 -0
- lightly_studio/models/annotation/annotation_base.py +11 -12
- lightly_studio/models/caption.py +73 -0
- lightly_studio/models/dataset.py +1 -2
- lightly_studio/models/metadata.py +1 -1
- lightly_studio/models/sample.py +2 -2
- lightly_studio/resolvers/annotation_label_resolver/__init__.py +2 -1
- lightly_studio/resolvers/annotation_label_resolver/get_all.py +15 -0
- lightly_studio/resolvers/annotation_resolver/__init__.py +2 -3
- lightly_studio/resolvers/annotation_resolver/create_many.py +3 -3
- lightly_studio/resolvers/annotation_resolver/delete_annotation.py +1 -1
- lightly_studio/resolvers/annotation_resolver/delete_annotations.py +7 -3
- lightly_studio/resolvers/annotation_resolver/get_by_id.py +19 -1
- lightly_studio/resolvers/annotation_resolver/update_annotation_label.py +0 -1
- lightly_studio/resolvers/annotations/annotations_filter.py +1 -11
- lightly_studio/resolvers/caption_resolver.py +80 -0
- lightly_studio/resolvers/dataset_resolver.py +4 -7
- lightly_studio/resolvers/metadata_resolver/__init__.py +2 -2
- lightly_studio/resolvers/metadata_resolver/sample/__init__.py +3 -3
- lightly_studio/resolvers/metadata_resolver/sample/bulk_update_metadata.py +46 -0
- lightly_studio/resolvers/samples_filter.py +18 -10
- lightly_studio/selection/mundig.py +7 -10
- lightly_studio/selection/selection_config.py +4 -1
- lightly_studio/services/annotations_service/__init__.py +8 -0
- lightly_studio/services/annotations_service/create_annotation.py +63 -0
- lightly_studio/services/annotations_service/delete_annotation.py +22 -0
- lightly_studio/type_definitions.py +2 -0
- {lightly_studio-0.3.2.dist-info → lightly_studio-0.3.4.dist-info}/METADATA +231 -41
- {lightly_studio-0.3.2.dist-info → lightly_studio-0.3.4.dist-info}/RECORD +114 -104
- lightly_studio/api/routes/api/annotation_task.py +0 -37
- lightly_studio/api/routes/api/metrics.py +0 -76
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/0.DenzbfeK.css +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.BBm0IWdq.css +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.BNTuXSAe.css +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.T-zjSUd3.css +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/2O287xak.js +0 -3
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/7YNGEs1C.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BBoGk9hq.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BRnH9v23.js +0 -92
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Bg1Y5eUZ.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C0JiMuYn.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C98Hk3r5.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CG0dMCJi.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cpy-nab_.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Crk-jcvV.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cs31G8Qn.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CsKrY2zA.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cur71c3O.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CzgC3GFB.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D8GZDMNN.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DFRh-Spp.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DcGCxgpH.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DkR_EZ_B.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DqUGznj_.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/H7C68rOM.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/KpAtIldw.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/M1Q1F7bw.js +0 -4
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/OH7-C_mc.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/gLNdjSzu.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/i0ZZ4z06.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.BI-EA5gL.js +0 -2
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.CcsRl3cZ.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.BbO4Zc3r.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/1._I9GR805.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.J2RBFrSr.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.Cmqj25a-.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.C45iKJHA.js +0 -6
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.huHuxdiF.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.FomEdhD6.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.Cb_ADSLk.js +0 -1
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/9.CajIG5ce.js +0 -1
- lightly_studio/metrics/__init__.py +0 -0
- lightly_studio/metrics/detection/__init__.py +0 -0
- lightly_studio/metrics/detection/map.py +0 -268
- lightly_studio/models/annotation_task.py +0 -28
- lightly_studio/resolvers/annotation_resolver/create.py +0 -19
- lightly_studio/resolvers/annotation_task_resolver.py +0 -31
- lightly_studio/resolvers/metadata_resolver/sample/bulk_set_metadata.py +0 -48
- {lightly_studio-0.3.2.dist-info → lightly_studio-0.3.4.dist-info}/WHEEL +0 -0
|
@@ -33,20 +33,15 @@ class SampleFilter(BaseModel):
|
|
|
33
33
|
annotation_label_ids: Optional[List[UUID]] = None
|
|
34
34
|
tag_ids: Optional[List[UUID]] = None
|
|
35
35
|
metadata_filters: Optional[List[MetadataFilter]] = None
|
|
36
|
+
sample_ids: Optional[List[UUID]] = None
|
|
36
37
|
|
|
37
38
|
def apply(self, query: QueryType) -> QueryType:
|
|
38
39
|
"""Apply the filters to the given query."""
|
|
40
|
+
if self.sample_ids:
|
|
41
|
+
query = query.where(col(SampleTable.sample_id).in_(self.sample_ids))
|
|
42
|
+
|
|
39
43
|
# Apply dimension-based filters to the query.
|
|
40
|
-
|
|
41
|
-
if self.width.min is not None:
|
|
42
|
-
query = query.where(SampleTable.width >= self.width.min)
|
|
43
|
-
if self.width.max is not None:
|
|
44
|
-
query = query.where(SampleTable.width <= self.width.max)
|
|
45
|
-
if self.height:
|
|
46
|
-
if self.height.min is not None:
|
|
47
|
-
query = query.where(SampleTable.height >= self.height.min)
|
|
48
|
-
if self.height.max is not None:
|
|
49
|
-
query = query.where(SampleTable.height <= self.height.max)
|
|
44
|
+
query = self._apply_dimension_filters(query)
|
|
50
45
|
|
|
51
46
|
# Apply annotation label filters to the query.
|
|
52
47
|
if self.annotation_label_ids:
|
|
@@ -79,3 +74,16 @@ class SampleFilter(BaseModel):
|
|
|
79
74
|
metadata_join_condition=SampleMetadataTable.sample_id == SampleTable.sample_id,
|
|
80
75
|
)
|
|
81
76
|
return query
|
|
77
|
+
|
|
78
|
+
def _apply_dimension_filters(self, query: QueryType) -> QueryType:
|
|
79
|
+
if self.width:
|
|
80
|
+
if self.width.min is not None:
|
|
81
|
+
query = query.where(SampleTable.width >= self.width.min)
|
|
82
|
+
if self.width.max is not None:
|
|
83
|
+
query = query.where(SampleTable.width <= self.width.max)
|
|
84
|
+
if self.height:
|
|
85
|
+
if self.height.min is not None:
|
|
86
|
+
query = query.where(SampleTable.height >= self.height.min)
|
|
87
|
+
if self.height.max is not None:
|
|
88
|
+
query = query.where(SampleTable.height <= self.height.max)
|
|
89
|
+
return query
|
|
@@ -10,29 +10,26 @@ from typing import Iterable
|
|
|
10
10
|
# Or remove the type ignore once typing stubs were added manually.
|
|
11
11
|
import lightly_mundig # type: ignore[import-untyped]
|
|
12
12
|
import numpy as np
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
from lightly_studio.dataset.env import LIGHTLY_STUDIO_LICENSE_KEY
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class Mundig:
|
|
17
|
-
"""Python
|
|
18
|
+
"""Python interface for the Mundig selection algorithm.
|
|
18
19
|
|
|
19
20
|
This class provides a Python interface to the lightly_mundig Rust library
|
|
20
|
-
for sample selection.
|
|
21
|
+
for sample selection. It allows combining different selection strategies
|
|
22
|
+
such as diversity and weighting.
|
|
21
23
|
"""
|
|
22
24
|
|
|
23
25
|
def __init__(self) -> None:
|
|
24
26
|
"""Initialize the Mundig selection interface."""
|
|
25
|
-
|
|
26
|
-
env = Env()
|
|
27
|
-
env.read_env()
|
|
28
|
-
license_key = env.str("LIGHTLY_STUDIO_LICENSE_KEY", default=None)
|
|
29
|
-
if license_key is None:
|
|
27
|
+
if LIGHTLY_STUDIO_LICENSE_KEY is None:
|
|
30
28
|
raise ValueError(
|
|
31
29
|
"LIGHTLY_STUDIO_LICENSE_KEY environment variable is not set. "
|
|
32
30
|
"Please set it to your LightlyStudio license key."
|
|
33
31
|
)
|
|
34
|
-
|
|
35
|
-
self.mundig = lightly_mundig.Selection(token=license_key)
|
|
32
|
+
self.mundig = lightly_mundig.Selection(token=LIGHTLY_STUDIO_LICENSE_KEY)
|
|
36
33
|
|
|
37
34
|
self.n_input_samples: int | None = None
|
|
38
35
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from typing import Literal, Sequence
|
|
5
6
|
from uuid import UUID
|
|
6
7
|
|
|
7
8
|
from pydantic import BaseModel
|
|
@@ -13,7 +14,7 @@ class SelectionConfig(BaseModel):
|
|
|
13
14
|
dataset_id: UUID
|
|
14
15
|
n_samples_to_select: int
|
|
15
16
|
selection_result_tag_name: str
|
|
16
|
-
strategies:
|
|
17
|
+
strategies: Sequence[SelectionStrategy]
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class SelectionStrategy(BaseModel):
|
|
@@ -25,10 +26,12 @@ class SelectionStrategy(BaseModel):
|
|
|
25
26
|
class EmbeddingDiversityStrategy(SelectionStrategy):
|
|
26
27
|
"""Selection strategy based on embedding diversity."""
|
|
27
28
|
|
|
29
|
+
strategy_name: Literal["diversity"] = "diversity"
|
|
28
30
|
embedding_model_name: str | None
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
class MetadataWeightingStrategy(SelectionStrategy):
|
|
32
34
|
"""Selection strategy based on metadata weighting."""
|
|
33
35
|
|
|
36
|
+
strategy_name: Literal["weights"] = "weights"
|
|
34
37
|
metadata_key: str
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
"""Services for annotations operations."""
|
|
2
2
|
|
|
3
|
+
from lightly_studio.services.annotations_service.create_annotation import (
|
|
4
|
+
create_annotation,
|
|
5
|
+
)
|
|
6
|
+
from lightly_studio.services.annotations_service.delete_annotation import (
|
|
7
|
+
delete_annotation,
|
|
8
|
+
)
|
|
3
9
|
from lightly_studio.services.annotations_service.get_annotation_by_id import (
|
|
4
10
|
get_annotation_by_id,
|
|
5
11
|
)
|
|
@@ -17,6 +23,8 @@ from lightly_studio.services.annotations_service.update_annotations import (
|
|
|
17
23
|
)
|
|
18
24
|
|
|
19
25
|
__all__ = [
|
|
26
|
+
"create_annotation",
|
|
27
|
+
"delete_annotation",
|
|
20
28
|
"get_annotation_by_id",
|
|
21
29
|
"update_annotation",
|
|
22
30
|
"update_annotation_bounding_box",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Create annotation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
from sqlmodel import Session
|
|
9
|
+
|
|
10
|
+
from lightly_studio.models.annotation.annotation_base import (
|
|
11
|
+
AnnotationBaseTable,
|
|
12
|
+
AnnotationCreate,
|
|
13
|
+
AnnotationType,
|
|
14
|
+
)
|
|
15
|
+
from lightly_studio.resolvers import annotation_resolver
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AnnotationCreateParams(BaseModel):
|
|
19
|
+
"""Input model for create annotation service."""
|
|
20
|
+
|
|
21
|
+
annotation_label_id: UUID
|
|
22
|
+
annotation_type: AnnotationType
|
|
23
|
+
dataset_id: UUID
|
|
24
|
+
sample_id: UUID
|
|
25
|
+
|
|
26
|
+
x: int | None = None
|
|
27
|
+
y: int | None = None
|
|
28
|
+
width: int | None = None
|
|
29
|
+
height: int | None = None
|
|
30
|
+
|
|
31
|
+
segmentation_mask: list[int] | None = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def create_annotation(session: Session, annotation: AnnotationCreateParams) -> AnnotationBaseTable:
|
|
35
|
+
"""Create a new annotation.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
session: Database session for executing the operation.
|
|
39
|
+
annotation: Annotation data to create.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
The retrieved annotation.
|
|
43
|
+
"""
|
|
44
|
+
annotation_create = AnnotationCreate(
|
|
45
|
+
**annotation.model_dump(),
|
|
46
|
+
)
|
|
47
|
+
new_annotation_ids = annotation_resolver.create_many(
|
|
48
|
+
session=session,
|
|
49
|
+
annotations=[annotation_create],
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if not new_annotation_ids:
|
|
53
|
+
raise ValueError("Failed to create annotation.")
|
|
54
|
+
|
|
55
|
+
created_annotation = annotation_resolver.get_by_id(
|
|
56
|
+
session=session,
|
|
57
|
+
annotation_id=new_annotation_ids[0],
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
if created_annotation is None:
|
|
61
|
+
raise ValueError(f"Failed to create annotation: {annotation}")
|
|
62
|
+
|
|
63
|
+
return created_annotation
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Delete an annotation by its ID."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from sqlmodel import Session
|
|
8
|
+
|
|
9
|
+
from lightly_studio.resolvers import annotation_resolver
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def delete_annotation(session: Session, annotation_id: UUID) -> None:
|
|
13
|
+
"""Delete an annotation by its ID.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
session: Database session for executing the operation.
|
|
17
|
+
annotation_id: ID of the annotation to delete.
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
ValueError: If the annotation with the given ID is not found.
|
|
21
|
+
"""
|
|
22
|
+
annotation_resolver.delete_annotation(session=session, annotation_id=annotation_id)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import TypeVar, Union
|
|
5
|
+
from uuid import UUID
|
|
5
6
|
|
|
6
7
|
from sqlmodel.sql.expression import SelectOfScalar
|
|
7
8
|
|
|
@@ -14,6 +15,7 @@ QueryType = TypeVar(
|
|
|
14
15
|
SelectOfScalar[AnnotationBaseTable],
|
|
15
16
|
SelectOfScalar[SampleTable],
|
|
16
17
|
SelectOfScalar[int],
|
|
18
|
+
SelectOfScalar[UUID],
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
PathLike = Union[str, Path]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lightly-studio
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: LightlyStudio is a lightweight, fast, and easy-to-use data exploration tool for data scientists and engineers.
|
|
5
5
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
6
6
|
Classifier: Operating System :: Microsoft :: Windows
|
|
@@ -10,7 +10,8 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.9
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
-
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Python: <3.13,>=3.8
|
|
14
15
|
Requires-Dist: annotated-types==0.7.0
|
|
15
16
|
Requires-Dist: duckdb-engine<0.17,>=0.15.0
|
|
16
17
|
Requires-Dist: duckdb<1.3,>=1.2.2
|
|
@@ -20,16 +21,23 @@ Requires-Dist: fastapi>=0.115.5
|
|
|
20
21
|
Requires-Dist: faster-coco-eval>=1.6.5
|
|
21
22
|
Requires-Dist: fsspec>=2023.1.0
|
|
22
23
|
Requires-Dist: labelformat>=0.1.7
|
|
23
|
-
Requires-Dist: lightly-mundig==0.1.
|
|
24
|
+
Requires-Dist: lightly-mundig==0.1.4
|
|
24
25
|
Requires-Dist: open-clip-torch>=2.20.0
|
|
26
|
+
Requires-Dist: pyarrow>=17.0.0
|
|
25
27
|
Requires-Dist: python-multipart>=0.0.20
|
|
26
28
|
Requires-Dist: scikit-learn==1.3.2
|
|
27
29
|
Requires-Dist: sqlmodel>=0.0.22
|
|
28
|
-
Requires-Dist: torchmetrics>=1.5.2
|
|
29
30
|
Requires-Dist: tqdm>=4.65.0
|
|
30
31
|
Requires-Dist: typing-extensions>=4.12.2
|
|
31
32
|
Requires-Dist: uvicorn>=0.32.1
|
|
32
33
|
Requires-Dist: xxhash>=3.5.0
|
|
34
|
+
Provides-Extra: cloud-storage
|
|
35
|
+
Requires-Dist: adlfs>=2023.1.0; extra == 'cloud-storage'
|
|
36
|
+
Requires-Dist: gcsfs>=2023.1.0; extra == 'cloud-storage'
|
|
37
|
+
Requires-Dist: s3fs>=2023.1.0; extra == 'cloud-storage'
|
|
38
|
+
Provides-Extra: lightly-edge
|
|
39
|
+
Requires-Dist: lightly-edge-sdk>=1.0.1b2; extra == 'lightly-edge'
|
|
40
|
+
Requires-Dist: opencv-python; extra == 'lightly-edge'
|
|
33
41
|
Description-Content-Type: text/markdown
|
|
34
42
|
|
|
35
43
|
<div align="center">
|
|
@@ -53,7 +61,7 @@ Description-Content-Type: text/markdown
|
|
|
53
61
|
|
|
54
62
|
We at **[Lightly](https://lightly.ai)** created **LightlyStudio**, an open-source tool
|
|
55
63
|
designed to supercharge your data curation workflows for computer vision datasets. Explore
|
|
56
|
-
your data, visualize annotations and crops, tag samples, and export curated lists to improve
|
|
64
|
+
your data, visualize captions, annotations and crops, tag samples, and export curated lists to improve
|
|
57
65
|
your machine learning pipelines. And much more!
|
|
58
66
|
|
|
59
67
|
LightlyStudio runs entirely locally on your machine, keeping your data private. It consists
|
|
@@ -65,7 +73,7 @@ Using LightlyStudio typically involves these steps:
|
|
|
65
73
|
|
|
66
74
|
1. **Index Your Dataset:** Run a Python script using the `lightly_studio` library to process your local dataset (images and annotations) and save metadata into a local `lightly_studio.db` file.
|
|
67
75
|
2. **Launch the UI:** The script then starts a local web server.
|
|
68
|
-
3. **Explore & Curate:** Use the UI to visualize images, annotations, and object crops. Filter and search your data (experimental text search available). Apply tags to interesting samples (e.g., "mislabeled", "review").
|
|
76
|
+
3. **Explore & Curate:** Use the UI to visualize images, annotations, captions, and object crops. Filter and search your data (experimental text search available). Apply tags to interesting samples (e.g., "mislabeled", "review").
|
|
69
77
|
4. **Export Curated Data:** Export information (like filenames) for your tagged samples from the UI to use downstream.
|
|
70
78
|
5. **Stop the Server:** Close the terminal running the script (Ctrl+C) when done.
|
|
71
79
|
|
|
@@ -104,7 +112,7 @@ The library is OS-independent and works on Windows, Linux, and macOS.
|
|
|
104
112
|
|
|
105
113
|
```shell
|
|
106
114
|
# 1. Create and activate a virtual environment (Recommended)
|
|
107
|
-
# On Linux/
|
|
115
|
+
# On Linux/MacOS:
|
|
108
116
|
python3 -m venv venv
|
|
109
117
|
source venv/bin/activate
|
|
110
118
|
|
|
@@ -113,41 +121,44 @@ python -m venv venv
|
|
|
113
121
|
.\venv\Scripts\activate
|
|
114
122
|
|
|
115
123
|
# 2. Install LightlyStudio
|
|
116
|
-
pip install
|
|
124
|
+
pip install lightly-studio
|
|
117
125
|
```
|
|
118
126
|
|
|
119
127
|
## **Quickstart**
|
|
120
128
|
|
|
121
|
-
Download
|
|
122
|
-
|
|
123
|
-
### YOLO Object Detection
|
|
124
|
-
|
|
125
|
-
To run an example using a yolo dataset, clone the example repository and run the example script from below:
|
|
129
|
+
Download example datasets by cloning the example repository:
|
|
126
130
|
|
|
127
131
|
```shell
|
|
128
132
|
git clone https://github.com/lightly-ai/dataset_examples dataset_examples
|
|
129
133
|
```
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
### YOLO Object Detection
|
|
136
|
+
|
|
137
|
+
To run an example using a YOLO dataset, create a file named `example_yolo.py` with the
|
|
138
|
+
following contents in the same directory that contains the `dataset_examples/` folder:
|
|
132
139
|
|
|
133
140
|
```python
|
|
134
|
-
|
|
141
|
+
# example_yolo.py
|
|
135
142
|
|
|
136
143
|
import lightly_studio as ls
|
|
137
144
|
|
|
138
|
-
data_yaml_path = Path(__file__).resolve().parent / "data.yaml"
|
|
139
|
-
|
|
140
145
|
# Create a dataset and add the samples from the yolo format
|
|
141
146
|
dataset = ls.Dataset.create()
|
|
142
147
|
dataset.add_samples_from_yolo(
|
|
143
|
-
data_yaml=
|
|
144
|
-
input_split="test",
|
|
148
|
+
data_yaml="dataset_examples/road_signs_yolo/data.yaml",
|
|
145
149
|
)
|
|
146
150
|
|
|
147
151
|
# Start the UI application on the port 8001.
|
|
148
152
|
ls.start_gui()
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Run the script:
|
|
149
156
|
|
|
150
157
|
```
|
|
158
|
+
python example_yolo.py
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
When you are done, stop the app by pressing Ctrl+C in the terminal.
|
|
151
162
|
|
|
152
163
|
<details>
|
|
153
164
|
<summary>The YOLO format details:</summary>
|
|
@@ -183,26 +194,20 @@ Where coordinates are normalized between 0 and 1.
|
|
|
183
194
|
|
|
184
195
|
### COCO Instance Segmentation
|
|
185
196
|
|
|
186
|
-
To run an instance segmentation example using a COCO dataset,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
git clone https://github.com/lightly-ai/dataset_examples dataset_examples
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
**`example_coco.py` script to explore the dataset:**
|
|
197
|
+
To run an instance segmentation example using a COCO dataset, create a file named
|
|
198
|
+
`example_coco.py` with the following contents in the same directory that contains
|
|
199
|
+
the `dataset_examples/` folder:
|
|
193
200
|
|
|
194
201
|
```python
|
|
195
|
-
|
|
202
|
+
# example_coco.py
|
|
196
203
|
|
|
197
204
|
import lightly_studio as ls
|
|
198
205
|
|
|
199
|
-
current_dir = Path(__file__).resolve().parent
|
|
200
|
-
|
|
201
206
|
# Create a dataset and add the samples from the coco format
|
|
202
207
|
dataset = ls.Dataset.create()
|
|
203
208
|
dataset.add_samples_from_coco(
|
|
204
|
-
annotations_json=
|
|
205
|
-
images_path=
|
|
209
|
+
annotations_json="dataset_examples/coco_subset_128_images/instances_train2017.json",
|
|
210
|
+
images_path="dataset_examples/coco_subset_128_images/images",
|
|
206
211
|
annotation_type=ls.AnnotationType.INSTANCE_SEGMENTATION,
|
|
207
212
|
)
|
|
208
213
|
|
|
@@ -210,6 +215,14 @@ dataset.add_samples_from_coco(
|
|
|
210
215
|
ls.start_gui()
|
|
211
216
|
```
|
|
212
217
|
|
|
218
|
+
Run the script:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
python example_coco.py
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
When you are done, stop the app by pressing Ctrl+C in the terminal.
|
|
225
|
+
|
|
213
226
|
<details>
|
|
214
227
|
<summary>The COCO format details:</summary>
|
|
215
228
|
|
|
@@ -230,6 +243,56 @@ COCO uses a single JSON file containing all annotations. The format consists of
|
|
|
230
243
|
|
|
231
244
|
</details>
|
|
232
245
|
|
|
246
|
+
### COCO Captions
|
|
247
|
+
|
|
248
|
+
To run a caption example using a COCO dataset, create a file named
|
|
249
|
+
`example_coco_captions.py` with the following contents in the same directory that contains
|
|
250
|
+
the `dataset_examples/` folder:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
# example_coco_captions.py
|
|
254
|
+
|
|
255
|
+
import lightly_studio as ls
|
|
256
|
+
|
|
257
|
+
# Create a dataset and add the samples from the coco format
|
|
258
|
+
dataset = ls.Dataset.create()
|
|
259
|
+
dataset.add_samples_from_coco_caption(
|
|
260
|
+
annotations_json="dataset_examples/coco_subset_128_images/captions_train2017.json",
|
|
261
|
+
images_path="dataset_examples/coco_subset_128_images/images",
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Start the UI application on the port 8001.
|
|
265
|
+
ls.start_gui()
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Run the script:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
python example_coco_captions.py
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Now you can inspect samples with their assigned captions in the app. When you are done,
|
|
275
|
+
stop the app by pressing Ctrl+C in the terminal.
|
|
276
|
+
|
|
277
|
+
<details>
|
|
278
|
+
<summary>The COCO format details:</summary>
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
coco_subset_128_images/
|
|
282
|
+
├── images/
|
|
283
|
+
│ ├── image1.jpg
|
|
284
|
+
│ ├── image2.jpg
|
|
285
|
+
│ └── ...
|
|
286
|
+
└── captions_train2017.json # Single JSON file containing all captions
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
COCO uses a single JSON file containing all captions. The format consists of three main components:
|
|
290
|
+
|
|
291
|
+
- Images: Defines metadata for each image in the dataset.
|
|
292
|
+
- Annotations: Defines the captions.
|
|
293
|
+
|
|
294
|
+
</details>
|
|
295
|
+
|
|
233
296
|
## 🔍 How It Works
|
|
234
297
|
|
|
235
298
|
1. Your **Python script** uses the `lightly_studio` **Dataset**.
|
|
@@ -253,6 +316,53 @@ dataset.add_samples_from_path(path="/path/to/image_dataset")
|
|
|
253
316
|
ls.start_gui()
|
|
254
317
|
```
|
|
255
318
|
|
|
319
|
+
#### ☁️ Cloud Storage Support
|
|
320
|
+
|
|
321
|
+
#### Installation with Cloud Storage Support
|
|
322
|
+
|
|
323
|
+
```shell
|
|
324
|
+
pip install lightly-studio[cloud-storage]
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### Example: Loading Dataset from Cloud Storage
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
import lightly_studio as ls
|
|
331
|
+
|
|
332
|
+
dataset = ls.Dataset.create()
|
|
333
|
+
|
|
334
|
+
# Load dataset from S3
|
|
335
|
+
dataset.add_samples_from_path(path="s3://my-bucket/path/to/images/")
|
|
336
|
+
|
|
337
|
+
# You can use glob pattern in the file path
|
|
338
|
+
dataset.add_samples_from_path(path="s3://my-bucket/path/to/images/**/*.jpg") # matches all .jpg files recursively
|
|
339
|
+
|
|
340
|
+
# Load dataset from gcs
|
|
341
|
+
dataset.add_samples_from_path(path="gs://path/to/images/")
|
|
342
|
+
|
|
343
|
+
ls.start_gui()
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Note**: Currently, cloud storage support is limited to loading images only. Annotation files (YOLO labels, COCO JSON files, etc.) cannot be loaded directly from cloud storage paths.
|
|
347
|
+
|
|
348
|
+
#### Authentication
|
|
349
|
+
|
|
350
|
+
**Important**: Cloud storage authentication must be configured before running LightlyStudio. The application relies on your existing cloud storage credentials and will not prompt for authentication.
|
|
351
|
+
|
|
352
|
+
#### AWS S3
|
|
353
|
+
|
|
354
|
+
You can use either of the following two options:
|
|
355
|
+
|
|
356
|
+
- **Set environment variables manually**: Set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` (LightlyStudio uses `s3fs` under the hood to connect to S3)
|
|
357
|
+
- **Authenticate using AWS CLI**: Run `aws configure` (this will automatically set the environment variables that LightlyStudio can access)
|
|
358
|
+
|
|
359
|
+
#### Google Cloud Storage
|
|
360
|
+
|
|
361
|
+
You can use either of the following two options:
|
|
362
|
+
|
|
363
|
+
- **Set environment variable manually**: Set `GOOGLE_APPLICATION_CREDENTIALS` pointing to your service account key file (LightlyStudio uses `gcsfs` under the hood to connect to GCS)
|
|
364
|
+
- **Authenticate using gcloud CLI**: Run `gcloud auth application-default login` (this will automatically set the environment variables that LightlyStudio can access)
|
|
365
|
+
|
|
256
366
|
#### Load Images With Annotations
|
|
257
367
|
|
|
258
368
|
The `Dataset` currently supports:
|
|
@@ -268,7 +378,6 @@ import lightly_studio as ls
|
|
|
268
378
|
dataset = ls.Dataset.create()
|
|
269
379
|
dataset.add_samples_from_yolo(
|
|
270
380
|
data_yaml="my_yolo_dataset/data.yaml",
|
|
271
|
-
input_split="val",
|
|
272
381
|
)
|
|
273
382
|
|
|
274
383
|
ls.start_gui()
|
|
@@ -564,6 +673,16 @@ In some use cases, one might want to assign a tag to the samples that are the re
|
|
|
564
673
|
query.add_tag("tag_name")
|
|
565
674
|
```
|
|
566
675
|
|
|
676
|
+
#### Export Samples
|
|
677
|
+
|
|
678
|
+
Currently, exporting to the COCO object detection format is supported and only annotations
|
|
679
|
+
of type object detection are exported. The following example exports the samples in the query
|
|
680
|
+
to a COCO JSON file named `coco_export.json`:
|
|
681
|
+
|
|
682
|
+
```py
|
|
683
|
+
query.export().to_coco_object_detections()
|
|
684
|
+
```
|
|
685
|
+
|
|
567
686
|
### Examples
|
|
568
687
|
|
|
569
688
|
#### Add Custom Metadata
|
|
@@ -625,7 +744,11 @@ samples.
|
|
|
625
744
|
Set the `LIGHTLY_STUDIO_LICENSE_KEY` environment variable before using selection features:
|
|
626
745
|
|
|
627
746
|
```bash
|
|
747
|
+
# On Linux/MacOS
|
|
628
748
|
export LIGHTLY_STUDIO_LICENSE_KEY="license_key_here"
|
|
749
|
+
|
|
750
|
+
# On Windows (PowerShell)
|
|
751
|
+
$env:LIGHTLY_STUDIO_LICENSE_KEY="license_key_here"
|
|
629
752
|
```
|
|
630
753
|
|
|
631
754
|
Alternatively, set it inside your Python script:
|
|
@@ -635,7 +758,15 @@ import os
|
|
|
635
758
|
os.environ["LIGHTLY_STUDIO_LICENSE_KEY"] = "license_key_here"
|
|
636
759
|
```
|
|
637
760
|
|
|
638
|
-
|
|
761
|
+
Or in a `.env` file:
|
|
762
|
+
|
|
763
|
+
```
|
|
764
|
+
LIGHTLY_STUDIO_LICENSE_KEY="license_key_here"
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
#### Diversity Selection
|
|
768
|
+
|
|
769
|
+
Diversity selection can be configured directly from a `DatasetQuery`. The example below showcases a simple case of selecting diverse samples.
|
|
639
770
|
|
|
640
771
|
```py
|
|
641
772
|
import lightly_studio as ls
|
|
@@ -653,6 +784,57 @@ dataset.query().selection().diverse(
|
|
|
653
784
|
ls.start_gui()
|
|
654
785
|
```
|
|
655
786
|
|
|
787
|
+
#### Metadata Weighting Selection
|
|
788
|
+
|
|
789
|
+
You can select samples based on the values of a metadata field. The example below showcases a simple case of selecting samples with the highest metadata value.
|
|
790
|
+
|
|
791
|
+
```py
|
|
792
|
+
import lightly_studio as ls
|
|
793
|
+
|
|
794
|
+
# Load your dataset
|
|
795
|
+
dataset = ls.Dataset.load_or_create()
|
|
796
|
+
dataset.add_samples_from_path(path="/path/to/image_dataset")
|
|
797
|
+
# Compute and store 'typicality' metadata.
|
|
798
|
+
dataset.compute_typicality_metadata(metadata_name="typicality")
|
|
799
|
+
|
|
800
|
+
# Select the 5 samples with the highest 'typicality' scores.
|
|
801
|
+
dataset.query().selection().metadata_weighting(
|
|
802
|
+
n_samples_to_select=5,
|
|
803
|
+
selection_result_tag_name="metadata_weighting_selection",
|
|
804
|
+
metadata_key="typicality",
|
|
805
|
+
)
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
#### Selection Based on Multiple Strategies
|
|
809
|
+
|
|
810
|
+
You can configure multiple strategies, the selection takes into account all of them at the same time, weighted by the `strength` parameter.
|
|
811
|
+
|
|
812
|
+
```py
|
|
813
|
+
import lightly_studio as ls
|
|
814
|
+
from lightly_studio.selection.selection_config import (
|
|
815
|
+
MetadataWeightingStrategy,
|
|
816
|
+
EmbeddingDiversityStrategy,
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
# Load your dataset
|
|
820
|
+
dataset = ls.Dataset.load_or_create()
|
|
821
|
+
dataset.add_samples_from_path(path="/path/to/image_dataset")
|
|
822
|
+
# Compute typicality and store it as `typicality` metadata
|
|
823
|
+
dataset.compute_typicality_metadata(metadata_name="typicality")
|
|
824
|
+
|
|
825
|
+
# Select 10 samples by combining typicality and diversity, diversity having double the strength.
|
|
826
|
+
dataset.query().selection().multi_strategies(
|
|
827
|
+
n_samples_to_select=10,
|
|
828
|
+
selection_result_tag_name="multi_strategy_selection",
|
|
829
|
+
selection_strategies=[
|
|
830
|
+
MetadataWeightingStrategy(metadata_key="typicality", strength=1.0),
|
|
831
|
+
EmbeddingDiversityStrategy(embedding_model_name="my_model_name", strength=2.0),
|
|
832
|
+
],
|
|
833
|
+
)
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
#### Exporting Selected Samples
|
|
837
|
+
|
|
656
838
|
The selected sample paths can be exported via the GUI, or by a script:
|
|
657
839
|
|
|
658
840
|
```py
|
|
@@ -671,19 +853,27 @@ with open("export.txt", "w") as f:
|
|
|
671
853
|
|
|
672
854
|
## 📚 **FAQ**
|
|
673
855
|
|
|
674
|
-
###
|
|
856
|
+
### Does LightlyStudio persist the datasets?
|
|
675
857
|
|
|
676
|
-
Yes, the information about datasets is
|
|
677
|
-
|
|
858
|
+
Yes, the information about datasets is persisted in a database file. You can see inspect
|
|
859
|
+
it after the dataset is processed. Use `Dataset.load()` to load a dataset from a pre-existing
|
|
860
|
+
database.
|
|
678
861
|
|
|
679
862
|
### Can I change the database path?
|
|
680
863
|
|
|
681
|
-
|
|
864
|
+
Yes, the database can be selected as follows:
|
|
865
|
+
```py
|
|
866
|
+
import lightly_studio as ls
|
|
867
|
+
|
|
868
|
+
ls.db_manager.connect(db_file="custom.db")
|
|
869
|
+
```
|
|
682
870
|
|
|
683
|
-
### Can I
|
|
871
|
+
### Can I use LightlyStudio from two scripts in parallel?
|
|
684
872
|
|
|
685
|
-
|
|
873
|
+
Only one script can be run at one time as the app uses a database lock for data integrity.
|
|
686
874
|
|
|
687
|
-
### Can I change the API backend port?
|
|
875
|
+
### Can I change the API backend host and port?
|
|
688
876
|
|
|
689
|
-
Yes
|
|
877
|
+
Yes, by setting environment variables. For the host set the LIGHTLY_STUDIO_HOST variable,
|
|
878
|
+
to change the port set the LIGHTLY_STUDIO_PORT variable. Note that if the port is unavailable
|
|
879
|
+
at runtime the app uses a random port number.
|