kaiko-eva 0.1.1__py3-none-any.whl → 0.1.5__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.
Files changed (68) hide show
  1. eva/core/callbacks/writers/embeddings/base.py +3 -4
  2. eva/core/data/dataloaders/dataloader.py +2 -2
  3. eva/core/data/splitting/random.py +6 -5
  4. eva/core/data/splitting/stratified.py +12 -6
  5. eva/core/losses/__init__.py +5 -0
  6. eva/core/losses/cross_entropy.py +27 -0
  7. eva/core/metrics/__init__.py +0 -4
  8. eva/core/metrics/defaults/__init__.py +0 -2
  9. eva/core/models/modules/module.py +9 -9
  10. eva/core/models/transforms/extract_cls_features.py +17 -9
  11. eva/core/models/transforms/extract_patch_features.py +23 -11
  12. eva/core/utils/io/__init__.py +2 -1
  13. eva/core/utils/io/gz.py +28 -0
  14. eva/core/utils/multiprocessing.py +46 -1
  15. eva/core/utils/progress_bar.py +15 -0
  16. eva/vision/callbacks/loggers/batch/segmentation.py +7 -4
  17. eva/vision/data/datasets/__init__.py +4 -0
  18. eva/vision/data/datasets/classification/__init__.py +2 -1
  19. eva/vision/data/datasets/classification/camelyon16.py +4 -1
  20. eva/vision/data/datasets/classification/panda.py +17 -1
  21. eva/vision/data/datasets/classification/wsi.py +4 -1
  22. eva/vision/data/datasets/segmentation/__init__.py +2 -0
  23. eva/vision/data/datasets/segmentation/consep.py +2 -2
  24. eva/vision/data/datasets/segmentation/lits.py +49 -29
  25. eva/vision/data/datasets/segmentation/lits_balanced.py +93 -0
  26. eva/vision/data/datasets/segmentation/monusac.py +7 -7
  27. eva/vision/data/datasets/segmentation/total_segmentator_2d.py +50 -18
  28. eva/vision/data/datasets/wsi.py +37 -1
  29. eva/vision/data/wsi/patching/coordinates.py +9 -1
  30. eva/vision/data/wsi/patching/samplers/_utils.py +2 -8
  31. eva/vision/data/wsi/patching/samplers/random.py +4 -2
  32. eva/vision/losses/__init__.py +2 -2
  33. eva/vision/losses/dice.py +75 -8
  34. eva/vision/metrics/__init__.py +11 -0
  35. eva/vision/metrics/defaults/__init__.py +7 -0
  36. eva/{core → vision}/metrics/defaults/segmentation/__init__.py +1 -1
  37. eva/{core → vision}/metrics/defaults/segmentation/multiclass.py +2 -1
  38. eva/vision/metrics/segmentation/BUILD +1 -0
  39. eva/vision/metrics/segmentation/__init__.py +9 -0
  40. eva/vision/metrics/segmentation/_utils.py +69 -0
  41. eva/{core/metrics → vision/metrics/segmentation}/generalized_dice.py +12 -10
  42. eva/vision/metrics/segmentation/mean_iou.py +57 -0
  43. eva/vision/models/modules/semantic_segmentation.py +4 -3
  44. eva/vision/models/networks/backbones/_utils.py +12 -0
  45. eva/vision/models/networks/backbones/pathology/__init__.py +4 -1
  46. eva/vision/models/networks/backbones/pathology/histai.py +8 -2
  47. eva/vision/models/networks/backbones/pathology/mahmood.py +2 -9
  48. eva/vision/models/networks/backbones/pathology/owkin.py +14 -0
  49. eva/vision/models/networks/backbones/pathology/paige.py +51 -0
  50. eva/vision/models/networks/decoders/__init__.py +1 -1
  51. eva/vision/models/networks/decoders/segmentation/__init__.py +12 -4
  52. eva/vision/models/networks/decoders/segmentation/base.py +16 -0
  53. eva/vision/models/networks/decoders/segmentation/{conv2d.py → decoder2d.py} +26 -22
  54. eva/vision/models/networks/decoders/segmentation/linear.py +2 -2
  55. eva/vision/models/networks/decoders/segmentation/semantic/__init__.py +12 -0
  56. eva/vision/models/networks/decoders/segmentation/{common.py → semantic/common.py} +3 -3
  57. eva/vision/models/networks/decoders/segmentation/semantic/with_image.py +94 -0
  58. eva/vision/models/networks/decoders/segmentation/typings.py +18 -0
  59. eva/vision/utils/colormap.py +20 -0
  60. eva/vision/utils/io/__init__.py +7 -1
  61. eva/vision/utils/io/nifti.py +19 -4
  62. {kaiko_eva-0.1.1.dist-info → kaiko_eva-0.1.5.dist-info}/METADATA +8 -39
  63. {kaiko_eva-0.1.1.dist-info → kaiko_eva-0.1.5.dist-info}/RECORD +66 -52
  64. {kaiko_eva-0.1.1.dist-info → kaiko_eva-0.1.5.dist-info}/WHEEL +1 -1
  65. eva/core/metrics/mean_iou.py +0 -120
  66. eva/vision/models/networks/decoders/decoder.py +0 -7
  67. {kaiko_eva-0.1.1.dist-info → kaiko_eva-0.1.5.dist-info}/entry_points.txt +0 -0
  68. {kaiko_eva-0.1.1.dist-info → kaiko_eva-0.1.5.dist-info}/licenses/LICENSE +0 -0
