active-vision 0.4.2__py3-none-any.whl → 0.4.3__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.
- active_vision/__init__.py +1 -1
- active_vision/core.py +55 -11
- active_vision/utils.py +35 -1
- {active_vision-0.4.2.dist-info → active_vision-0.4.3.dist-info}/METADATA +2 -2
- active_vision-0.4.3.dist-info/RECORD +7 -0
- active_vision-0.4.2.dist-info/RECORD +0 -7
- {active_vision-0.4.2.dist-info → active_vision-0.4.3.dist-info}/WHEEL +0 -0
- {active_vision-0.4.2.dist-info → active_vision-0.4.3.dist-info}/licenses/LICENSE +0 -0
active_vision/__init__.py
CHANGED
active_vision/core.py
CHANGED
@@ -308,6 +308,7 @@ class ActiveLearner:
|
|
308
308
|
"label": self.eval_set[label_col].tolist(),
|
309
309
|
"pred_label": [self.learn.dls.vocab[i] for i in cls_preds.numpy()],
|
310
310
|
"pred_conf": torch.max(F.softmax(probs, dim=1), dim=1)[0].numpy(),
|
311
|
+
"probs": probs.numpy().tolist(),
|
311
312
|
"loss": loss.numpy().tolist(),
|
312
313
|
}
|
313
314
|
)
|
@@ -324,9 +325,17 @@ class ActiveLearner:
|
|
324
325
|
get_base64_image
|
325
326
|
)
|
326
327
|
interactive_eval_df = interactive_eval_df[
|
327
|
-
[
|
328
|
+
[
|
329
|
+
"image",
|
330
|
+
"filepath",
|
331
|
+
"label",
|
332
|
+
"pred_label",
|
333
|
+
"pred_conf",
|
334
|
+
"loss",
|
335
|
+
"probs",
|
336
|
+
]
|
328
337
|
]
|
329
|
-
|
338
|
+
|
330
339
|
show(
|
331
340
|
interactive_eval_df,
|
332
341
|
columnDefs=[{"width": "200px", "targets": "_all"}],
|
@@ -337,7 +346,11 @@ class ActiveLearner:
|
|
337
346
|
return eval_df
|
338
347
|
|
339
348
|
def sample_uncertain(
|
340
|
-
self,
|
349
|
+
self,
|
350
|
+
df: pd.DataFrame,
|
351
|
+
num_samples: int,
|
352
|
+
strategy: str = "least-confidence",
|
353
|
+
interactive: bool = False,
|
341
354
|
):
|
342
355
|
"""
|
343
356
|
Sample top `num_samples` low confidence samples. Returns a df with filepaths and predicted labels, and confidence scores.
|
@@ -442,7 +455,11 @@ class ActiveLearner:
|
|
442
455
|
return result_df
|
443
456
|
|
444
457
|
def sample_diverse(
|
445
|
-
self,
|
458
|
+
self,
|
459
|
+
df: pd.DataFrame,
|
460
|
+
num_samples: int,
|
461
|
+
strategy: str = "model-based-outlier",
|
462
|
+
interactive: bool = False,
|
446
463
|
):
|
447
464
|
"""
|
448
465
|
Sample top `num_samples` diverse samples. Returns a df with filepaths and predicted labels, and confidence scores.
|
@@ -526,9 +543,18 @@ class ActiveLearner:
|
|
526
543
|
if interactive:
|
527
544
|
logger.info("Rendering interactive table")
|
528
545
|
interactive_df = result_df.copy()
|
529
|
-
interactive_df["image"] = interactive_df["filepath"].apply(
|
546
|
+
interactive_df["image"] = interactive_df["filepath"].apply(
|
547
|
+
get_base64_image
|
548
|
+
)
|
530
549
|
interactive_df = interactive_df[
|
531
|
-
[
|
550
|
+
[
|
551
|
+
"image",
|
552
|
+
"filepath",
|
553
|
+
"strategy",
|
554
|
+
"score",
|
555
|
+
"pred_label",
|
556
|
+
"pred_conf",
|
557
|
+
]
|
532
558
|
]
|
533
559
|
|
534
560
|
show(
|
@@ -544,7 +570,13 @@ class ActiveLearner:
|
|
544
570
|
logger.error(f"Unknown strategy: {strategy}")
|
545
571
|
raise ValueError(f"Unknown strategy: {strategy}")
|
546
572
|
|
547
|
-
def sample_random(
|
573
|
+
def sample_random(
|
574
|
+
self,
|
575
|
+
df: pd.DataFrame,
|
576
|
+
num_samples: int,
|
577
|
+
seed: int = None,
|
578
|
+
interactive: bool = False,
|
579
|
+
):
|
548
580
|
"""
|
549
581
|
Sample `num_samples` random samples. Returns a df with filepaths and predicted labels, and confidence scores.
|
550
582
|
|
@@ -580,7 +612,13 @@ class ActiveLearner:
|
|
580
612
|
|
581
613
|
return result_df
|
582
614
|
|
583
|
-
def sample_combination(
|
615
|
+
def sample_combination(
|
616
|
+
self,
|
617
|
+
df: pd.DataFrame,
|
618
|
+
num_samples: int,
|
619
|
+
combination: dict,
|
620
|
+
interactive: bool = False,
|
621
|
+
):
|
584
622
|
"""
|
585
623
|
Sample samples based on a combination of strategies.
|
586
624
|
|
@@ -614,7 +652,9 @@ class ActiveLearner:
|
|
614
652
|
|
615
653
|
# Validate total proportions sum to 1
|
616
654
|
if not np.isclose(sum(combination.values()), 1.0):
|
617
|
-
raise ValueError(
|
655
|
+
raise ValueError(
|
656
|
+
f"Proportions must sum to 1, got {sum(combination.values())}"
|
657
|
+
)
|
618
658
|
|
619
659
|
# Calculate samples per strategy and handle rounding
|
620
660
|
samples_per_strategy = {
|
@@ -648,7 +688,9 @@ class ActiveLearner:
|
|
648
688
|
df=df, num_samples=n_samples, strategy=strategy, interactive=False
|
649
689
|
)
|
650
690
|
elif strategy == "random":
|
651
|
-
strategy_df = self.sample_random(
|
691
|
+
strategy_df = self.sample_random(
|
692
|
+
df=df, num_samples=n_samples, interactive=False
|
693
|
+
)
|
652
694
|
else:
|
653
695
|
raise ValueError(f"Unknown strategy: {strategy}")
|
654
696
|
|
@@ -852,7 +894,9 @@ class ActiveLearner:
|
|
852
894
|
)
|
853
895
|
|
854
896
|
# Add element_id to finish button
|
855
|
-
finish_btn = gr.Button(
|
897
|
+
finish_btn = gr.Button(
|
898
|
+
"Finish Labeling", variant="primary", elem_id="finish_btn"
|
899
|
+
)
|
856
900
|
|
857
901
|
# Add event handler for slider changes
|
858
902
|
progress.change(
|
active_vision/utils.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import base64
|
2
|
+
import os
|
2
3
|
from io import BytesIO
|
3
4
|
|
5
|
+
from itables import show
|
4
6
|
from loguru import logger
|
5
7
|
from PIL import Image
|
6
8
|
|
@@ -11,7 +13,7 @@ def get_base64_image(filepath, width=200):
|
|
11
13
|
# Convert to RGB if needed
|
12
14
|
if img.mode != "RGB":
|
13
15
|
img = img.convert("RGB")
|
14
|
-
|
16
|
+
|
15
17
|
aspect_ratio = img.height / img.width
|
16
18
|
height = int(width * aspect_ratio)
|
17
19
|
img = img.resize((width, height), Image.Resampling.LANCZOS)
|
@@ -22,3 +24,35 @@ def get_base64_image(filepath, width=200):
|
|
22
24
|
except Exception as e:
|
23
25
|
logger.warning(f"Failed to encode image {filepath}: {e}")
|
24
26
|
return None
|
27
|
+
|
28
|
+
|
29
|
+
def show_interactive_table(df, filepath_col="filepath", image_col="image"):
|
30
|
+
"""
|
31
|
+
Display an interactive table with images from filepaths.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
df: pandas DataFrame that contains a 'filepath' column
|
35
|
+
"""
|
36
|
+
# Create a copy to avoid modifying the original dataframe
|
37
|
+
interactive_df = df.copy()
|
38
|
+
|
39
|
+
# Add image column by applying get_base64_image to filepath column
|
40
|
+
interactive_df[image_col] = interactive_df[filepath_col].apply(get_base64_image)
|
41
|
+
|
42
|
+
# Convert filepath to clickable link with relative path
|
43
|
+
interactive_df[filepath_col] = interactive_df[filepath_col].apply(
|
44
|
+
lambda x: f'<a href="{x.replace(os.sep, "/")}">{x}</a>'
|
45
|
+
)
|
46
|
+
|
47
|
+
# Reorder columns to show image first
|
48
|
+
cols = interactive_df.columns.tolist()
|
49
|
+
cols.remove(image_col)
|
50
|
+
interactive_df = interactive_df[[image_col] + cols]
|
51
|
+
|
52
|
+
# Display interactive table
|
53
|
+
show(
|
54
|
+
interactive_df,
|
55
|
+
columnDefs=[{"width": "200px", "targets": "_all"}],
|
56
|
+
style="width:1200px",
|
57
|
+
autoWidth=False,
|
58
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: active-vision
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.3
|
4
4
|
Summary: Active learning for computer vision.
|
5
5
|
Project-URL: Homepage, https://github.com/dnth/active-vision
|
6
6
|
Project-URL: Bug Tracker, https://github.com/dnth/active-vision/issues
|
@@ -156,7 +156,7 @@ al = ActiveLearner(name="cycle-1")
|
|
156
156
|
al.load_model(model="resnet18", pretrained=True)
|
157
157
|
|
158
158
|
# Load dataset
|
159
|
-
al.load_dataset(train_df, filepath_col="filepath", label_col="label"
|
159
|
+
al.load_dataset(train_df, filepath_col="filepath", label_col="label")
|
160
160
|
|
161
161
|
# Train model
|
162
162
|
al.train(epochs=10, lr=5e-3)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
active_vision/__init__.py,sha256=ztL09ANIuHmKmue2Uaui475201zOvb4sEYHNspIzDEA,43
|
2
|
+
active_vision/core.py,sha256=9Qwmrere_ryQKqFKLm0aRp-3drz2yBzHfm6jumjWAto,47765
|
3
|
+
active_vision/utils.py,sha256=L2nIUSohqCABqV8qjKNTHmxQoiom2DXMjce5aw2_Tjc,1902
|
4
|
+
active_vision-0.4.3.dist-info/METADATA,sha256=JLNqzChj2bhefMu9a4HSrimzImsYm1ePuJhJbTNUWe8,19798
|
5
|
+
active_vision-0.4.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
+
active_vision-0.4.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
7
|
+
active_vision-0.4.3.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
active_vision/__init__.py,sha256=WHlXpfYbX7Qp1P6kfuEm60U1xl8_A6fQPVJDSLjojYo,43
|
2
|
-
active_vision/core.py,sha256=51fskr1E2QLwgxuKzv75yxqH73ktIxEPovxqN7LWibM,47081
|
3
|
-
active_vision/utils.py,sha256=IV8RbxCX2Owk0-fF0-LK53YJr8erHQjYb6gSrj9oACo,841
|
4
|
-
active_vision-0.4.2.dist-info/METADATA,sha256=v_fUTAj-2vn33eQJH3aafPAMw3KINJe-u9XK-2Nojyk,19812
|
5
|
-
active_vision-0.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
-
active_vision-0.4.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
7
|
-
active_vision-0.4.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|