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 CHANGED
@@ -1,3 +1,3 @@
1
- __version__ = "0.4.2"
1
+ __version__ = "0.4.3"
2
2
 
3
3
  from .core import *
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
- ["image", "filepath", "label", "pred_label", "pred_conf", "loss"]
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, df: pd.DataFrame, num_samples: int, strategy: str = "least-confidence", interactive: bool = False
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, df: pd.DataFrame, num_samples: int, strategy: str = "model-based-outlier", interactive: bool = False
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(get_base64_image)
546
+ interactive_df["image"] = interactive_df["filepath"].apply(
547
+ get_base64_image
548
+ )
530
549
  interactive_df = interactive_df[
531
- ["image", "filepath", "strategy", "score", "pred_label", "pred_conf"]
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(self, df: pd.DataFrame, num_samples: int, seed: int = None, interactive: bool = False):
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(self, df: pd.DataFrame, num_samples: int, combination: dict, interactive: bool = False):
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(f"Proportions must sum to 1, got {sum(combination.values())}")
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(df=df, num_samples=n_samples, interactive=False)
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("Finish Labeling", variant="primary", elem_id="finish_btn")
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.2
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", batch_size=8)
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,,