@@ -1,19 +1,20 @@
1
1
  """Convolutional based semantic segmentation decoder."""
2
2
 
3
- from typing import List, Tuple
3
+ from typing import List, Sequence, Tuple
4
4
 
5
5
  import torch
6
6
  from torch import nn
7
7
  from torch.nn import functional
8
8
 
9
- from eva.vision.models.networks.decoders import decoder
9
+ from eva.vision.models.networks.decoders.segmentation import base
10
+ from eva.vision.models.networks.decoders.segmentation.typings import DecoderInputs
10
11
 
11
12
 
12
- class ConvDecoder(decoder.Decoder):
13
- """Convolutional segmentation decoder."""
13
+ class Decoder2D(base.Decoder):
14
+ """Segmentation decoder for 2D applications."""
14
15
 
15
- def __init__(self, layers: nn.Module) -> None:
16
- """Initializes the convolutional based decoder head.
16
+ def __init__(self, layers: nn.Module, combine_features: bool = True) -> None:
17
+ """Initializes the based decoder head.
17
18
 
18
19
  Here the input nn layers will be directly applied to the
19
20
  features of shape (batch_size, hidden_size, n_patches_height,
@@ -21,13 +22,16 @@ class ConvDecoder(decoder.Decoder):
21
22
  Note the n_patches is also known as grid_size.
22
23
 
23
24
  Args:
24
- layers: The convolutional layers to be used as the decoder head.
25
+ layers: The layers to be used as the decoder head.
26
+ combine_features: Whether to combine the features from different
27
+ feature levels into one tensor before applying the decoder head.
25
28
  """
26
29
  super().__init__()
27
30
 
28
31
  self._layers = layers
32
+ self._combine_features = combine_features
29
33
 
30
- def _forward_features(self, features: List[torch.Tensor]) -> torch.Tensor:
34
+ def _forward_features(self, features: torch.Tensor | List[torch.Tensor]) -> torch.Tensor:
31
35
  """Forward function for multi-level feature maps to a single one.
32
36
 
33
37
  It will interpolate the features and concat them into a single tensor
@@ -46,6 +50,8 @@ class ConvDecoder(decoder.Decoder):
46
50
  A tensor of shape (batch_size, hidden_size, n_patches_height,
47
51
  n_patches_width) which is feature map of the decoder head.
48
52
  """
53
+ if isinstance(features, torch.Tensor):
54
+ features = [features]
49
55
  if not isinstance(features, list) or features[0].ndim != 4:
50
56
  raise ValueError(
51
57
  "Input features should be a list of four (4) dimensional inputs of "
@@ -63,7 +69,9 @@ class ConvDecoder(decoder.Decoder):
63
69
  ]
64
70
  return torch.cat(upsampled_features, dim=1)
65
71
 
66
- def _forward_head(self, patch_embeddings: torch.Tensor) -> torch.Tensor:
72
+ def _forward_head(
73
+ self, patch_embeddings: torch.Tensor | Sequence[torch.Tensor]
74
+ ) -> torch.Tensor:
67
75
  """Forward of the decoder head.
68
76
 
69
77
  Args:
@@ -75,12 +83,12 @@ class ConvDecoder(decoder.Decoder):
75
83
  """
76
84
  return self._layers(patch_embeddings)
77
85
 
78
- def _cls_seg(
86
+ def _upscale(
79
87
  self,
80
88
  logits: torch.Tensor,
81
89
  image_size: Tuple[int, int],
82
90
  ) -> torch.Tensor:
83
- """Classify each pixel of the image.
91
+ """Upscales the calculated logits to the target image size.
84
92
 
85
93
  Args:
86
94
  logits: The decoder outputs of shape (batch_size, n_classes,
@@ -93,22 +101,18 @@ class ConvDecoder(decoder.Decoder):
93
101
  """
94
102
  return functional.interpolate(logits, image_size, mode="bilinear")
95
103
 
96
- def forward(
97
- self,
98
- features: List[torch.Tensor],
99
- image_size: Tuple[int, int],
100
- ) -> torch.Tensor:
104
+ def forward(self, decoder_inputs: DecoderInputs) -> torch.Tensor:
101
105
  """Maps the patch embeddings to a segmentation mask of the image size.
102
106
 
103
107
  Args:
104
- features: List of multi-level image features of shape (batch_size,
105
- hidden_size, n_patches_height, n_patches_width).
106
- image_size: The target image size (height, width).
108
+ decoder_inputs: Inputs required by the decoder.
107
109
 
108
110
  Returns:
109
111
  Tensor containing scores for all of the classes with shape
110
112
  (batch_size, n_classes, image_height, image_width).
111
113
  """
112
- patch_embeddings = self._forward_features(features)
113
- logits = self._forward_head(patch_embeddings)
114
- return self._cls_seg(logits, image_size)
114
+ features, image_size, _ = DecoderInputs(*decoder_inputs)
115
+ if self._combine_features:
116
+ features = self._forward_features(features)
117
+ logits = self._forward_head(features)
118
+ return self._upscale(logits, image_size)
@@ -6,10 +6,10 @@ import torch
6
6
  from torch import nn
7
7
  from torch.nn import functional
8
8
 
9
- from eva.vision.models.networks.decoders import decoder
9
+ from eva.vision.models.networks.decoders.segmentation import base
10
10
 
11
11
 
12
- class LinearDecoder(decoder.Decoder):
12
+ class LinearDecoder(base.Decoder):
13
13
  """Linear decoder."""
14
14
 
15
15
  def __init__(self, layers: nn.Module) -> None:
@@ -0,0 +1,12 @@
1
+ """Semantic Segmentation decoder heads API."""
2
+
3
+ from eva.vision.models.networks.decoders.segmentation.semantic.common import (
4
+ ConvDecoder1x1,
5
+ ConvDecoderMS,
6
+ SingleLinearDecoder,
7
+ )
8
+ from eva.vision.models.networks.decoders.segmentation.semantic.with_image import (
9
+ ConvDecoderWithImage,
10
+ )
11
+
12
+ __all__ = ["ConvDecoder1x1", "ConvDecoderMS", "SingleLinearDecoder", "ConvDecoderWithImage"]
@@ -7,10 +7,10 @@ output by an encoder into pixel-wise predictions for segmentation tasks.
7
7
 
8
8
  from torch import nn
9
9
 
10
- from eva.vision.models.networks.decoders.segmentation import conv2d, linear
10
+ from eva.vision.models.networks.decoders.segmentation import decoder2d, linear
11
11
 
12
12
 
13
- class ConvDecoder1x1(conv2d.ConvDecoder):
13
+ class ConvDecoder1x1(decoder2d.Decoder2D):
14
14
  """A convolutional decoder with a single 1x1 convolutional layer."""
15
15
 
16
16
  def __init__(self, in_features: int, num_classes: int) -> None:
@@ -29,7 +29,7 @@ class ConvDecoder1x1(conv2d.ConvDecoder):
29
29
  )
