deepvisiontools 0.1.0__tar.gz → 0.2.0__tar.gz

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.
Files changed (67) hide show
  1. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/PKG-INFO +8 -7
  2. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/README.md +4 -3
  3. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/pyproject.toml +3 -2
  4. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/__init__.py +1 -1
  5. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/config/config.py +3 -0
  6. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/inference/predictor.py +7 -1
  7. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/metrics/base_metric.py +102 -67
  8. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/__init__.py +6 -4
  9. deepvisiontools-0.2.0/src/deepvisiontools/models/timmyolo/__init__.py +4 -0
  10. deepvisiontools-0.2.0/src/deepvisiontools/models/timmyolo/errors.py +5 -0
  11. deepvisiontools-0.2.0/src/deepvisiontools/models/timmyolo/timmyolo.py +392 -0
  12. deepvisiontools-0.2.0/src/deepvisiontools/models/timmyolo/utils.py +230 -0
  13. {deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8 → deepvisiontools-0.2.0/src/deepvisiontools/models/yolo}/__init__.py +3 -3
  14. {deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8 → deepvisiontools-0.2.0/src/deepvisiontools/models/yolo}/errors.py +1 -1
  15. deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8/yolov8.py → deepvisiontools-0.2.0/src/deepvisiontools/models/yolo/yolo.py +19 -7
  16. deepvisiontools-0.2.0/src/deepvisiontools/models/yoloseg/__init__.py +4 -0
  17. {deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8seg → deepvisiontools-0.2.0/src/deepvisiontools/models/yoloseg}/utils.py +1 -1
  18. deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8seg/yolov8seg.py → deepvisiontools-0.2.0/src/deepvisiontools/models/yoloseg/yoloseg.py +32 -11
  19. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/train/trainer.py +32 -12
  20. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools.egg-info/PKG-INFO +8 -7
  21. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools.egg-info/SOURCES.txt +12 -8
  22. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools.egg-info/requires.txt +1 -1
  23. deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8seg/__init__.py +0 -4
  24. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/LICENSE.txt +0 -0
  25. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/setup.cfg +0 -0
  26. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/setup.py +0 -0
  27. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/config/__init__.py +0 -0
  28. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/config/errors.py +0 -0
  29. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/__init__.py +0 -0
  30. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/additional_augmentations.py +0 -0
  31. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/augmentation_class.py +0 -0
  32. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/batch_augmentations.py +0 -0
  33. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/data_reader/__init__.py +0 -0
  34. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/data_reader/readers.py +0 -0
  35. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/dataset.py +0 -0
  36. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/data/errors.py +0 -0
  37. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/formats/__init__.py +0 -0
  38. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/formats/base_data.py +0 -0
  39. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/formats/base_formats.py +0 -0
  40. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/formats/errors.py +0 -0
  41. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/formats/formats.py +0 -0
  42. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/formats/utils.py +0 -0
  43. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/inference/__init__.py +0 -0
  44. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/inference/evaluator.py +0 -0
  45. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/inference/patchifier.py +0 -0
  46. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/metrics/__init__.py +0 -0
  47. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/metrics/available_metrics.py +0 -0
  48. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/metrics/func.py +0 -0
  49. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/metrics/matcher.py +0 -0
  50. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/metrics/utils.py +0 -0
  51. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/basemodel.py +0 -0
  52. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/mask2former/__init__.py +0 -0
  53. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/mask2former/mask2former.py +0 -0
  54. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/smp/__init__.py +0 -0
  55. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/smp/errors.py +0 -0
  56. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/models/smp/smp.py +0 -0
  57. {deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8 → deepvisiontools-0.2.0/src/deepvisiontools/models/yolo}/utils.py +0 -0
  58. {deepvisiontools-0.1.0/src/deepvisiontools/models/yolov8seg → deepvisiontools-0.2.0/src/deepvisiontools/models/yoloseg}/errors.py +0 -0
  59. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/preprocessing/__init__.py +0 -0
  60. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/preprocessing/image.py +0 -0
  61. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/preprocessing/preprocessing.py +0 -0
  62. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/train/__init__.py +0 -0
  63. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/utils/__init__.py +0 -0
  64. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/utils/errors.py +0 -0
  65. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools/utils/visualization.py +0 -0
  66. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools.egg-info/dependency_links.txt +0 -0
  67. {deepvisiontools-0.1.0 → deepvisiontools-0.2.0}/src/deepvisiontools.egg-info/top_level.txt +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepvisiontools
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Overlay of PyTorch to generalize trainning and inference processes for detection, instance segmentation and semantic segmentation tasks.
5
5
  Author-email: Lucas Bernigaud Samatan <lucas.bernigaud-samatan@inrae.fr>, Jordan Bernigaud Samatan <jordan.bernigaud-samatan@inrae.fr>, Paul Faucher <paul.faucher@inrae.fr>