30
30
 
31
31
 
32
- class ConvDecoderMS(conv2d.ConvDecoder):
32
+ class ConvDecoderMS(decoder2d.Decoder2D):
33
33
  """A multi-stage convolutional decoder with upsampling and convolutional layers.
34
34
 
35
35
  This decoder applies a series of upsampling and convolutional layers to transform
@@ -0,0 +1,94 @@
1
+ """Convolutional semantic segmentation decoders that use input image & feature maps as input."""
2
+
3
+ from typing import List
4
+
5
+ import torch
6
+ from torch import nn
7
+ from torchvision.transforms.functional import rgb_to_grayscale
8
+ from typing_extensions import override
9
+
10
+ from eva.vision.models.networks.decoders.segmentation import decoder2d
11
+ from eva.vision.models.networks.decoders.segmentation.typings import DecoderInputs
12
+
13
+
14
+ class ConvDecoderWithImage(decoder2d.Decoder2D):
15
+ """A convolutional that in addition to encoded features, also takes the input image as input.
16
+
17
+ In a first stage, the input features are upsampled and passed through a convolutional layer,
18
+ while in the second stage, the input image channels are concatenated with the upsampled features
19
+ and passed through additional convolutional blocks in order to combine the image prior
20
+ information with the encoded features. Lastly, a 1x1 conv operation reduces the number of
21
+ channels to the number of classes.
22
+ """
23
+
24
+ _default_hidden_dims = [64, 32, 32]
25
+
26
+ def __init__(
27
+ self,
28
+ in_features: int,
29
+ num_classes: int,
30
+ greyscale: bool = False,
31
+ hidden_dims: List[int] | None = None,
32
+ ) -> None:
33
+ """Initializes the decoder.
34
+
35
+ Args:
36
+ in_features: The hidden dimension size of the embeddings.
37
+ num_classes: Number of output classes as channels.
38
+ greyscale: Whether to convert input images to greyscale.
39
+ hidden_dims: List of hidden dimensions for the convolutional layers.
40
+ """
41
+ hidden_dims = hidden_dims or self._default_hidden_dims
42
+ if len(hidden_dims) != 3:
43
+ raise ValueError("Hidden dims must have 3 elements.")
44
+
45
+ super().__init__(
46
+ layers=nn.Sequential(
47
+ nn.Upsample(scale_factor=2),
48
+ Conv2dBnReLU(in_features, hidden_dims[0]),
49
+ )
50
+ )
51
+ self.greyscale = greyscale
52
+
53
+ additional_hidden_dims = 1 if greyscale else 3
54
+ self.image_block = nn.Sequential(
55
+ Conv2dBnReLU(hidden_dims[0] + additional_hidden_dims, hidden_dims[1]),
56
+ Conv2dBnReLU(hidden_dims[1], hidden_dims[2]),
57
+ )
58
+
59
+ self.classifier = nn.Conv2d(hidden_dims[2], num_classes, kernel_size=1)
60
+
61
+ @override
62
+ def forward(self, decoder_inputs: DecoderInputs) -> torch.Tensor:
63
+ if decoder_inputs.images is None:
64
+ raise ValueError("Input images are missing.")
65
+
66
+ logits = super().forward(decoder_inputs)
67
+ in_images = (
68
+ rgb_to_grayscale(decoder_inputs.images) if self.greyscale else decoder_inputs.images
69
+ )
70
+ logits = torch.cat([logits, in_images], dim=1)
71
+ logits = self.image_block(logits)
72
+
73
+ return self.classifier(logits)
74
+
75
+
76
+ class Conv2dBnReLU(nn.Sequential):
77
+ """A single convolutional layer with batch normalization and ReLU activation."""
78
+
79
+ def __init__(
80
+ self, in_channels: int, out_channels: int, kernel_size: int = 3, padding: int = 1
81
+ ) -> None:
82
+ """Initializes the layer.
83
+
84
+ Args:
85
+ in_channels: Number of input channels.
86
+ out_channels: Number of output channels.
87
+ kernel_size: Size of the convolutional kernel.
88
+ padding: Padding size for the convolutional layer.
89
+ """
90
+ super().__init__(
91
+ nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, padding=padding),
92
+ nn.BatchNorm2d(out_channels),
93
+ nn.ReLU(inplace=True),
94
+ )
@@ -0,0 +1,18 @@
1
+ """Type-hints for segmentation decoders."""
2
+
3
+ from typing import List, NamedTuple, Tuple
4
+
5
+ import torch
6
+
7
+
8
+ class DecoderInputs(NamedTuple):
9
+ """Input scheme for segmentation decoders."""
10
+
11
+ features: List[torch.Tensor]
12
+ """List of image features generated by the encoder from the original images."""
13
+
14
+ image_size: Tuple[int, int]
15
+ """Size of the original input images to be used for upsampling."""
16
+
17
+ images: torch.Tensor | None = None
18
+ """The original input images for which the encoder generated the encoded_images."""
@@ -1,5 +1,7 @@
1
1
  """Color mapping constants."""
2
2
 
3
+ from typing import List, Tuple
4
+
3
5
  COLORS = [
4
6
  (0, 0, 0),
5
7
  (255, 0, 0), # Red
@@ -75,3 +77,21 @@ COLORS = [
75
77
 
76
78
  COLORMAP = dict(enumerate(COLORS)) | {255: (255, 255, 255)}
77
79
  """Class id to RGB color mapping."""
80
+
81
+
82
+ def get_colors(num_colors: int) -> List[Tuple[int, int, int]]:
83
+ """Get a list of RGB colors.
84
+
85
+ If the number of colors is greater than the predefined colors, it will
86
+ repeat the colors until it reaches the requested number
87
+
88
+ Args:
89
+ num_colors: The number of colors to return.
90
+
91
+ Returns:
92
+ A list of RGB colors.
93
+ """
94
+ colors = COLORS
95
+ while len(colors) < num_colors:
96
+ colors = colors + COLORS[1:]
97
+ return colors
@@ -2,7 +2,12 @@
2
2
 
3
3
  from eva.vision.utils.io.image import read_image, read_image_as_array, read_image_as_tensor
4
4
  from eva.vision.utils.io.mat import read_mat, save_mat
5
- from eva.vision.utils.io.nifti import fetch_nifti_shape, read_nifti, save_array_as_nifti
5
+ from eva.vision.utils.io.nifti import (
6
+ fetch_nifti_axis_direction_code,
7
+ fetch_nifti_shape,
8
+ read_nifti,
9
+ save_array_as_nifti,
10
+ )
6
11
  from eva.vision.utils.io.text import read_csv
7
12
 
8
13
  __all__ = [
@@ -10,6 +15,7 @@ __all__ = [
10
15
  "read_image_as_array",
11
16
  "read_image_as_tensor",
12
17
  "fetch_nifti_shape",
18
+ "fetch_nifti_axis_direction_code",
13
19
  "read_nifti",
14
20
  "save_array_as_nifti",
15
21
  "read_csv",
@@ -5,6 +5,7 @@ from typing import Any, Tuple
5
5
  import nibabel as nib
6
6
  import numpy as np
7
7
  import numpy.typing as npt
8
+ from nibabel import orientations
8
9
 
9
10
  from eva.vision.utils.io import _utils
10
11
 
@@ -28,13 +29,13 @@ def read_nifti(
28
29
  ValueError: If the input channel is invalid for the image.
29
30
  """
30
31
  _utils.check_file(path)
31
- image_data = nib.load(path) # type: ignore
32
+ image_data: nib.Nifti1Image = nib.load(path) # type: ignore
32
33
  if slice_index is not None:
33
- image_data = image_data.slicer[:, :, slice_index : slice_index + 1] # type: ignore
34
+ image_data = image_data.slicer[:, :, slice_index : slice_index + 1]
34
35
 
35
- image_array = image_data.get_fdata() # type: ignore
36
+ image_array = image_data.get_fdata()
36
37
  if use_storage_dtype:
37
- image_array = image_array.astype(image_data.get_data_dtype()) # type: ignore
38
+ image_array = image_array.astype(image_data.get_data_dtype())
38
39
 
39
40
  return image_array
40
41
 
@@ -73,3 +74,17 @@ def fetch_nifti_shape(path: str) -> Tuple[int]:
73
74
  _utils.check_file(path)
74
75
  image = nib.load(path) # type: ignore
75
76
  return image.header.get_data_shape() # type: ignore
77
+
78
+
79
+ def fetch_nifti_axis_direction_code(path: str) -> str:
80
+ """Fetches the NIfTI axis direction code from a file.
81
+
82
+ Args:
83
+ path: The path to the NIfTI file.
84
+
85
+ Returns:
86
+ The axis direction codes as string (e.g. "LAS").
87
+ """
88
+ _utils.check_file(path)
89
+ image_data: nib.Nifti1Image = nib.load(path) # type: ignore
90
+ return "".join(orientations.aff2axcodes(image_data.affine))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kaiko-eva
3
- Version: 0.1.1
3
+ Version: 0.1.5
4
4
  Summary: Evaluation Framework for oncology foundation models.