6
- Maintainer-email: Jordan Bernigaud Samatan <jordan.bernigaud-samatan@inrae.fr>
6
+ Maintainer-email: Jordan Bernigaud Samatan <jordan.bernigaud-samatan@inrae.fr>, Lucas Bernigaud Samatan <lucas.bernigaud-samatan@inrae.fr>
7
7
  License: GNU AFFERO GENERAL PUBLIC LICENSE
8
8
  Version 3, 19 November 2007
9
9
 
@@ -673,7 +673,7 @@ Project-URL: Repository, https://forgemia.inra.fr/ue-apc/librairies/python/deepv
673
673
  Classifier: Development Status :: 4 - Beta
674
674
  Classifier: Programming Language :: Python :: 3.11
675
675
  Classifier: Programming Language :: Python :: 3.12
676
- Requires-Python: <=3.12.9,>=3.11.9
676
+ Requires-Python: <=3.12.12,>=3.11.9
677
677
  Description-Content-Type: text/markdown
678
678
  License-File: LICENSE.txt
679
679
  Requires-Dist: torch<=2.6.0,>=2.4.0
@@ -684,7 +684,7 @@ Requires-Dist: tensorboard<=2.19.0,>=2.18.0
684
684
  Requires-Dist: ultralytics<=8.3.95,>=8.3.28
685
685
  Requires-Dist: transformers<=4.50.0,>=4.44.2
686
686
  Requires-Dist: colorcet==3.1.0
687
- Requires-Dist: segmentation-models-pytorch<=0.4.0,>=0.3.4
687
+ Requires-Dist: segmentation-models-pytorch<=0.5.0,>0.4.0
688
688
  Requires-Dist: openpyxl==3.1.5
689
689
  Dynamic: license-file
690
690
 