5
5
  Keywords: machine-learning,evaluation-framework,oncology,foundation-models
6
6
  Author-Email: Ioannis Gatopoulos <ioannis@kaiko.ai>, =?utf-8?q?Nicolas_K=C3=A4nzig?= <nicolas@kaiko.ai>, Roman Moser <roman@kaiko.ai>
@@ -216,14 +216,14 @@ Project-URL: Homepage, https://kaiko-ai.github.io/eva/dev/
216
216
  Project-URL: Repository, https://github.com/kaiko-ai/eva
217
217
  Project-URL: Documentation, https://kaiko-ai.github.io/eva/dev/
218
218
  Requires-Python: >=3.10
219
- Requires-Dist: torch==2.3.0
220
- Requires-Dist: lightning>=2.2.2
221
- Requires-Dist: jsonargparse[omegaconf]==4.31.0
219
+ Requires-Dist: torch>=2.3.0
220
+ Requires-Dist: lightning>=2.2.0
221
+ Requires-Dist: jsonargparse[omegaconf]>=4.30.0
222
222
  Requires-Dist: tensorboard>=2.16.2
223
223
  Requires-Dist: loguru>=0.7.2
224
- Requires-Dist: pandas>=2.2.0
224
+ Requires-Dist: pandas>=2.0.0
225
225
  Requires-Dist: transformers>=4.38.2
226
- Requires-Dist: onnxruntime>=1.17.1
226
+ Requires-Dist: onnxruntime>=1.15.1
227
227
  Requires-Dist: onnx>=1.16.0
228
228
  Requires-Dist: toolz>=0.12.1
229
229
  Requires-Dist: rich>=13.7.1
@@ -468,41 +468,10 @@ and [tutorials](https://kaiko-ai.github.io/eva/dev/user-guide/advanced/replicate
468
468
 
469
469
  ## Leaderboards
470
470
 
471
- In this section you will find model benchmarks which were generated with _`eva`_.
471
+ The following table shows the FMs we have evaluated with _`eva`_. For more detailed information about the evaluation process, please refer to our [documentation](https://kaiko-ai.github.io/eva/main/leaderboards/).
472
472
 
473
- ### Table I: WSI and microscopy image tasks
473
+ ![Pathology Leaderboard](./docs/images/leaderboard.svg)
474
474
 
475
- <br />
476
-
477
- <div align="center">
478
-
479
- | Model | BACH | CRC | MHIST | PCam | Camelyon16 | PANDA | CoNSeP | MoNuSAC |
480
- |---------|-------|-------|-------|--------|------------|-------|------------|-------|
481
- | ViT-S/16 _(random)_ <sup>[1]</sup> | 0.411|0.613|0.5|0.752|0.551|0.347|0.489|0.394|
482
- | ViT-S/16 _(ImageNet)_ <sup>[1]</sup> | 0.675|0.936|0.827|0.861|0.751|0.676|0.54|0.512|
483
- | DINO<sub>(p=16)</sub> <sup>[2]</sup> | 0.77|0.936|0.751|0.905|0.869|0.737|0.625|0.549|
484
- | Phikon <sup>[3]</sup> | 0.715|0.942|0.766|0.925|0.879|0.784|0.68|0.554|
485
- | UNI <sup>[4]</sup> | 0.797|0.95|0.835|0.939|0.933|0.774|0.67|0.575|
486
- | ViT-S/16 _(kaiko.ai)_ <sup>[5]</sup> | 0.8|0.949|0.831|0.902|0.897|0.77|0.622|0.573|
487
- | ViT-S/8 _(kaiko.ai)_ <sup>[5]</sup> | 0.825|0.948|0.826|0.887|0.879|0.741|0.677|0.617|
488
- | ViT-B/16 _(kaiko.ai)_ <sup>[5]</sup> | 0.846|0.959|0.839|0.906|0.891|0.753|0.647|0.572|
489
- | ViT-B/8 _(kaiko.ai)_ <sup>[5]</sup> | 0.867|0.952|0.814|0.921|0.939|0.761|0.706|0.661|
490
- | ViT-L/14 _(kaiko.ai)_ <sup>[5]</sup> | 0.862|0.935|0.822|0.907|0.941|0.769|0.686|0.599|
491
-
492
- _Table I: Linear probing evaluation of FMs on patch-level downstream datasets.<br> We report balanced accuracy
493
- for classification tasks and generalized Dice score for semgetnation tasks, averaged over 5 runs. Results are
494
- reported on the "test" split if available and otherwise on the "validation" split._
495
-
496
- </div>
497
-
498
- <br />
499
-
500
- _References_:
501
- 1. _"Emerging properties in self-supervised vision transformers”_, [arXiv](https://arxiv.org/abs/2104.14294)
502
- 2. _"Benchmarking self-supervised learning on diverse pathology datasets”_, [arXiv](https://arxiv.org/abs/2212.04690)
503
- 3. _"Scaling self-supervised learning for histopathology with masked image modeling”_, [medRxiv](https://www.medrxiv.org/content/10.1101/2023.07.21.23292757v1)
504
- 4. _"A General-Purpose Self-Supervised Model for Computational Pathology”_, [arXiv](https://arxiv.org/abs/2308.15474)
505
- 5. _"Towards Training Large-Scale Pathology Foundation Models: from TCGA to Hospital Scale”_, [arXiv](https://arxiv.org/pdf/2404.15217)
506
475
 
507
476
  ## Contributing
508
477