@@ -707,21 +707,22 @@ deepvisiontools is developped by INRAE (french National Research Institute for A
707
707
 
708
708
  ## Citations
709
709
 
710
- deepvisiontools provide models wrapper that allow you to use differents models with all machinery available. It is the resposability of the user to cite properly the actual model developpers.
710
+ deepvisiontools provides model wrappers that allow you to use differents models with all machinery available. It is the responsability of the user to cite properly the actual model developpers.
711
711
  In particular, if using one of these models : Yolo, SMP please cite the actual models developpers (which are not deepvisiontools). For instance for Yolo, please cite ultralytics (https://www.ultralytics.com/) or for SMP cite https://github.com/qubvel-org/segmentation_models.pytorch
712
712
  Similar stands for other models.
713
+ TimmYolo model is a new model that combines timm encoders with a Yolo detection head. The strategy is based on patchification for the backbone (to avoid loosing resolution in resizing) then merge the features before running a Yolo detection heads. If you use this wrapper please cite both timm library, ultralytics library as well as deepvisiontools as model developper.
713
714
 
714
715
  ## Documentation
715
716
 
716
717
  All documentation about deepvisiontools, including tutorials, can be found at : https://deepvisiontools.readthedocs.io/en/latest/
717
718
 
718
719
  ## Installation
719
- We have tested deepvisiontools for python versions between 3.11.9 and 3.12.9
720
+ We have tested deepvisiontools for python versions between 3.11.9 and 3.12.11, we recommend to use python 3.12.11 to minimize the risk of bugs.
720
721
 
721
722
  ```shell
722
723
  pip install deepvisiontools
723
724
  ```
724
-
725
+ If you wish to use TimmYolo model, you may encounter an error saying that feature_only is not available for a given encoder name. Please upgrade your timm version (1.0.15 should have most of them). You may need to reinstall deepvisiontools as you could create conflicts with segmentation-models-pytorch.
725
726
  ## License
726
727
 
727
728
  GNU Affero General Public License v3 or later (AGPLv3+) (AGPL-3.0).
@@ -17,21 +17,22 @@ deepvisiontools is developped by INRAE (french National Research Institute for A
17
17
 
18
18
  ## Citations
19
19
 
20
- deepvisiontools provide models wrapper that allow you to use differents models with all machinery available. It is the resposability of the user to cite properly the actual model developpers.
20
+ deepvisiontools provides model wrappers that allow you to use differents models with all machinery available. It is the responsability of the user to cite properly the actual model developpers.
21
21
  In particular, if using one of these models : Yolo, SMP please cite the actual models developpers (which are not deepvisiontools). For instance for Yolo, please cite ultralytics (https://www.ultralytics.com/) or for SMP cite https://github.com/qubvel-org/segmentation_models.pytorch
22
22
  Similar stands for other models.
23
+ TimmYolo model is a new model that combines timm encoders with a Yolo detection head. The strategy is based on patchification for the backbone (to avoid loosing resolution in resizing) then merge the features before running a Yolo detection heads. If you use this wrapper please cite both timm library, ultralytics library as well as deepvisiontools as model developper.
23
24
 
24
25
  ## Documentation
25
26
 
26
27
  All documentation about deepvisiontools, including tutorials, can be found at : https://deepvisiontools.readthedocs.io/en/latest/
27
28
 
28
29
  ## Installation
29
- We have tested deepvisiontools for python versions between 3.11.9 and 3.12.9
30
+ We have tested deepvisiontools for python versions between 3.11.9 and 3.12.11, we recommend to use python 3.12.11 to minimize the risk of bugs.
30
31
 
31
32
  ```shell
32
33
  pip install deepvisiontools
33
34
  ```
34
-
35
+ If you wish to use TimmYolo model, you may encounter an error saying that feature_only is not available for a given encoder name. Please upgrade your timm version (1.0.15 should have most of them). You may need to reinstall deepvisiontools as you could create conflicts with segmentation-models-pytorch.
35
36
  ## License
36
37
 
37
38
  GNU Affero General Public License v3 or later (AGPLv3+) (AGPL-3.0).
@@ -11,6 +11,7 @@ authors = [
11
11
  ]
12
12
  maintainers = [
13
13
  { name = "Jordan Bernigaud Samatan", email = "jordan.bernigaud-samatan@inrae.fr" },
14
+ { name = "Lucas Bernigaud Samatan", email = "lucas.bernigaud-samatan@inrae.fr" },
14
15
  ]
15
16
  description = "Overlay of PyTorch to generalize trainning and inference processes for detection, instance segmentation and semantic segmentation tasks."
16
17
  readme = "README.md"
@@ -20,7 +21,7 @@ classifiers = [
20
21
  "Programming Language :: Python :: 3.12"
21
22
  ]
22
23
  dynamic = ["version"]
23
- requires-python = ">=3.11.9,<=3.12.9"
24
+ requires-python = ">=3.11.9,<=3.12.12"
24
25
  dependencies = [
25
26
  "torch>=2.4.0,<=2.6.0",
26
27
  "torchvision>=0.19.0,<=0.21.0",
@@ -30,7 +31,7 @@ dependencies = [
30
31
  "ultralytics>=8.3.28,<=8.3.95",
31
32
  "transformers>=4.44.2,<=4.50.0",
32
33
  "colorcet==3.1.0",
33
- "segmentation-models-pytorch>=0.3.4,<=0.4.0",
34
+ "segmentation-models-pytorch>0.4.0,<=0.5.0",
34
35
  "openpyxl==3.1.5"
35
36
  ]
36
37
 
@@ -5,7 +5,7 @@ from deepvisiontools.utils import visualization
5
5
  from deepvisiontools.inference.predictor import Predictor
6
6
  from deepvisiontools.inference.evaluator import Evaluator
7
7
 
8
- __version__ = "0.1.0"
8
+ __version__ = "0.2.0"
9
9
 
10
10
  __all__ = (
11
11
  Configuration,
@@ -105,6 +105,7 @@ class Configuration(metaclass=_SingletonConfig):
105
105
  patchifier_mode: Literal["bbox", "instance_mask"] = "bbox",
106
106
  seed: Union[False, int] = False,
107
107
  deterministic: bool = False,
108
+ optimize=True,
108
109
  ):
109
110
 
110
111
  # generic
@@ -127,6 +128,8 @@ class Configuration(metaclass=_SingletonConfig):
127
128
  # reproducibility
128
129
  self.seed = seed
129
130
  self.deterministic = deterministic
131
+ # mixed precision (torch.amp + gradiant scaler)
132
+ self.optimize = optimize
130
133
 
131
134
  @property
132
135
  def device(self):
@@ -123,8 +123,14 @@ class Predictor:
123
123
  else loader
124
124
  )
125
125
  predictions = BatchedFormat([])
126
+
126
127
  for patch in loader:
127
- predictions += self.model.get_predictions(patch)
128
+ with torch.autocast(
129
+ device_type=Configuration().device,
130
+ dtype=torch.float16,
131
+ enabled=Configuration().optimize,
132
+ ):
133
+ predictions += self.model.get_predictions(patch)
128
134
  return predictions
129
135
 
130
136
  def predict(
@@ -38,7 +38,7 @@ class DetectMetric(Metric):
38
38
  self.func = func
39
39
  self.name = name
40
40
  self.add_state("stats", default=[], dist_reduce_fx="cat")
41
- self.nc = 1 # always one class
41
+ self.nc = 1 # always one class
42
42
 
43
43
  def update(
44
44
  self,
@@ -71,67 +71,79 @@ class DetectMetric(Metric):
71
71
  tp, fp, fn, _ = matcher.match_pred_target(pred, targ)
72
72
  elif pred.nb_object != 0 and targ.nb_object == 0:
73
73
  tp, fp, fn, _ = 0, pred.nb_object, 0, None
74
- #elif prediction.size == 0 and target.size != 0:
74
+ # elif prediction.size == 0 and target.size != 0:
75
75
  elif pred.nb_object == 0 and targ.nb_object != 0:
76
76
  tp, fp, fn, _ = 0, 0, targ.nb_object, None
77
77
  else:
78
78
  tp, fp, fn, _ = torch.nan, torch.nan, torch.nan, None
79
79
 
80
80
  # NaN because of no tn in detection
81
- self.stats.append(torch.tensor([[[tp, fp, torch.nan, fn, torch.nan]]])) # fix tn and support to nan
82
-
81
+ self.stats.append(
82
+ torch.tensor([[[tp, fp, torch.nan, fn, torch.nan]]])
83
+ ) # fix tn and support to nan
84
+
83
85
  def global_micro_compute(self) -> Tensor:
84
86
  """Compute metric with global/micro averagging."""
85
87
  n_samples = len(self.stats)
86
88
  samples_stack = torch.cat(self.stats).view(n_samples, self.nc, 5) # (N, NC, 5)
87
89
  # sum stats accross samples
88
- samples_stack = samples_stack.sum(dim=0) # (NC, 5)
90
+ samples_stack = samples_stack.nansum(dim=0) # (NC, 5)
89
91
  # sum stats accross classes
90
- micro_stack = torch.sum(samples_stack, dim=0) # (5,)
92
+ micro_stack = torch.nansum(samples_stack, dim=0) # (5,)
91
93
  # compute metric
92
94
  tp, fp, tn, fn, _ = micro_stack.unbind(0)
93
95
  return self.func(tp, fp, tn, fn)
94
-
96
+
95
97
  def samplewise_micro(self) -> Tensor:
96
98
  """Compute metric with samplewise/micro averagging."""
97
99
  n_samples = len(self.stats)
98
100
  samples_stack = torch.cat(self.stats).view(n_samples, self.nc, 5) # (N, NC, 5))
99
101
  # sum stat accross classes
100
- samples_stack = samples_stack.sum(dim=1) # (NC, 5)
102
+ samples_stack = samples_stack.nansum(dim=1) # (NC, 5)
101
103
  # compute metric/sample
102
104
  tp, fp, tn, fn, _ = samples_stack.unbind(dim=1)
103
105
  samples_metrics = self.func(tp, fp, tn, fn)
104
106
  # mean accross samples
105
107
  return torch.nanmean(samples_metrics)
106
-
108
+
107
109
  def compute_last_sample(self):
108
110
  """Return metrics values of the last sample in self.stats.
109
111
  Used in combination with self.update
110
-
112
+
111
113
  Returns:
112
114
  Dict[str, Float]: dictionnary with metric value for all classes combined and for each class
113
115
  """
114
116
 
115
117
  if not self.stats:
116
- return {'all_cls': torch.tensor(torch.nan)}
117
-
118
+ return {"all_cls": torch.tensor(torch.nan)}
119
+
118
120
  metric_sample_dict = {}
119
121
 
120
- matrix_stats_img = self.stats[-1].squeeze(0) # matrix with stats (tp, fp, tn, fn) of one sample (one row for each class)
122
+ matrix_stats_img = self.stats[-1].squeeze(
123
+ 0
124
+ ) # matrix with stats (tp, fp, tn, fn) of one sample (one row for each class)
121
125
  nb_class = matrix_stats_img.size(dim=0)
122
- tp, fp, tn, fn, _ = matrix_stats_img.nansum(dim=0).unbind(dim=0) # sum over all classes
123
- all_class_metric_value = round(self.func(tp, fp, tn, fn).item(),3) # metric compute for all classes
124
- metric_sample_dict['all_cls'] = all_class_metric_value
126
+ tp, fp, tn, fn, _ = matrix_stats_img.nansum(dim=0).unbind(
127
+ dim=0
128
+ ) # sum over all classes
129
+ all_class_metric_value = round(
130
+ self.func(tp, fp, tn, fn).item(), 3
131
+ ) # metric compute for all classes
132
+ metric_sample_dict["all_cls"] = all_class_metric_value
125
133
 
126
134
  if nb_class > 1:
127
- for index_class in range (nb_class) : # metric compute for each class
128
- matrix_stats_img_class = matrix_stats_img[index_class,:]
129
- tp, fp, tn, fn, _ = matrix_stats_img_class.unbind(dim=0) # stats (tp, fp, tn, fn) of the given class
130
- class_metric_value = round(self.func(tp, fp, tn, fn).item(),3) # metric compute for the given class
135
+ for index_class in range(nb_class): # metric compute for each class
136
+ matrix_stats_img_class = matrix_stats_img[index_class, :]
137
+ tp, fp, tn, fn, _ = matrix_stats_img_class.unbind(
138
+ dim=0
139
+ ) # stats (tp, fp, tn, fn) of the given class
140
+ class_metric_value = round(
141
+ self.func(tp, fp, tn, fn).item(), 3
142
+ ) # metric compute for the given class
131
143
  metric_sample_dict["cls_{0}".format(index_class)] = class_metric_value
132
144
 
133
145
  return metric_sample_dict
134
-
146
+
135
147
  def compute(self) -> Dict[str, Tensor]:
136
148
  """Return metric computed with internal state.
137
149
 
@@ -140,7 +152,7 @@ class DetectMetric(Metric):
140
152
  """
141
153
  if not self.stats:
142
154
  return {self.name: torch.tensor(torch.nan)}
143
-
155
+
144
156
  # global micro
145
157
  global_value = self.global_micro_compute()
146
158
  # samplewise micro
@@ -218,27 +230,31 @@ class ClassWiseDetectMetric(Metric):
218
230
  if i == 0:
219
231
  met.update(prediction, target)
220
232
  else:
221
- filtered_pred = self._filter_classes(prediction, i-1) # -1 because classes start at 0
222
- filtered_targ = self._filter_classes(target, i-1)
233
+ filtered_pred = self._filter_classes(
234
+ prediction, i - 1
235
+ ) # -1 because classes start at 0
236
+ filtered_targ = self._filter_classes(target, i - 1)
223
237
  met.update(filtered_pred, filtered_targ)
224
-
238
+
225
239
  # retrieve and save in a list the stats for each sample in the batch for the given class
226
240
  batch_size = prediction.size
227
- for num_elem in range (batch_size,0,-1):
241
+ for num_elem in range(batch_size, 0, -1):
228
242
  met_samples_result.append(met.stats[-num_elem])
229
-
230
- list_met_class.append(met_samples_result) # save the list in the list containing the list of each class
231
-
243
+
244
+ list_met_class.append(
245
+ met_samples_result
246
+ ) # save the list in the list containing the list of each class
247
+
232
248
  # save the batch sample stats for each class in a matrix (N, NC, 5) and append in metric 'stats' attribute
233
249
  for num_sample in range(batch_size):
234
250
  sample_stats = []
235
- for num_class in range(1,len(list_met_class)):
251
+ for num_class in range(1, len(list_met_class)):
236
252
  sample_stats.append(list_met_class[num_class][num_sample])
237
-
238
- class_stack = torch.cat(sample_stats).view(1, Configuration().num_classes, 5) # (N, NC, 5)
239
- self.stats.append(class_stack)
240
-
241
253
 
254
+ class_stack = torch.cat(sample_stats).view(
255
+ 1, Configuration().num_classes, 5
256
+ ) # (N, NC, 5)
257
+ self.stats.append(class_stack)
242
258
 
243
259
  # for sample_list_met_class in list_met_class:
244
260
  # sample_list_met_class = sample_list_met_class[1:]
@@ -305,27 +321,37 @@ class ClassWiseDetectMetric(Metric):
305
321
  def compute_last_sample(self):
306
322
  """Return metrics values of the last sample in self.stats.
307
323
  Used in combination with self.update
308
-
324
+
309
325
  Returns:
310
326
  Dict[str, Float]: dictionnary with metric value for all classes combined and for each class
311
327
  """
312
328
 
313
329
  if not self.stats:
314
- return {'all_cls': torch.tensor(torch.nan)}
315
-
330
+ return {"all_cls": torch.tensor(torch.nan)}
331
+
316
332
  metric_sample_dict = {}
317
333
 
318
- matrix_stats_img = self.stats[-1].squeeze(0) # matrix with stats (tp, fp, tn, fn) of one sample (one row for each class)
334
+ matrix_stats_img = self.stats[-1].squeeze(
335
+ 0
336
+ ) # matrix with stats (tp, fp, tn, fn) of one sample (one row for each class)
319
337
  nb_class = matrix_stats_img.size(dim=0)
320
- tp, fp, tn, fn, _ = matrix_stats_img.nansum(dim=0).unbind(dim=0) # sum over all classes
321
- all_class_metric_value = round(self.func(tp, fp, tn, fn).item(),3) # metric compute for all classes
322
- metric_sample_dict['all_cls'] = all_class_metric_value
338
+ tp, fp, tn, fn, _ = matrix_stats_img.nansum(dim=0).unbind(
339
+ dim=0
340
+ ) # sum over all classes
341
+ all_class_metric_value = round(
342
+ self.func(tp, fp, tn, fn).item(), 3
343
+ ) # metric compute for all classes
344
+ metric_sample_dict["all_cls"] = all_class_metric_value
323
345
 
324
346
  if nb_class > 1:
325
- for index_class in range (nb_class) : # metric compute for each class
326
- matrix_stats_img_class = matrix_stats_img[index_class,:]
327
- tp, fp, tn, fn, _ = matrix_stats_img_class.unbind(dim=0) # stats (tp, fp, tn, fn) of the given class
328
- class_metric_value = round(self.func(tp, fp, tn, fn).item(),3) # metric compute for the given class
347
+ for index_class in range(nb_class): # metric compute for each class
348
+ matrix_stats_img_class = matrix_stats_img[index_class, :]
349
+ tp, fp, tn, fn, _ = matrix_stats_img_class.unbind(
350
+ dim=0
351
+ ) # stats (tp, fp, tn, fn) of the given class
352
+ class_metric_value = round(
353
+ self.func(tp, fp, tn, fn).item(), 3
354
+ ) # metric compute for the given class
329
355
  metric_sample_dict["cls_{0}".format(index_class)] = class_metric_value
330
356
 
331
357
  return metric_sample_dict
@@ -336,9 +362,9 @@ class ClassWiseDetectMetric(Metric):
336
362
  Returns:
337
363
  Dict[str, Tensor]: dictionnary with all "global" DetectMetric in self.classmetrics
338
364
  """
339
- #classwisedict = {met.name: met.compute()["global"] for met in self.classmetrics}
340
- #return classwisedict
341
-
365
+ # classwisedict = {met.name: met.compute()["global"] for met in self.classmetrics}
366
+ # return classwisedict
367
+
342
368
  if not self.stats:
343
369
  return {self.name: torch.tensor(torch.nan)}
344
370
 
@@ -349,8 +375,7 @@ class ClassWiseDetectMetric(Metric):
349
375
  # global macro
350
376
  global_macro, class_metrics = self.global_macro_compute()
351
377
  classes_dict = {
352
- f"/cls_{i}": class_metrics[i]
353
- for i in range(class_metrics.nelement())
378
+ f"/cls_{i}": class_metrics[i] for i in range(class_metrics.nelement())
354
379
  }
355
380
  metric_dict.update({"_global_macro": global_macro})
356
381
  metric_dict.update(classes_dict)
@@ -460,9 +485,9 @@ class ClassifMetric(Metric):
460
485
  n_samples = len(self.stats)
461
486
  samples_stack = torch.cat(self.stats).view(n_samples, self.nc, 5) # (N, NC, 5)
462
487
  # sum stats accross samples
463
- samples_stack = samples_stack.sum(dim=0) # (NC, 5)
488
+ samples_stack = samples_stack.nansum(dim=0) # (NC, 5)
464
489
  # sum stats accross classes
465
- micro_stack = torch.sum(samples_stack, dim=0) # (5,)
490
+ micro_stack = torch.nansum(samples_stack, dim=0) # (5,)
466
491
  # compute metric
467
492
  tp, fp, tn, fn, _ = micro_stack.unbind(0)
468
493
  return self.func(tp, fp, tn, fn)
@@ -473,7 +498,7 @@ class ClassifMetric(Metric):
473
498
  n_samples = len(self.stats)
474
499
  samples_stack = torch.cat(self.stats).view(n_samples, self.nc, 5) # (N, NC, 5)
475
500
  # sum stats accross samples
476
- samples_stack = samples_stack.sum(dim=0) # (NC, 5)
501
+ samples_stack = samples_stack.nansum(dim=0) # (NC, 5)
477
502
  # compute metric/class
478
503
  tp, fp, tn, fn, _ = samples_stack.unbind(1)
479
504
  class_metrics = self.func(tp, fp, tn, fn) # (NC,)
@@ -484,7 +509,7 @@ class ClassifMetric(Metric):
484
509
  n_samples = len(self.stats)
485
510
  samples_stack = torch.cat(self.stats).view(n_samples, self.nc, 5) # (N, NC, 5))
486
511
  # sum stat accross classes
487
- samples_stack = samples_stack.sum(dim=1) # (NC, 5)
512
+ samples_stack = samples_stack.nansum(dim=1) # (NC, 5)
488
513
  # compute metric/sample
489
514
  tp, fp, tn, fn, _ = samples_stack.unbind(dim=1)
490
515
  samples_metrics = self.func(tp, fp, tn, fn)
@@ -504,35 +529,45 @@ class ClassifMetric(Metric):
504
529
  macro_samplewise = torch.nanmean(macro, dim=0)
505
530
 
506
531
  return macro_samplewise
507
-
532
+
508
533
  def compute_last_sample(self):
509
534
  """Return metrics values of the last sample in self.stats.
510
535
  Used in combination with self.update
511
-
536
+
512
537
  Returns:
513
538
  Dict[str, Float]: dictionnary with metric value for all classes combined and for each class
514
539
  """
515
540
 
516
541
  if not self.stats:
517
- return {'all_cls': torch.tensor(torch.nan)}
518
-
542
+ return {"all_cls": torch.tensor(torch.nan)}
543
+
519
544
  metric_sample_dict = {}
520
545
 
521
- matrix_stats_img = self.stats[-1].squeeze(0) # matrix with stats (tp, fp, tn, fn) of one sample (one row for each class)
546
+ matrix_stats_img = self.stats[-1].squeeze(
547
+ 0
548
+ ) # matrix with stats (tp, fp, tn, fn) of one sample (one row for each class)
522
549
  nb_class = matrix_stats_img.size(dim=0)
523
- tp, fp, tn, fn, _ = matrix_stats_img.nansum(dim=0).unbind(dim=0) # sum over all classes
524
- all_class_metric_value = round(self.func(tp, fp, tn, fn).item(),3) # metric compute for all classes
525
- metric_sample_dict['all_cls'] = all_class_metric_value
550
+ tp, fp, tn, fn, _ = matrix_stats_img.nansum(dim=0).unbind(
551
+ dim=0
552
+ ) # sum over all classes
553
+ all_class_metric_value = round(
554
+ self.func(tp, fp, tn, fn).item(), 3
555
+ ) # metric compute for all classes
556
+ metric_sample_dict["all_cls"] = all_class_metric_value
526
557
 
527
558
  if nb_class > 1:
528
- for index_class in range (nb_class) : # metric compute for each class
529
- matrix_stats_img_class = matrix_stats_img[index_class,:]
530
- tp, fp, tn, fn, _ = matrix_stats_img_class.unbind(dim=0) # stats (tp, fp, tn, fn) of the given class
531
- class_metric_value = round(self.func(tp, fp, tn, fn).item(),3) # metric compute for the given class
559
+ for index_class in range(nb_class): # metric compute for each class
560
+ matrix_stats_img_class = matrix_stats_img[index_class, :]
561
+ tp, fp, tn, fn, _ = matrix_stats_img_class.unbind(
562
+ dim=0
563
+ ) # stats (tp, fp, tn, fn) of the given class
564
+ class_metric_value = round(
565
+ self.func(tp, fp, tn, fn).item(), 3
566
+ ) # metric compute for the given class
532
567
  metric_sample_dict["cls_{0}".format(index_class)] = class_metric_value
533
568
 
534
569
  return metric_sample_dict
535
-
570
+
536
571
  def compute(self):
537
572
  """Comput metric with all averag strategy and return a dict with all values."""
538
573
  if not self.stats:
@@ -1,13 +1,15 @@
1
- from deepvisiontools.models.yolov8.yolov8 import Yolov8
2
- from deepvisiontools.models.yolov8seg.yolov8seg import Yolov8Seg
1
+ from deepvisiontools.models.yolo.yolo import Yolo
2
+ from deepvisiontools.models.yoloseg.yoloseg import YoloSeg
3
3
  from deepvisiontools.models.mask2former.mask2former import Mask2Former
4
+ from deepvisiontools.models.timmyolo.timmyolo import TimmYolo
4
5
  from deepvisiontools.models.basemodel import BaseModel
5
6
  from deepvisiontools.models.smp.smp import SMP, _ConcreteSegmentationModel
6
7
 
7
8
  __all__ = (
8
9
  "BaseModel",
9
- "Yolov8",
10
- "Yolov8Seg",
10
+ "Yolo",
11
+ "YoloSeg",
12
+ "TimmYolo",
11
13
  "Mask2Former",
12
14
  "SMP",
13
15
  "_ConcreteSegmentationModel",
@@ -0,0 +1,4 @@
1
+ from deepvisiontools.models.timmyolo.timmyolo import TimmYolo, LossHyperParams, YoloLoss
2
+ from deepvisiontools.models.timmyolo.errors import NonImplementedForward
3
+
4
+ __all__ = ("TimmYolo", "LossHyperParams", "YoloLoss", "NonImplementedForward")
@@ -0,0 +1,5 @@
1
+ class NonImplementedForward(Exception):
2
+ def __init__(self):
3
+ super().__init__(
4
+ message="Model does not work with forward because of internal patchification and feature merging required. Please use model.run_forward() to perform predictions."
5
+ )