From 5ec27d06a82528d0662ace16a55800d908e1de35 Mon Sep 17 00:00:00 2001 From: Vladimir Iglovikov Date: Sat, 18 Jan 2025 19:46:57 -0800 Subject: [PATCH 1/5] Works for Albumentations --- .pre-commit-config.yaml | 4 +- benchmark/transforms/albumentations_impl.py | 268 +++++++++++--------- benchmark/transforms/kornia_impl.py | 2 +- benchmark/transforms/specs.py | 201 ++++++++------- pyproject.toml | 33 --- requirements-dev.txt | 2 + 6 files changed, 265 insertions(+), 245 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4ea7193..b56131c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: - id: requirements-txt-fixer - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.7.2 + rev: v0.9.2 hooks: # Run the linter. - id: ruff @@ -63,7 +63,7 @@ repos: hooks: - id: pyproject-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.13.0 + rev: v1.14.1 hooks: - id: mypy files: ^benchmark/ diff --git a/benchmark/transforms/albumentations_impl.py b/benchmark/transforms/albumentations_impl.py index a95814f..0ced421 100644 --- a/benchmark/transforms/albumentations_impl.py +++ b/benchmark/transforms/albumentations_impl.py @@ -12,63 +12,104 @@ class AlbumentationsImpl: """Albumentations implementations of transforms""" + @staticmethod + def Resize(params: dict[str, Any]) -> A.BasicTransform: + return A.Resize( + height=params["target_size"], + width=params["target_size"], + interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, + p=1, + ) + + @staticmethod + def RandomCrop128(params: dict[str, Any]) -> A.BasicTransform: + return A.RandomCrop( + height=params["height"], + width=params["width"], + p=1, + ) + + @staticmethod + def RandomResizedCrop(params: dict[str, Any]) -> A.BasicTransform: + return A.RandomResizedCrop( + size=(params["height"], params["width"]), + scale=params["scale"], + ratio=params["ratio"], + interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, + p=1, + ) + + @staticmethod + def CenterCrop128(params: dict[str, Any]) -> A.BasicTransform: + return A.CenterCrop( + height=params["height"], + width=params["width"], + p=1, + ) + @staticmethod def HorizontalFlip(params: dict[str, Any]) -> A.BasicTransform: - return A.HorizontalFlip(**params) + return A.HorizontalFlip(p=1) @staticmethod def VerticalFlip(params: dict[str, Any]) -> A.BasicTransform: - return A.VerticalFlip(**params) + return A.VerticalFlip(p=1) @staticmethod - def Rotate(params: dict[str, Any]) -> A.BasicTransform: - return A.Rotate( - limit=(params["angle"], params["angle"]), - interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, - p=params["p"], + def Pad(params: dict[str, Any]) -> A.BasicTransform: + return A.Pad( + padding=params["padding"], + p=1, ) @staticmethod def Affine(params: dict[str, Any]) -> A.BasicTransform: return A.Affine( rotate=params["angle"], - translate_percent=[x / 100 for x in params["shift"]], # convert to percentage + translate_px=params["shift"], scale=params["scale"], shear=params["shear"], interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, - p=params["p"], + border_mode=cv2.BORDER_CONSTANT if params["mode"] == "constant" else cv2.BORDER_REFLECT, + p=1, ) @staticmethod - def Clahe(params: dict[str, Any]) -> A.BasicTransform: - return A.CLAHE( - clip_limit=params["clip_limit"], - tile_grid_size=params["tile_grid_size"], - p=params["p"], + def Perspective(params: dict[str, Any]) -> A.BasicTransform: + return A.Perspective( + scale=params["scale"], + interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, + p=1, ) @staticmethod - def Equalize(params: dict[str, Any]) -> A.BasicTransform: - return A.Equalize(**params) + def Elastic(params: dict[str, Any]) -> A.BasicTransform: + return A.ElasticTransform( + alpha=params["alpha"], + sigma=params["sigma"], + interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, + approximate=params["approximate"], + same_dxdy=params["same_dxdy"], + p=1, + ) @staticmethod - def RandomCrop80(params: dict[str, Any]) -> A.BasicTransform: - return A.RandomCrop( - height=params["height"], - width=params["width"], - p=params["p"], + def ColorJitter(params: dict[str, Any]) -> A.BasicTransform: + return A.ColorJitter( + brightness=params["brightness"], + contrast=params["contrast"], + saturation=params["saturation"], + hue=params["hue"], + p=1, ) @staticmethod - def RandomResizedCrop(params: dict[str, Any]) -> A.BasicTransform: - return A.RandomResizedCrop( - height=params["height"], - width=params["width"], - scale=params["scale"], - ratio=params["ratio"], - interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, - p=params["p"], - ) + def ChannelShuffle(params: dict[str, Any]) -> A.BasicTransform: + return A.ChannelShuffle(p=1) + + @staticmethod + def Grayscale(params: dict[str, Any]) -> A.BasicTransform: + return A.ToGray(p=1) @staticmethod def ShiftRGB(params: dict[str, Any]) -> A.BasicTransform: @@ -77,117 +118,119 @@ def ShiftRGB(params: dict[str, Any]) -> A.BasicTransform: r_shift_limit=shift, g_shift_limit=shift, b_shift_limit=shift, - p=params["p"], + p=1, ) @staticmethod - def Resize(params: dict[str, Any]) -> A.BasicTransform: - return A.Resize( - height=params["target_size"], - width=params["target_size"], - interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, - p=params["p"], + def GaussianBlur(params: dict[str, Any]) -> A.BasicTransform: + return A.GaussianBlur( + blur_limit=params["kernel_size"], # assuming square kernel + sigma_limit=(params["sigma"], params["sigma"]), + p=1, ) @staticmethod - def RandomGamma(params: dict[str, Any]) -> A.BasicTransform: - return A.RandomGamma( - gamma_limit=(params["gamma"], params["gamma"]), - p=params["p"], + def GaussianNoise(params: dict[str, Any]) -> A.BasicTransform: + return A.GaussNoise( + std_range=(params["std"], params["std"]), + mean_range=(params["mean"], params["mean"]), + per_channel=params["per_channel"], + p=1, ) @staticmethod - def Grayscale(params: dict[str, Any]) -> A.BasicTransform: - return A.ToGray(p=params["p"]) + def Invert(params: dict[str, Any]) -> A.BasicTransform: + return A.InvertImg(p=1) @staticmethod - def ColorJitter(params: dict[str, Any]) -> A.BasicTransform: - return A.ColorJitter( - brightness=params["brightness"], - contrast=params["contrast"], - saturation=params["saturation"], - hue=params["hue"], - p=params["p"], + def Posterize(params: dict[str, Any]) -> A.BasicTransform: + return A.Posterize( + num_bits=params["bits"], + p=1, ) @staticmethod - def PlankianJitter(params: dict[str, Any]) -> A.BasicTransform: - return A.PlanckianJitter( - mode=params["mode"], - p=params["p"], + def Solarize(params: dict[str, Any]) -> A.BasicTransform: + return A.Solarize( + threshold_range=(params["threshold"], params["threshold"]), + p=1, ) @staticmethod - def RandomPerspective(params: dict[str, Any]) -> A.BasicTransform: - return A.Perspective( - scale=params["scale"], - interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, - p=params["p"], + def Sharpen(params: dict[str, Any]) -> A.BasicTransform: + return A.Sharpen( + alpha=params["alpha"], + lightness=params["lightness"], + p=1, ) @staticmethod - def GaussianBlur(params: dict[str, Any]) -> A.BasicTransform: - return A.GaussianBlur( - blur_limit=params["kernel_size"][0], # assuming square kernel - sigma_limit=(params["sigma"], params["sigma"]), - p=params["p"], - ) + def AutoContrast(params: dict[str, Any]) -> A.BasicTransform: + return A.AutoContrast(p=1) @staticmethod - def MedianBlur(params: dict[str, Any]) -> A.BasicTransform: - return A.MedianBlur( - blur_limit=(params["blur_limit"], params["blur_limit"]), - p=params["p"], - ) + def Equalize(params: dict[str, Any]) -> A.BasicTransform: + return A.Equalize(p=1) @staticmethod - def MotionBlur(params: dict[str, Any]) -> A.BasicTransform: - return A.MotionBlur( - blur_limit=params["kernel_size"], - p=params["p"], + def Normalize(params: dict[str, Any]) -> A.BasicTransform: + return A.Normalize( + mean=params["mean"], + std=params["std"], + p=1, ) @staticmethod - def Posterize(params: dict[str, Any]) -> A.BasicTransform: - return A.Posterize( - num_bits=params["bits"], - p=params["p"], + def Erasing(params: dict[str, Any]) -> A.BasicTransform: + return A.Erasing( + scale=params["scale"], + ratio=params["ratio"], + p=1, ) @staticmethod def JpegCompression(params: dict[str, Any]) -> A.BasicTransform: return A.ImageCompression( - quality_lower=params["quality"], - quality_upper=params["quality"], - p=params["p"], + quality_range=(params["quality"], params["quality"]), + p=1, ) @staticmethod - def GaussianNoise(params: dict[str, Any]) -> A.BasicTransform: - return A.GaussNoise( - var_limit=params["var"] * 255, # convert to 0-255 range - mean=params["mean"], - per_channel=params["per_channel"], - p=params["p"], + def RandomGamma(params: dict[str, Any]) -> A.BasicTransform: + return A.RandomGamma( + gamma_limit=(params["gamma"], params["gamma"]), + p=1, ) @staticmethod - def Elastic(params: dict[str, Any]) -> A.BasicTransform: - return A.ElasticTransform( - alpha=params["alpha"], - sigma=params["sigma"], - interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, - approximate=params["approximate"], - same_dxdy=params["same_dxdy"], - p=params["p"], + def PlankianJitter(params: dict[str, Any]) -> A.BasicTransform: + return A.PlanckianJitter( + mode=params["mode"], + p=1, ) @staticmethod - def Normalize(params: dict[str, Any]) -> A.BasicTransform: - return A.Normalize( - mean=params["mean"], - std=params["std"], - p=params["p"], + def MedianBlur(params: dict[str, Any]) -> A.BasicTransform: + return A.MedianBlur( + blur_limit=(params["blur_limit"], params["blur_limit"]), + p=1, + ) + + @staticmethod + def MotionBlur(params: dict[str, Any]) -> A.BasicTransform: + return A.MotionBlur( + blur_limit=params["kernel_size"], + angle_range=params["angle_range"], + direction_range=params["direction_range"], + p=1, + ) + + @staticmethod + def CLAHE(params: dict[str, Any]) -> A.BasicTransform: + return A.CLAHE( + clip_limit=params["clip_limit"], + tile_grid_size=params["tile_grid_size"], + p=1, ) @staticmethod @@ -195,7 +238,7 @@ def Brightness(params: dict[str, Any]) -> A.BasicTransform: return A.RandomBrightnessContrast( brightness_limit=params["brightness_limit"], contrast_limit=(0.0, 0.0), - p=params["p"], + p=1, ) @staticmethod @@ -203,14 +246,7 @@ def Contrast(params: dict[str, Any]) -> A.BasicTransform: return A.RandomBrightnessContrast( brightness_limit=(0.0, 0.0), contrast_limit=params["contrast_limit"], - p=params["p"], - ) - - @staticmethod - def Solarize(params: dict[str, Any]) -> A.BasicTransform: - return A.Solarize( - threshold=params["threshold"], - p=params["p"], + p=1, ) @staticmethod @@ -219,23 +255,23 @@ def CoarseDropout(params: dict[str, Any]) -> A.BasicTransform: hole_height_range=params["hole_height_range"], hole_width_range=params["hole_width_range"], num_holes_range=params["num_holes_range"], - p=params["p"], + p=1, ) @staticmethod def Blur(params: dict[str, Any]) -> A.BasicTransform: return A.Blur( - blur_limit=params["radius"], - p=params["p"], + blur_limit=(params["radius"], params["radius"]), + p=1, ) @staticmethod def HSV(params: dict[str, Any]) -> A.BasicTransform: return A.HueSaturationValue( - hue_shift_limit=params["hue"], - sat_shift_limit=params["saturation"], - val_shift_limit=params["value"], - p=params["p"], + hue_shift_limit=params["hue"] * 255, + sat_shift_limit=params["saturation"] * 255, + val_shift_limit=params["value"] * 255, + p=1, ) @staticmethod diff --git a/benchmark/transforms/kornia_impl.py b/benchmark/transforms/kornia_impl.py index 4c54baa..7adc196 100644 --- a/benchmark/transforms/kornia_impl.py +++ b/benchmark/transforms/kornia_impl.py @@ -146,7 +146,7 @@ def Posterize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: def JpegCompression(params: dict[str, Any]) -> Kaug.AugmentationBase2D: return Kaug.RandomJPEG( jpeg_quality=params["quality"], - p=params["p"], + p=1, ) @staticmethod diff --git a/benchmark/transforms/specs.py b/benchmark/transforms/specs.py index c17bacd..2aec31b 100644 --- a/benchmark/transforms/specs.py +++ b/benchmark/transforms/specs.py @@ -17,22 +17,54 @@ def __str__(self) -> str: # Define all transform specifications based on the original implementations TRANSFORM_SPECS = [ TransformSpec( - "HorizontalFlip", + "Resize", + { + "target_size": 512, + "interpolation": "bilinear", + }, + ), + TransformSpec( + "RandomCrop128", { - "p": 1.0, + "height": 128, + "width": 128, }, ), + TransformSpec( + "RandomResizedCrop", + { + "height": 512, + "width": 512, + "scale": (0.08, 1.0), + "ratio": (0.75, 1.3333333333333333), + "interpolation": "bilinear", + }, + ), + TransformSpec( + "CenterCrop128", + { + "height": 128, + "width": 128, + }, + ), + TransformSpec( + "HorizontalFlip", + {}, + ), TransformSpec( "VerticalFlip", + {}, + ), + TransformSpec( + "Pad", { - "p": 1.0, + "padding": 10, }, ), TransformSpec( "Rotate", { "angle": 45, - "p": 1.0, "interpolation": "nearest", "mode": "reflect", # from imgaug implementation }, @@ -41,205 +73,188 @@ def __str__(self) -> str: "Affine", { "angle": 25.0, - "shift": (50, 50), + "shift": (20, 20), "scale": 2.0, "shear": [10.0, 15.0], - "p": 1.0, "interpolation": "bilinear", - "mode": "reflect", # from imgaug implementation + "mode": "constant", # from imgaug implementation }, ), TransformSpec( - "Equalize", + "Perspective", { - "p": 1.0, + "scale": (0.05, 0.1), + "interpolation": "bilinear", }, ), TransformSpec( - "RandomCrop80", + "Elastic", { - "height": 80, - "width": 80, - "p": 1.0, + "alpha": 50.0, + "sigma": 5.0, + "interpolation": "bilinear", + "approximate": False, + "same_dxdy": True, }, ), TransformSpec( - "RandomResizedCrop", + "ColorJitter", { - "height": 512, - "width": 512, - "scale": (0.08, 1.0), - "ratio": (0.75, 1.3333333333333333), - "interpolation": "bilinear", - "p": 1.0, + "brightness": 0.5, + "contrast": 1.5, + "saturation": 1.5, + "hue": 0.5, + }, + ), + TransformSpec( + "ChannelShuffle", + {}, + ), + TransformSpec( + "Grayscale", + { + "num_output_channels": 3, # from torchvision implementation }, ), TransformSpec( "ShiftRGB", { "pixel_shift": 100, - "p": 1.0, "per_channel": True, # from imgaug implementation }, ), TransformSpec( - "Resize", + "GaussianBlur", { - "target_size": 512, - "interpolation": "bilinear", - "p": 1.0, + "sigma": 2.0, + "kernel_size": (5, 5), }, ), TransformSpec( - "RandomGamma", + "GaussianNoise", { - "gamma": 120, - "p": 1.0, + "mean": 0, + "std": 0.44, + "per_channel": True, }, ), TransformSpec( - "Grayscale", - { - "p": 1.0, - "num_output_channels": 3, # from torchvision implementation - }, + "Invert", + {}, ), TransformSpec( - "ColorJitter", + "Posterize", { - "brightness": 0.5, - "contrast": 1.5, - "saturation": 1.5, - "hue": 0.5, - "p": 1.0, + "bits": 4, }, ), TransformSpec( - "PlankianJitter", + "Solarize", { - "mode": "blackbody", - "p": 1.0, + "threshold": 0.5, }, ), TransformSpec( - "RandomPerspective", + "Sharpen", { - "scale": (0.05, 0.1), - "p": 1.0, - "interpolation": "bilinear", + "alpha": [0.2, 0.5], + "lightness": [0.5, 1], }, ), TransformSpec( - "GaussianBlur", - { - "sigma": 2.0, - "kernel_size": (5, 5), - "p": 1.0, - }, + "AutoContrast", + {}, ), TransformSpec( - "MedianBlur", - { - "blur_limit": 5, - "p": 1.0, - }, + "Equalize", + {}, ), TransformSpec( - "MotionBlur", + "Normalize", { - "kernel_size": 5, - "angle": 45, - "direction": 0.0, - "p": 1.0, + "mean": (0.485, 0.456, 0.406), + "std": (0.229, 0.224, 0.225), }, ), TransformSpec( - "Posterize", + "Erasing", { - "bits": 4, - "p": 1.0, + "scale": (0.02, 0.33), + "ratio": (0.3, 3.3), + "fill": 0, }, ), TransformSpec( "JpegCompression", { "quality": 50, - "p": 1.0, }, ), TransformSpec( - "GaussianNoise", + "RandomGamma", { - "mean": 127, - "var": 0.010, - "per_channel": True, - "p": 1.0, + "gamma": 120, }, ), TransformSpec( - "Elastic", + "PlankianJitter", { - "alpha": 50.0, - "sigma": 5.0, - "interpolation": "bilinear", - "approximate": False, - "same_dxdy": True, - "p": 1.0, + "mode": "blackbody", }, ), TransformSpec( - "Normalize", + "MedianBlur", { - "mean": (0.485, 0.456, 0.406), - "std": (0.229, 0.224, 0.225), - "p": 1.0, + "blur_limit": 5, + }, + ), + TransformSpec( + "MotionBlur", + { + "kernel_size": 5, + "angle_range": (0, 360), + "direction_range": (-1, 1), }, ), TransformSpec( - "Clahe", + "CLAHE", { "clip_limit": (1, 4), "tile_grid_size": (8, 8), - "p": 1.0, }, ), TransformSpec( "Brightness", { "brightness_limit": (0.2, 0.2), - "p": 1.0, }, ), TransformSpec( "Contrast", { "contrast_limit": (0.2, 0.2), - "p": 1.0, }, ), TransformSpec( "CoarseDropout", { - "hole_height_range": (16, 16), - "hole_width_range": (16, 16), - "num_holes_range": (1, 1), - "p": 1.0, + "hole_height_range": (0.1, 0.1), + "hole_width_range": (0.1, 0.1), + "num_holes_range": (4, 4), }, ), TransformSpec( "Blur", { "radius": 5, - "p": 1.0, }, ), TransformSpec( "HSV", { - "hue": 0.015, # standard HSV adjustment values + "hue": 0.015, "saturation": 0.7, "value": 0.4, - "p": 1.0, }, ), ] diff --git a/pyproject.toml b/pyproject.toml index f1985bc..0d96502 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -102,46 +102,13 @@ format.skip-magic-trailing-comma = false # Like Black, automatically detect the appropriate line ending. lint.select = [ "ALL" ] lint.ignore = [ - "ANN101", - "ANN102", - "ANN204", - "ANN401", - "ARG001", - "ARG002", "ARG004", - "B008", - "B027", - "BLE001", - "C901", "D100", - "D101", "D102", - "D103", - "D104", "D105", - "D106", - "D107", - "D205", "D415", - "EM101", - "EM102", - "F403", - "FBT001", - "FBT002", - "FBT003", - "G004", "N802", "N812", - "PD901", - "PLR0913", - "PLR2004", - "PTH123", - "S311", - "T201", - "TCH001", - "TCH002", - "TCH003", - "TRY003", ] # Allow fix for all enabled rules (when `--fix`) is provided. diff --git a/requirements-dev.txt b/requirements-dev.txt index c363173..107ec53 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,2 +1,4 @@ +pandas pre_commit>=3.5.0 pytest>=8.3.3 +tabulate From f28973f3d48552c6ad8d687e0ce7bfb0c28feced Mon Sep 17 00:00:00 2001 From: Vladimir Iglovikov Date: Sat, 18 Jan 2025 20:19:35 -0800 Subject: [PATCH 2/5] Added torchvision --- benchmark/transforms/albumentations_impl.py | 15 ++- benchmark/transforms/specs.py | 11 +- benchmark/transforms/torchvision_impl.py | 125 +++++++++++++------- 3 files changed, 104 insertions(+), 47 deletions(-) diff --git a/benchmark/transforms/albumentations_impl.py b/benchmark/transforms/albumentations_impl.py index 0ced421..2d46e0d 100644 --- a/benchmark/transforms/albumentations_impl.py +++ b/benchmark/transforms/albumentations_impl.py @@ -59,6 +59,18 @@ def VerticalFlip(params: dict[str, Any]) -> A.BasicTransform: def Pad(params: dict[str, Any]) -> A.BasicTransform: return A.Pad( padding=params["padding"], + fill=params["fill"], + border_mode=cv2.BORDER_CONSTANT if params["border_mode"] == "constant" else cv2.BORDER_REFLECT, + p=1, + ) + + @staticmethod + def Rotate(params: dict[str, Any]) -> A.BasicTransform: + return A.Rotate( + limit=params["angle"], + interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, + border_mode=cv2.BORDER_CONSTANT if params["mode"] == "constant" else cv2.BORDER_REFLECT, + fill=params["fill"], p=1, ) @@ -71,6 +83,7 @@ def Affine(params: dict[str, Any]) -> A.BasicTransform: shear=params["shear"], interpolation=cv2.INTER_LINEAR if params["interpolation"] == "bilinear" else cv2.INTER_NEAREST, border_mode=cv2.BORDER_CONSTANT if params["mode"] == "constant" else cv2.BORDER_REFLECT, + fill=params["fill"], p=1, ) @@ -109,7 +122,7 @@ def ChannelShuffle(params: dict[str, Any]) -> A.BasicTransform: @staticmethod def Grayscale(params: dict[str, Any]) -> A.BasicTransform: - return A.ToGray(p=1) + return A.ToGray(num_output_channels=params["num_output_channels"], p=1) @staticmethod def ShiftRGB(params: dict[str, Any]) -> A.BasicTransform: diff --git a/benchmark/transforms/specs.py b/benchmark/transforms/specs.py index 2aec31b..48fc815 100644 --- a/benchmark/transforms/specs.py +++ b/benchmark/transforms/specs.py @@ -59,6 +59,8 @@ def __str__(self) -> str: "Pad", { "padding": 10, + "fill": 0, + "border_mode": "constant", }, ), TransformSpec( @@ -66,7 +68,8 @@ def __str__(self) -> str: { "angle": 45, "interpolation": "nearest", - "mode": "reflect", # from imgaug implementation + "mode": "constant", + "fill": 0, }, ), TransformSpec( @@ -77,7 +80,8 @@ def __str__(self) -> str: "scale": 2.0, "shear": [10.0, 15.0], "interpolation": "bilinear", - "mode": "constant", # from imgaug implementation + "mode": "constant", + "fill": 0, }, ), TransformSpec( @@ -85,6 +89,7 @@ def __str__(self) -> str: { "scale": (0.05, 0.1), "interpolation": "bilinear", + "fill": 0, }, ), TransformSpec( @@ -113,7 +118,7 @@ def __str__(self) -> str: TransformSpec( "Grayscale", { - "num_output_channels": 3, # from torchvision implementation + "num_output_channels": 1, }, ), TransformSpec( diff --git a/benchmark/transforms/torchvision_impl.py b/benchmark/transforms/torchvision_impl.py index b7269f6..5b11031 100644 --- a/benchmark/transforms/torchvision_impl.py +++ b/benchmark/transforms/torchvision_impl.py @@ -9,6 +9,35 @@ class TorchvisionImpl: """Torchvision implementations of transforms""" + @staticmethod + def Resize(params: dict[str, Any]) -> v2.Transform: + return v2.Resize( + size=params["target_size"], + interpolation=InterpolationMode.BILINEAR + if params["interpolation"] == "bilinear" + else InterpolationMode.NEAREST, + antialias=True, + ) + + @staticmethod + def RandomCrop128(params: dict[str, Any]) -> v2.Transform: + return v2.RandomCrop(size=(params["height"], params["width"])) + + @staticmethod + def RandomResizedCrop(params: dict[str, Any]) -> v2.Transform: + return v2.RandomResizedCrop( + size=(params["height"], params["width"]), + scale=params["scale"], + ratio=params["ratio"], + interpolation=InterpolationMode.BILINEAR + if params["interpolation"] == "bilinear" + else InterpolationMode.NEAREST, + ) + + @staticmethod + def CenterCrop128(params: dict[str, Any]) -> v2.Transform: + return v2.CenterCrop(size=(params["height"], params["width"])) + @staticmethod def HorizontalFlip(params: dict[str, Any]) -> v2.Transform: return v2.RandomHorizontalFlip(**params) @@ -17,6 +46,10 @@ def HorizontalFlip(params: dict[str, Any]) -> v2.Transform: def VerticalFlip(params: dict[str, Any]) -> v2.Transform: return v2.RandomVerticalFlip(**params) + @staticmethod + def Pad(params: dict[str, Any]) -> v2.Transform: + return v2.Pad(padding=params["padding"], fill=params["fill"], padding_mode=params["border_mode"]) + @staticmethod def Rotate(params: dict[str, Any]) -> v2.Transform: return v2.RandomRotation( @@ -24,6 +57,7 @@ def Rotate(params: dict[str, Any]) -> v2.Transform: interpolation=InterpolationMode.BILINEAR if params["interpolation"] == "bilinear" else InterpolationMode.NEAREST, + fill=params["fill"], ) @staticmethod @@ -39,38 +73,24 @@ def Affine(params: dict[str, Any]) -> v2.Transform: ) @staticmethod - def Equalize(params: dict[str, Any]) -> v2.Transform: - return v2.RandomEqualize(**params) - - @staticmethod - def RandomCrop80(params: dict[str, Any]) -> v2.Transform: - return v2.RandomCrop(size=(params["height"], params["width"])) - - @staticmethod - def RandomResizedCrop(params: dict[str, Any]) -> v2.Transform: - return v2.RandomResizedCrop( - size=(params["height"], params["width"]), - scale=params["scale"], - ratio=params["ratio"], + def Perspective(params: dict[str, Any]) -> v2.Transform: + return v2.RandomPerspective( + distortion_scale=params["scale"][1], # Using max scale interpolation=InterpolationMode.BILINEAR if params["interpolation"] == "bilinear" else InterpolationMode.NEAREST, + fill=params["fill"], + p=1, ) @staticmethod - def Resize(params: dict[str, Any]) -> v2.Transform: - return v2.Resize( - size=params["target_size"], + def Elastic(params: dict[str, Any]) -> v2.Transform: + return v2.ElasticTransform( + alpha=params["alpha"], + sigma=params["sigma"], interpolation=InterpolationMode.BILINEAR if params["interpolation"] == "bilinear" else InterpolationMode.NEAREST, - antialias=True, - ) - - @staticmethod - def Grayscale(params: dict[str, Any]) -> v2.Transform: - return v2.RandomGrayscale( - p=params["p"], ) @staticmethod @@ -83,32 +103,42 @@ def ColorJitter(params: dict[str, Any]) -> v2.Transform: ) @staticmethod - def RandomPerspective(params: dict[str, Any]) -> v2.Transform: - return v2.RandomPerspective( - distortion_scale=params["scale"][1], # Using max scale - p=params["p"], - interpolation=InterpolationMode.BILINEAR - if params["interpolation"] == "bilinear" - else InterpolationMode.NEAREST, + def ChannelShuffle(params: dict[str, Any]) -> v2.Transform: + return v2.RandomChannelPermutation() + + @staticmethod + def Grayscale(params: dict[str, Any]) -> v2.Transform: + return v2.Grayscale( + num_output_channels=params["num_output_channels"], ) @staticmethod def GaussianBlur(params: dict[str, Any]) -> v2.Transform: return v2.GaussianBlur(kernel_size=params["kernel_size"], sigma=(params["sigma"], params["sigma"])) + @staticmethod + def Invert(params: dict[str, Any]) -> v2.Transform: + return v2.RandomInvert(p=1) + @staticmethod def Posterize(params: dict[str, Any]) -> v2.Transform: - return v2.RandomPosterize(bits=params["bits"], p=params["p"]) + return v2.RandomPosterize(bits=params["bits"], p=1) @staticmethod - def Elastic(params: dict[str, Any]) -> v2.Transform: - return v2.ElasticTransform( - alpha=params["alpha"], - sigma=params["sigma"], - interpolation=InterpolationMode.BILINEAR - if params["interpolation"] == "bilinear" - else InterpolationMode.NEAREST, - ) + def Solarize(params: dict[str, Any]) -> v2.Transform: + return v2.RandomSolarize(threshold=params["threshold"], p=1) + + @staticmethod + def Sharpen(params: dict[str, Any]) -> v2.Transform: + return v2.RandomAdjustSharpness(sharpness_factor=params["lightness"][0], p=1) + + @staticmethod + def AutoContrast(params: dict[str, Any]) -> v2.Transform: + return v2.RandomAutocontrast(p=1) + + @staticmethod + def Equalize(params: dict[str, Any]) -> v2.Transform: + return v2.RandomEqualize(p=1) @staticmethod def Normalize(params: dict[str, Any]) -> v2.Transform: @@ -119,6 +149,19 @@ def Normalize(params: dict[str, Any]) -> v2.Transform: ], ) + @staticmethod + def Erasing(params: dict[str, Any]) -> v2.Transform: + return v2.RandomErasing( + scale=params["scale"], + ratio=params["ratio"], + value=params["fill"], + p=1, + ) + + @staticmethod + def JpegCompression(params: dict[str, Any]) -> v2.Transform: + return v2.JPEG(quality=params["quality"]) + @staticmethod def Brightness(params: dict[str, Any]) -> v2.Transform: return v2.ColorJitter(brightness=params["brightness_limit"], contrast=0.0, saturation=0.0, hue=0.0) @@ -127,10 +170,6 @@ def Brightness(params: dict[str, Any]) -> v2.Transform: def Contrast(params: dict[str, Any]) -> v2.Transform: return v2.ColorJitter(brightness=0.0, contrast=params["contrast_limit"], saturation=0.0, hue=0.0) - @staticmethod - def JpegCompression(params: dict[str, Any]) -> v2.Transform: - return v2.JPEG(quality=params["quality"]) - @staticmethod def __call__(transform: v2.Transform, image: torch.Tensor) -> torch.Tensor: """Apply the transform to the image""" From 1b3f0db1b080f8dc919f368f8f5d6ae165b516bc Mon Sep 17 00:00:00 2001 From: Vladimir Iglovikov Date: Thu, 30 Jan 2025 12:37:20 -0800 Subject: [PATCH 3/5] Updated benchmark --- benchmark/transforms/albumentations_impl.py | 86 +- benchmark/transforms/augly_impl.py | 28 +- benchmark/transforms/imgaug_impl.py | 41 +- benchmark/transforms/kornia_impl.py | 371 ++- benchmark/transforms/specs.py | 100 +- benchmark/transforms/torchvision_impl.py | 4 +- output/albumentations_results.json | 2403 +++++++++---------- output/augly_results.json | 912 +++---- output/comparison.md | 97 +- output/imgaug_results.json | 1696 +++++-------- output/kornia_results.json | 2092 ++++++++-------- output/torchvision_results.json | 1390 +++++------ requirements/albumentations.txt | 3 +- run_all.sh | 1 + run_single.sh | 2 +- 15 files changed, 4019 insertions(+), 5207 deletions(-) diff --git a/benchmark/transforms/albumentations_impl.py b/benchmark/transforms/albumentations_impl.py index 2d46e0d..15c7dec 100644 --- a/benchmark/transforms/albumentations_impl.py +++ b/benchmark/transforms/albumentations_impl.py @@ -26,6 +26,7 @@ def RandomCrop128(params: dict[str, Any]) -> A.BasicTransform: return A.RandomCrop( height=params["height"], width=params["width"], + pad_if_needed=True, p=1, ) @@ -44,6 +45,7 @@ def CenterCrop128(params: dict[str, Any]) -> A.BasicTransform: return A.CenterCrop( height=params["height"], width=params["width"], + pad_if_needed=True, p=1, ) @@ -125,7 +127,7 @@ def Grayscale(params: dict[str, Any]) -> A.BasicTransform: return A.ToGray(num_output_channels=params["num_output_channels"], p=1) @staticmethod - def ShiftRGB(params: dict[str, Any]) -> A.BasicTransform: + def RGBShift(params: dict[str, Any]) -> A.BasicTransform: shift = params["pixel_shift"] return A.RGBShift( r_shift_limit=shift, @@ -179,7 +181,7 @@ def Sharpen(params: dict[str, Any]) -> A.BasicTransform: @staticmethod def AutoContrast(params: dict[str, Any]) -> A.BasicTransform: - return A.AutoContrast(p=1) + return A.AutoContrast(p=1, method="pil") @staticmethod def Equalize(params: dict[str, Any]) -> A.BasicTransform: @@ -287,6 +289,86 @@ def HSV(params: dict[str, Any]) -> A.BasicTransform: p=1, ) + @staticmethod + def ChannelDropout(params: dict[str, Any]) -> A.BasicTransform: + return A.ChannelDropout(p=1) + + @staticmethod + def LinearIllumination(params: dict[str, Any]) -> A.BasicTransform: + return A.Illumination(p=1, mode="linear", angle_range=(90, 90)) + + @staticmethod + def CornerIllumination(params: dict[str, Any]) -> A.BasicTransform: + return A.Illumination(p=1, mode="corner") + + @staticmethod + def GaussianIllumination(params: dict[str, Any]) -> A.BasicTransform: + return A.Illumination(p=1, mode="gaussian") + + @staticmethod + def Hue(params: dict[str, Any]) -> A.BasicTransform: + return A.HueSaturationValue( + hue_shift_limit=params["hue"], + sat_shift_limit=0, + val_shift_limit=0, + p=1, + ) + + @staticmethod + def PlasmaBrightness(params: dict[str, Any]) -> A.BasicTransform: + return A.PlasmaBrightnessContrast(p=1, roughness=params["roughness"], contrast_range=(0.0, 0.0)) + + @staticmethod + def PlasmaContrast(params: dict[str, Any]) -> A.BasicTransform: + return A.PlasmaBrightnessContrast(p=1, roughness=params["roughness"], brightness_range=(0.0, 0.0)) + + @staticmethod + def PlasmaShadow(params: dict[str, Any]) -> A.BasicTransform: + return A.PlasmaShadow(p=1, roughness=params["roughness"]) + + @staticmethod + def Rain(params: dict[str, Any]) -> A.BasicTransform: + return A.RandomRain( + p=1, + drop_width=params["drop_width"], + brightness_coefficient=params["brightness_coefficient"], + ) + + @staticmethod + def SaltAndPepper(params: dict[str, Any]) -> A.BasicTransform: + return A.SaltAndPepper(p=1, amount=params["amount"], salt_vs_pepper=params["salt_vs_pepper"]) + + @staticmethod + def Saturation(params: dict[str, Any]) -> A.BasicTransform: + sat_shift_limit = params["saturation_factor"] * 255 + return A.HueSaturationValue(p=1, hue_shift_limit=0, sat_shift_limit=sat_shift_limit, val_shift_limit=0) + + @staticmethod + def Snow(params: dict[str, Any]) -> A.BasicTransform: + return A.RandomSnow(p=1, snow_point_range=params["snow_point_range"]) + + @staticmethod + def OpticalDistortion(params: dict[str, Any]) -> A.BasicTransform: + return A.OpticalDistortion(p=1, distort_limit=params["distort_limit"]) + + @staticmethod + def Shear(params: dict[str, Any]) -> A.BasicTransform: + return A.Affine( + p=1, + shear=params["shear"], + interpolation=cv2.INTER_LINEAR, + border_mode=cv2.BORDER_CONSTANT, + fill=0, + ) + + @staticmethod + def ThinPlateSpline(params: dict[str, Any]) -> A.BasicTransform: + return A.ThinPlateSpline( + p=1, + num_control_points=params["num_control_points"], + scale_range=(params["distortion_scale"], params["distortion_scale"]), + ) + @staticmethod def __call__(transform: A.BasicTransform, image: np.ndarray) -> np.ndarray: """Apply the transform to the image""" diff --git a/benchmark/transforms/augly_impl.py b/benchmark/transforms/augly_impl.py index 4baee26..fecca06 100644 --- a/benchmark/transforms/augly_impl.py +++ b/benchmark/transforms/augly_impl.py @@ -13,11 +13,11 @@ class AuglyImpl: @staticmethod def HorizontalFlip(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: - return imaugs.HFlip(p=params["p"]) + return imaugs.HFlip(p=1) @staticmethod def VerticalFlip(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: - return imaugs.VFlip(p=params["p"]) + return imaugs.VFlip(p=1) @staticmethod def Rotate(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: @@ -25,11 +25,11 @@ def Rotate(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.RandomRotation( min_degrees=params["angle"], max_degrees=params["angle"], - p=params["p"], + p=1, ) @staticmethod - def RandomCrop80(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: + def RandomCrop128(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: # Augly uses relative coordinates (0-1) # Using fixed values as augly's crop works differently return imaugs.Crop( @@ -37,7 +37,7 @@ def RandomCrop80(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: y1=0.25, x2=0.75, y2=0.75, - p=params["p"], + p=1, ) @staticmethod @@ -46,12 +46,12 @@ def Resize(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: width=params["target_size"], height=params["target_size"], resample=Image.BILINEAR if params["interpolation"] == "bilinear" else Image.NEAREST, - p=params["p"], + p=1, ) @staticmethod def Grayscale(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: - return imaugs.Grayscale(p=params["p"]) + return imaugs.Grayscale(p=1) @staticmethod def ColorJitter(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: @@ -59,21 +59,21 @@ def ColorJitter(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: brightness_factor=params["brightness"], contrast_factor=params["contrast"], saturation_factor=params["saturation"], - p=params["p"], + p=1, ) @staticmethod def GaussianBlur(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.Blur( radius=params["sigma"], - p=params["p"], + p=1, ) @staticmethod def JpegCompression(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.EncodingQuality( quality=params["quality"], - p=params["p"], + p=1, ) @staticmethod @@ -81,14 +81,14 @@ def GaussianNoise(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.RandomNoise( mean=params["mean"], var=params["var"], - p=params["p"], + p=1, ) @staticmethod def Blur(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.Blur( radius=params["radius"], - p=params["p"], + p=1, ) @staticmethod @@ -96,14 +96,14 @@ def Brightness(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.RandomBrightness( min_factor=params["brightness_limit"][0], max_factor=params["brightness_limit"][1], - p=params["p"], + p=1, ) @staticmethod def Contrast(params: dict[str, Any]) -> imaugs.transforms.BaseTransform: return imaugs.Contrast( factor=params["contrast_limit"][0], - p=params["p"], + p=1, ) @staticmethod diff --git a/benchmark/transforms/imgaug_impl.py b/benchmark/transforms/imgaug_impl.py index d4b4448..2f020ec 100644 --- a/benchmark/transforms/imgaug_impl.py +++ b/benchmark/transforms/imgaug_impl.py @@ -15,11 +15,11 @@ class ImgaugImpl: @staticmethod def HorizontalFlip(params: dict[str, Any]) -> iaa.Augmenter: - return iaa.Fliplr(p=params["p"]) + return iaa.Fliplr(p=1) @staticmethod def VerticalFlip(params: dict[str, Any]) -> iaa.Augmenter: - return iaa.Flipud(p=params["p"]) + return iaa.Flipud(p=1) @staticmethod def Rotate(params: dict[str, Any]) -> iaa.Augmenter: @@ -44,7 +44,7 @@ def Equalize(params: dict[str, Any]) -> iaa.Augmenter: return iaa.AllChannelsHistogramEqualization() @staticmethod - def RandomCrop80(params: dict[str, Any]) -> iaa.Augmenter: + def RandomCrop128(params: dict[str, Any]) -> iaa.Augmenter: return iaa.CropToFixedSize(width=params["width"], height=params["height"]) @staticmethod @@ -70,7 +70,7 @@ def Grayscale(params: dict[str, Any]) -> iaa.Augmenter: return iaa.Grayscale(alpha=1.0) @staticmethod - def RandomPerspective(params: dict[str, Any]) -> iaa.Augmenter: + def Perspective(params: dict[str, Any]) -> iaa.Augmenter: return iaa.PerspectiveTransform( scale=params["scale"], mode=params.get("mode", "replicate"), @@ -87,7 +87,7 @@ def MedianBlur(params: dict[str, Any]) -> iaa.Augmenter: @staticmethod def MotionBlur(params: dict[str, Any]) -> iaa.Augmenter: - return iaa.MotionBlur(k=params["kernel_size"], angle=[params["angle"]], direction=params["direction"]) + return iaa.MotionBlur(k=params["kernel_size"], angle=params["angle_range"]) @staticmethod def Posterize(params: dict[str, Any]) -> iaa.Augmenter: @@ -101,7 +101,7 @@ def JpegCompression(params: dict[str, Any]) -> iaa.Augmenter: def GaussianNoise(params: dict[str, Any]) -> iaa.Augmenter: return iaa.AdditiveGaussianNoise( loc=params["mean"], - scale=(0, params["var"]), + scale=(0, params["std"]), per_channel=params["per_channel"], ) @@ -114,7 +114,7 @@ def Elastic(params: dict[str, Any]) -> iaa.Augmenter: ) @staticmethod - def Clahe(params: dict[str, Any]) -> iaa.Augmenter: + def CLAHE(params: dict[str, Any]) -> iaa.Augmenter: return iaa.AllChannelsCLAHE(clip_limit=params["clip_limit"], tile_grid_size_px=params["tile_grid_size"]) @staticmethod @@ -133,6 +133,33 @@ def Brightness(params: dict[str, Any]) -> iaa.Augmenter: def Contrast(params: dict[str, Any]) -> iaa.Augmenter: return iaa.AddToHueAndSaturation(value=int(params["contrast_limit"][0] * 100)) + @staticmethod + def Invert(params: dict[str, Any]) -> iaa.Augmenter: + return iaa.Invert(1.0) + + @staticmethod + def Sharpen(params: dict[str, Any]) -> iaa.Augmenter: + return iaa.Sharpen( + alpha=(params["alpha"][0], params["alpha"][1]), + lightness=(params["lightness"][0], params["lightness"][1]), + ) + + @staticmethod + def Solarize(params: dict[str, Any]) -> iaa.Augmenter: + return iaa.Solarize(threshold=params["threshold"] * 255) # Convert from [0,1] to [0,255] + + @staticmethod + def ChannelShuffle(params: dict[str, Any]) -> iaa.Augmenter: + return iaa.ChannelShuffle(1.0) + + @staticmethod + def Saturation(params: dict[str, Any]) -> iaa.Augmenter: + return iaa.MultiplySaturation(mul=params["saturation_factor"]) + + @staticmethod + def Shear(params: dict[str, Any]) -> iaa.Augmenter: + return iaa.ShearX(shear=params["shear"]) + @staticmethod def __call__(transform: iaa.Augmenter, image: np.ndarray) -> np.ndarray: """Apply the transform to the image""" diff --git a/benchmark/transforms/kornia_impl.py b/benchmark/transforms/kornia_impl.py index 7adc196..3a30865 100644 --- a/benchmark/transforms/kornia_impl.py +++ b/benchmark/transforms/kornia_impl.py @@ -1,5 +1,6 @@ from typing import Any +import kornia import kornia.augmentation as Kaug import torch @@ -10,205 +11,347 @@ class KorniaImpl: """Kornia implementations of transforms""" @staticmethod - def HorizontalFlip(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomHorizontalFlip(**params) + def ColorJitter(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.ColorJitter( + brightness=params["brightness"], + contrast=params["contrast"], + saturation=params["saturation"], + hue=params["hue"], + p=1, + ) @staticmethod - def VerticalFlip(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomVerticalFlip(**params) + def AutoContrast(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomAutoContrast(p=1) @staticmethod - def Rotate(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - # Convert degrees to radians for rotation - angle = torch.tensor(params["angle"]) * (torch.pi / 180.0) - return Kaug.RandomRotation( - degrees=angle, - resample="bilinear", - p=params["p"], + def Blur(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomBoxBlur( + p=1, + kernel_size=(params["radius"], params["radius"]), + border_type=params["border_mode"], ) @staticmethod - def Affine(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomAffine( - degrees=params["angle"], - translate=0.1, - scale=[params["scale"], params["scale"]], - shear=params["shear"], - p=params["p"], + def Brightness(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomBrightness( + brightness=params["brightness_limit"], + p=1, ) @staticmethod - def Clahe(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomClahe( - clip_limit=params["clip_limit"], - grid_size=params["tile_grid_size"], - p=params["p"], - ) + def ChannelDropout(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomChannelDropout(p=1) @staticmethod - def Equalize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomEqualize(**params) + def ChannelShuffle(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomChannelShuffle(p=1) @staticmethod - def RandomCrop80(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomCrop( - size=(params["height"], params["width"]), - p=params["p"], - ) + def CLAHE(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomClahe(p=1, clip_limit=params["clip_limit"], grid_size=params["tile_grid_size"]) @staticmethod - def RandomResizedCrop(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomResizedCrop( - size=(params["height"], params["width"]), - scale=params["scale"], - ratio=params["ratio"], - p=params["p"], + def Contrast(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomContrast( + contrast=params["contrast_limit"], + p=1, ) @staticmethod - def Resize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.Resize( - size=(params["target_size"], params["target_size"]), - p=params["p"], - ) + def Equalize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomEqualize(p=1) @staticmethod def RandomGamma(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - gamma = params["gamma"] / 100 # Convert to kornia scale + gamma = params["gamma"] / 100 return Kaug.RandomGamma( gamma=(gamma, gamma), - p=params["p"], + p=1, ) @staticmethod - def Grayscale(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomGrayscale(p=params["p"]) + def GaussianBlur(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomGaussianBlur( + kernel_size=params["kernel_size"], + sigma=(params["sigma"], params["sigma"]), + p=1, + ) @staticmethod - def ColorJitter(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.ColorJitter( - brightness=params["brightness"], - contrast=params["contrast"], - saturation=params["saturation"], - hue=params["hue"], - p=params["p"], + def LinearIllumination(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomLinearIllumination( + gain=params["gain"], + p=1, ) @staticmethod - def PlankianJitter(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomPlanckianJitter( - mode=params["mode"], - p=params["p"], + def CornerIllumination(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomLinearCornerIllumination( + gain=params["gain"], + p=1, ) @staticmethod - def RandomPerspective(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomPerspective( - distortion_scale=params["scale"][1], # Using max scale - p=params["p"], + def GaussianIllumination(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomGaussianIllumination( + gain=params["gain"], + p=1, ) @staticmethod - def GaussianBlur(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomGaussianBlur( - kernel_size=params["kernel_size"], - sigma=(params["sigma"], params["sigma"]), - p=params["p"], + def GaussianNoise(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomGaussianNoise( + mean=params["mean"], + std=params["std"], + p=1, + ) + + @staticmethod + def Grayscale(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomGrayscale(p=1) + + @staticmethod + def Hue(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomHue( + hue=params["hue"], + p=1, + ) + + @staticmethod + def Invert(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomInvert(p=1) + + @staticmethod + def JpegCompression(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomJPEG( + jpeg_quality=params["quality"], + p=1, ) @staticmethod def MedianBlur(params: dict[str, Any]) -> Kaug.AugmentationBase2D: kernel_size = params["blur_limit"] - if kernel_size % 2 == 0: - kernel_size += 1 # Ensure odd kernel size return Kaug.RandomMedianBlur( kernel_size=(kernel_size, kernel_size), - p=params["p"], + p=1, ) @staticmethod def MotionBlur(params: dict[str, Any]) -> Kaug.AugmentationBase2D: return Kaug.RandomMotionBlur( kernel_size=params["kernel_size"], - angle=params["angle"], - direction=params["direction"], - p=params["p"], + angle=params["angle_range"], + direction=params["direction_range"], + p=1, ) @staticmethod - def Posterize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomPosterize( - bits=params["bits"], - p=params["p"], + def PlankianJitter(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomPlanckianJitter( + mode=params["mode"], + p=1, ) @staticmethod - def JpegCompression(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomJPEG( - jpeg_quality=params["quality"], + def PlasmaBrightness(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomPlasmaBrightness( + roughness=(params["roughness"], params["roughness"]), p=1, ) @staticmethod - def Elastic(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - sigma = torch.tensor([params["sigma"], params["sigma"]]).float() - alpha = torch.tensor([params["alpha"], params["alpha"]]).float() - return Kaug.RandomElasticTransform( - alpha=alpha, - sigma=sigma, - p=params["p"], + def PlasmaContrast(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomPlasmaContrast( + roughness=(params["roughness"], params["roughness"]), + p=1, ) @staticmethod - def Normalize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.Normalize( - mean=params["mean"], - std=params["std"], - p=params["p"], + def PlasmaShadow(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomPlasmaShadow( + roughness=(params["roughness"], params["roughness"]), + p=1, ) @staticmethod - def Brightness(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomBrightness( - brightness=params["brightness_limit"], - p=params["p"], + def Rain(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomRain( + drop_width=(params["drop_width"], params["drop_width"]), + drop_height=(params["drop_height"], params["drop_height"]), + p=1, ) @staticmethod - def Contrast(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomContrast( - contrast=params["contrast_limit"], - p=params["p"], + def RGBShift(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomRGBShift( + r_shift_limit=params["pixel_shift"] / 255.0, + g_shift_limit=params["pixel_shift"] / 255.0, + b_shift_limit=params["pixel_shift"] / 255.0, + p=1, ) @staticmethod - def GaussianNoise(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomGaussianNoise( - mean=params["mean"], - std=params["var"], - p=params["p"], + def SaltAndPepper(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomSaltAndPepperNoise( + amount=params["amount"], + salt_vs_pepper=params["salt_vs_pepper"], + p=1, ) @staticmethod - def RGBShift(params: dict[str, Any]) -> Kaug.AugmentationBase2D: - return Kaug.RandomRGBShift( - r_shift_limit=params["r_shift_limit"] / 255.0, - g_shift_limit=params["g_shift_limit"] / 255.0, - b_shift_limit=params["b_shift_limit"] / 255.0, - p=params["p"], + def Saturation(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomSaturation( + saturation=params["saturation_factor"], + p=1, + ) + + @staticmethod + def Sharpen(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomSharpness( + p=1, + ) + + @staticmethod + def Snow(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomSnow( + snow_coefficient=params["snow_point_range"], + p=1, ) @staticmethod def Solarize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: return Kaug.RandomSolarize( - threshold=params["threshold"] / 255.0, - p=params["p"], + thresholds=params["threshold"], + p=1, + ) + + @staticmethod + def CenterCrop128(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.CenterCrop( + size=(params["height"], params["width"]), + pad_if_needed=True, + p=1, ) @staticmethod - def CoarseDropout(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + def Affine(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomAffine( + degrees=params["angle"], + translate=params["shift"][0] / 255.0, + scale=(params["scale"], params["scale"]), + shear=params["shear"], + p=1, + ) + + @staticmethod + def RandomCrop128(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomCrop( + size=(params["height"], params["width"]), + pad_if_needed=True, + p=1, + ) + + @staticmethod + def Elastic(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomElasticTransform( + alpha=(params["alpha"], params["alpha"]), + sigma=(params["sigma"], params["sigma"]), + p=1, + ) + + @staticmethod + def Erasing(params: dict[str, Any]) -> Kaug.AugmentationBase2D: return Kaug.RandomErasing( - p=params["p"], + p=1, + scale=params["scale"], + ratio=params["ratio"], + value=params["fill"], + ) + + @staticmethod + def OpticalDistortion(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return kornia.augmentation.RandomFisheye( + center_x=torch.tensor([-0.3, 0.3]), + center_y=torch.tensor([-0.3, 0.3]), + gamma=torch.tensor([0.9, 1.1]), + p=1, + ) + + @staticmethod + def HorizontalFlip(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomHorizontalFlip(p=1) + + @staticmethod + def Perspective(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomPerspective( + distortion_scale=params["scale"][1], + resample=params["interpolation"], + p=1, + ) + + @staticmethod + def RandomResizedCrop(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomResizedCrop( + size=(params["height"], params["width"]), + scale=params["scale"], + ratio=params["ratio"], + p=1, + ) + + @staticmethod + def RandomRotate90(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomRotation90( + times=(0, 3), + p=1, + ) + + @staticmethod + def Rotate(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + # Convert degrees to radians for rotation + angle = torch.tensor(params["angle"]) * (torch.pi / 180.0) + return kornia.geometry.transform.Rotate( + angle=angle, + mode="bilinear", + ) + + @staticmethod + def Shear(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomShear( + shear=params["shear"], + p=1, + ) + + @staticmethod + def ThinPlateSpline(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomThinPlateSpline( + p=1, + ) + + @staticmethod + def VerticalFlip(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomVerticalFlip(p=1) + + @staticmethod + def Resize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.Resize( + size=(params["target_size"], params["target_size"]), + p=1, + ) + + @staticmethod + def Normalize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.Normalize( + mean=params["mean"], + std=params["std"], + p=1, + ) + + @staticmethod + def Posterize(params: dict[str, Any]) -> Kaug.AugmentationBase2D: + return Kaug.RandomPosterize( + bits=params["bits"], + p=1, ) @staticmethod diff --git a/benchmark/transforms/specs.py b/benchmark/transforms/specs.py index 48fc815..a5d7f53 100644 --- a/benchmark/transforms/specs.py +++ b/benchmark/transforms/specs.py @@ -78,7 +78,7 @@ def __str__(self) -> str: "angle": 25.0, "shift": (20, 20), "scale": 2.0, - "shear": [10.0, 15.0], + "shear": (10.0, 15.0), "interpolation": "bilinear", "mode": "constant", "fill": 0, @@ -122,10 +122,9 @@ def __str__(self) -> str: }, ), TransformSpec( - "ShiftRGB", + "RGBShift", { "pixel_shift": 100, - "per_channel": True, # from imgaug implementation }, ), TransformSpec( @@ -162,8 +161,8 @@ def __str__(self) -> str: TransformSpec( "Sharpen", { - "alpha": [0.2, 0.5], - "lightness": [0.5, 1], + "alpha": (0.2, 0.5), + "lightness": (0.5, 1), }, ), TransformSpec( @@ -252,6 +251,7 @@ def __str__(self) -> str: "Blur", { "radius": 5, + "border_mode": "constant", }, ), TransformSpec( @@ -262,4 +262,94 @@ def __str__(self) -> str: "value": 0.4, }, ), + TransformSpec( + "ChannelDropout", + {}, + ), + TransformSpec( + "LinearIllumination", + { + "gain": (0.01, 0.2), + }, + ), + TransformSpec( + "CornerIllumination", + { + "gain": (0.01, 0.2), + }, + ), + TransformSpec( + "GaussianIllumination", + { + "gain": (0.01, 0.2), + }, + ), + TransformSpec( + "Hue", + { + "hue": 20, + }, + ), + TransformSpec( + "PlasmaBrightness", + { + "roughness": 0.5, + }, + ), + TransformSpec( + "PlasmaContrast", + { + "roughness": 0.5, + }, + ), + TransformSpec( + "PlasmaShadow", + { + "roughness": 0.5, + }, + ), + TransformSpec( + "Rain", + { + "drop_width": 5, + "drop_height": 20, + "brightness_coefficient": 1.0, + }, + ), + TransformSpec( + "SaltAndPepper", + { + "amount": (0.01, 0.06), + "salt_vs_pepper": (0.4, 0.6), + }, + ), + TransformSpec( + "Saturation", + { + "saturation_factor": 0.5, + }, + ), + TransformSpec( + "Snow", + {"snow_point_range": (0.5, 0.5)}, + ), + TransformSpec( + "OpticalDistortion", + { + "distort_limit": 0.5, + }, + ), + TransformSpec( + "Shear", + { + "shear": 10, + }, + ), + TransformSpec( + "ThinPlateSpline", + { + "num_control_points": 2, + "distortion_scale": 0.5, + }, + ), ] diff --git a/benchmark/transforms/torchvision_impl.py b/benchmark/transforms/torchvision_impl.py index 5b11031..bc5408e 100644 --- a/benchmark/transforms/torchvision_impl.py +++ b/benchmark/transforms/torchvision_impl.py @@ -21,7 +21,7 @@ def Resize(params: dict[str, Any]) -> v2.Transform: @staticmethod def RandomCrop128(params: dict[str, Any]) -> v2.Transform: - return v2.RandomCrop(size=(params["height"], params["width"])) + return v2.RandomCrop(size=(params["height"], params["width"]), pad_if_needed=True) @staticmethod def RandomResizedCrop(params: dict[str, Any]) -> v2.Transform: @@ -36,7 +36,7 @@ def RandomResizedCrop(params: dict[str, Any]) -> v2.Transform: @staticmethod def CenterCrop128(params: dict[str, Any]) -> v2.Transform: - return v2.CenterCrop(size=(params["height"], params["width"])) + return v2.CenterCrop(size=(params["height"], params["width"]), pad_if_needed=True) @staticmethod def HorizontalFlip(params: dict[str, Any]) -> v2.Transform: diff --git a/output/albumentations_results.json b/output/albumentations_results.json index 1ccd668..97a8f5d 100644 --- a/output/albumentations_results.json +++ b/output/albumentations_results.json @@ -2,16 +2,16 @@ "metadata": { "system_info": { "python_version": "3.12.7 | packaged by Anaconda, Inc. | (main, Oct 4 2024, 08:22:19) [Clang 14.0.6 ]", - "platform": "macOS-15.0.1-arm64-arm-64bit", + "platform": "macOS-15.1-arm64-arm-64bit", "processor": "arm", - "cpu_count": "10", - "timestamp": "2024-11-02T16:32:47.141362+00:00" + "cpu_count": "16", + "timestamp": "2025-01-30T20:22:09.348864+00:00" }, "library_versions": { - "albumentations": "1.4.21", - "numpy": "2.1.2", + "albumentations": "2.0.2", + "numpy": "2.2.2", "pillow": "not installed", - "opencv-python-headless": "4.10.0.84", + "opencv-python-headless": "4.11.0.86", "torch": "not installed", "opencv-python": "not installed" }, @@ -22,8 +22,8 @@ "pillow": "not installed" }, "benchmark_params": { - "num_images": 1000, - "num_runs": 20, + "num_images": 2000, + "num_runs": 5, "max_warmup_iterations": 1000, "warmup_window": 5, "warmup_threshold": 0.05, @@ -31,1542 +31,1277 @@ } }, "results": { - "HorizontalFlip(p=1.0)": { + "Resize(target_size=512, interpolation=bilinear)": { "supported": true, - "warmup_iterations": 22, + "warmup_iterations": 16, "throughputs": [ - 6191.0368383479, - 8989.17817144948, - 9276.613493562785, - 9176.64818182935, - 8504.79959198037, - 8814.931613681078, - 8997.856294170122, - 9164.740831617348, - 8366.549640894533, - 8602.770303815185, - 8573.75574343702, - 5908.978104345355, - 7628.628177877575, - 8851.49293312135, - 8260.605592434487, - 8506.06558490302, - 8640.447234080848, - 8712.527945417964, - 8443.060911203735, - 8740.249650211324 - ], - "median_throughput": 8621.608768948015, - "std_throughput": 891.4153861608924, + 3553.596075899863, + 3662.321732957875, + 3662.3717494372027, + 3636.26804792736, + 3696.2820487058552 + ], + "median_throughput": 3662.321732957875, + "std_throughput": 53.90382612587518, "times": [ - 0.16152383293956518, - 0.11124487477354705, - 0.1077979588881135, - 0.10897225001826882, - 0.11758066597394645, - 0.11344387498684227, - 0.1111375829204917, - 0.10911383293569088, - 0.11952358414418995, - 0.11624162504449487, - 0.11663499986752868, - 0.16923399991355836, - 0.1310851671732962, - 0.11297529214061797, - 0.1210564998909831, - 0.11756316595710814, - 0.11573474993929267, - 0.11477725021541119, - 0.1184404578525573, - 0.11441320786252618 - ], - "mean_time": 0.11598763372349326, - "std_time": 0.011992328123018233, + 0.5628101667389274, + 0.5461016660556197, + 0.5460942080244422, + 0.5500144581310451, + 0.5410842499695718 + ], + "mean_time": 0.5461016660556197, + "std_time": 0.008037788976649547, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "VerticalFlip(p=1.0)": { + "RandomCrop128(height=128, width=128)": { "supported": true, - "warmup_iterations": 23, + "warmup_iterations": 49, "throughputs": [ - 25450.500523902097, - 15235.686553234325, - 19592.28449323103, - 16463.94286067498, - 17688.327079731087, - 21231.385104191973, - 28214.216390682122, - 28164.18722225359, - 28444.27622199942, - 28213.320841864315, - 22169.180191668605, - 26754.95809434625, - 22563.728273715755, - 25338.853977149254, - 16233.35988947292, - 16985.090081753795, - 16545.77907143256, - 26390.96901660055, - 28418.139470290185, - 28479.88611459973 - ], - "median_throughput": 23951.291125432504, - "std_throughput": 5013.1234416187, + 114589.92119675157, + 113189.92607785038, + 116783.77207114537, + 118381.13287499962, + 117933.79451152535 + ], + "median_throughput": 116783.77207114537, + "std_throughput": 2222.2804980399987, "times": [ - 0.03929195809178054, - 0.06563537498004735, - 0.05104050016961992, - 0.06073879194445908, - 0.05653445888310671, - 0.04710008297115564, - 0.03544312505982816, - 0.035506084095686674, - 0.03515645791776478, - 0.0354442500974983, - 0.04510766710154712, - 0.037376249907538295, - 0.04431891697458923, - 0.03946508397348225, - 0.06160154193639755, - 0.058875166112557054, - 0.06043837498873472, - 0.03789174999110401, - 0.03518879204057157, - 0.03511249995790422 - ], - "mean_time": 0.04175140265979888, - "std_time": 0.008738774636330571, + 0.017453541979193687, + 0.017669416964054108, + 0.017125667072832584, + 0.01689458405598998, + 0.016958667431026697 + ], + "mean_time": 0.017125667072832584, + "std_time": 0.0003258846265789088, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Rotate(angle=45, p=1.0, interpolation=nearest, mode=reflect)": { + "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 1224.659498711691, - 925.5676610460062, - 1028.4793650614777, - 1145.3959948722618, - 1144.689463765791, - 1275.445808616896, - 1222.351677571119, - 1182.0383951088374, - 1188.864029951023, - 1212.4129260847935, - 1105.5954683764269, - 1182.086891718114, - 1099.3165138344302, - 1171.1202908547898, - 1126.95712012375, - 1154.0652039106371, - 1233.1308336781117, - 1261.9378009597665, - 1143.8297798650628, - 1049.619492441156 - ], - "median_throughput": 1162.5927473827135, - "std_throughput": 83.97439082897809, + 4520.655583117836, + 4523.842498330771, + 4520.155370510317, + 4539.538107369352, + 4491.518470892838 + ], + "median_throughput": 4520.655583117836, + "std_throughput": 17.35275982631806, "times": [ - 0.8165535000152886, - 1.0804180419072509, - 0.9723092499189079, - 0.873060500016436, - 0.8735993748996407, - 0.7840395830571651, - 0.8180951671674848, - 0.8459962080232799, - 0.8411390830297023, - 0.8248014999553561, - 0.9044899591244757, - 0.8459614999592304, - 0.909656124887988, - 0.8538832499179989, - 0.8873452078551054, - 0.8665021669585258, - 0.8109439588151872, - 0.7924320828169584, - 0.8742559580132365, - 0.9527262090705335 - ], - "mean_time": 0.8601464289634093, - "std_time": 0.06212861086440763, + 0.4424137081950903, + 0.44210204062983394, + 0.44246266689151525, + 0.44057345762848854, + 0.44528370816260576 + ], + "mean_time": 0.4424137081950903, + "std_time": 0.0016982268790504433, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Affine(angle=25.0, shift=(50, 50), scale=2.0, shear=[10.0, 15.0], p=1.0, interpolation=bilinear, mode=reflect)": { + "CenterCrop128(height=128, width=128)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 767.8801371793144, - 954.1601583265846, - 959.8633541801396, - 879.1481231602052, - 865.7219134553635, - 871.5048211066207, - 853.066357729375, - 916.779249100759, - 890.5174798411235, - 914.1291460276772, - 922.067614219473, - 855.9323547670981, - 935.5347190950275, - 973.5721011183113, - 939.6571736845588, - 908.8733644922522, - 904.2349276012876, - 942.9924157398925, - 889.3428158634232, - 833.122102166982 - ], - "median_throughput": 906.5541460467699, - "std_throughput": 49.392463173731926, + 119630.04082214735, + 113651.69995130008, + 118396.02993449329, + 121280.11146898978, + 122754.30214948278 + ], + "median_throughput": 119630.04082214735, + "std_throughput": 3484.189156970239, "times": [ - 1.3022865829989314, - 1.048042083159089, - 1.041814957978204, - 1.137464749859646, - 1.1551053340081125, - 1.1474405829794705, - 1.17224174994044, - 1.0907751249615103, - 1.1229425841011107, - 1.0939373329747468, - 1.084519166033715, - 1.168316625058651, - 1.0689074168913066, - 1.027145291911438, - 1.0642179169226438, - 1.1002632919698954, - 1.1059072918724269, - 1.0604539159685373, - 1.1244257919024676, - 1.2003042500000447 - ], - "mean_time": 1.1030780724579126, - "std_time": 0.060099822287744284, + 0.01671820878982544, + 0.0175976250320673, + 0.01689245831221342, + 0.016490750014781952, + 0.01629270799458027 + ], + "mean_time": 0.01671820878982544, + "std_time": 0.0004869128304994318, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Equalize(p=1.0)": { + "HorizontalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 656.1069890598561, - 894.444682417597, - 943.3949287652506, - 829.5352425719353, - 890.8705476203851, - 958.7345474785478, - 972.6955838735715, - 936.1477412648642, - 753.3556584583569, - 781.4194349413702, - 788.5526076882933, - 705.3965423196645, - 837.4617287483161, - 940.8948291052218, - 811.652269698058, - 782.7063898166542, - 919.9808690588578, - 943.3711958703406, - 867.2434558285287, - 799.7756361058232 - ], - "median_throughput": 852.3525922884223, - "std_throughput": 90.10339032498943, + 12245.578970193195, + 12531.949993153039, + 12873.012258021381, + 12741.663571857667, + 12648.687919376773 + ], + "median_throughput": 12648.687919376773, + "std_throughput": 238.16244515405927, "times": [ - 1.52414166694507, - 1.1180121249053627, - 1.06000145804137, - 1.2054942920804024, - 1.1224975420627743, - 1.0430415829177946, - 1.0280708749778569, - 1.0682074590586126, - 1.3273942908272147, - 1.2797224579844624, - 1.2681462089531124, - 1.4176423330791295, - 1.194084416842088, - 1.0628180420026183, - 1.2320547078270465, - 1.2776182908564806, - 1.0869791249278933, - 1.0600281250663102, - 1.1530787500087172, - 1.250350666930899 - ], - "mean_time": 1.1732233925811961, - "std_time": 0.12402309353730552, + 0.16332424990832806, + 0.15959208272397518, + 0.15536379208788276, + 0.15696537494659424, + 0.158119167201221 + ], + "mean_time": 0.158119167201221, + "std_time": 0.0029772295534841384, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomCrop80(height=80, width=80, p=1.0)": { + "VerticalFlip()": { "supported": true, - "warmup_iterations": 17, + "warmup_iterations": 16, + "throughputs": [ + 24590.856960445824, + 24989.210315740933, + 25608.08543862018, + 26850.292575081134, + 24849.27352118374 + ], + "median_throughput": 24989.210315740933, + "std_throughput": 904.2796812443848, + "times": [ + 0.08133104117587209, + 0.08003454189747572, + 0.07810033299028873, + 0.07448708405718207, + 0.08048525033518672 + ], + "mean_time": 0.08003454189747572, + "std_time": 0.0028961943623324864, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Pad(padding=10, fill=0, border_mode=constant)": { + "supported": true, + "warmup_iterations": 16, "throughputs": [ - 111235.74519905329, - 112063.1248691989, - 112244.99503073642, - 112161.06231828366, - 106456.59310282435, - 101694.48442800525, - 107588.10251393101, - 108129.05566664638, - 106197.04392157738, - 105580.35371383996, - 106081.09888901, - 103494.22279764967, - 107940.839424728, - 105434.26053836347, - 110361.57079603495, - 109533.52354482458, - 109873.50804965799, - 101080.29406658393, - 101993.11005767297, - 111828.67934583552 - ], - "median_throughput": 107764.4709693295, - "std_throughput": 3629.5897566970975, + 31866.39463811293, + 32295.395501748768, + 32591.04924142105, + 31337.197252552513, + 31484.61796464257 + ], + "median_throughput": 31866.39463811293, + "std_throughput": 529.9034070556334, "times": [ - 0.008989915950223804, - 0.00892354198731482, - 0.008909083204343915, - 0.0089157500769943, - 0.009393499931320548, - 0.009833374992012978, - 0.009294708026573062, - 0.009248208021745086, - 0.009416457964107394, - 0.00947145908139646, - 0.00942675000987947, - 0.009662375086918473, - 0.009264334104955196, - 0.009484583046287298, - 0.009061125107109547, - 0.009129625046625733, - 0.009101375006139278, - 0.009893125155940652, - 0.009804583853110671, - 0.008942249929532409 - ], - "mean_time": 0.00927949621062592, - "std_time": 0.00031254052555951527, + 0.06276204204186797, + 0.0619283327832818, + 0.0613665422424674, + 0.06382191693410277, + 0.06352308299392462 + ], + "mean_time": 0.06276204204186797, + "std_time": 0.0010436643457612123, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear, p=1.0)": { + "Rotate(angle=45, interpolation=nearest, mode=constant, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 2936.2955968082106, - 2890.364500330233, - 2871.492450945978, - 2863.7806924023803, - 2583.766237589001, - 2924.7509132239948, - 2886.049037121707, - 2886.9398534908205, - 2910.311122854176, - 2915.0071299513343, - 2855.5936966417325, - 2858.361743746511, - 2887.1041172018054, - 2927.4336768747785, - 2869.057644889159, - 2254.834433730578, - 2898.3294954299913, - 2723.1193553886756, - 2871.247177409666, - 2832.148473951181 - ], - "median_throughput": 2878.7707440338427, - "std_throughput": 157.56720678158456, + 2933.797572252752, + 2913.8579802866284, + 3066.210598860769, + 3077.6775013209644, + 3077.7870295382895 + ], + "median_throughput": 3066.210598860769, + "std_throughput": 82.62917141781472, "times": [ - 0.34056516690179706, - 0.3459771249908954, - 0.34825095906853676, - 0.3491887499112636, - 0.3870319169946015, - 0.34190945816226304, - 0.34649445908144116, - 0.3463875420857221, - 0.34360587503761053, - 0.3430523341521621, - 0.3501898751128465, - 0.3498507500626147, - 0.34636783413589, - 0.341596124926582, - 0.3485464998520911, - 0.44349154201336205, - 0.3450263338163495, - 0.3672259161248803, - 0.34828070807270706, - 0.35308883315883577 - ], - "mean_time": 0.34737048862694847, - "std_time": 0.019013044968842093, + 0.6817102921195328, + 0.6863752501085401, + 0.6522709173150361, + 0.6498406669124961, + 0.6498175412416458 + ], + "mean_time": 0.6522709173150361, + "std_time": 0.017577594134500843, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ShiftRGB(pixel_shift=100, p=1.0, per_channel=True)": { + "Affine(angle=25.0, shift=(20, 20), scale=2.0, shear=(10.0, 15.0), interpolation=bilinear, mode=constant, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 2436.4205865878403, - 2436.7389600273973, - 2453.9623829819056, - 1739.2840727063615, - 1863.3329155589097, - 1511.5387087602355, - 2182.226062813524, - 2020.8314053635454, - 2207.9057929607757, - 2262.944323050212, - 2420.849566305415, - 2418.101665636692, - 2408.6542971921954, - 2356.4578429954836, - 2413.214035858645, - 2403.792704913568, - 2373.1070027464257, - 2344.6015229216127, - 1851.0914163349591, - 2346.0016098052433 - ], - "median_throughput": 2351.2297264003637, - "std_throughput": 276.0214017554926, + 1511.8029755855164, + 1503.0497817451337, + 1504.4175810785714, + 1446.6065657048443, + 1464.3438683458826 + ], + "median_throughput": 1503.0497817451337, + "std_throughput": 28.79460390029961, "times": [ - 0.4104381671641022, - 0.41038454114459455, - 0.4075042090844363, - 0.5749492079485208, - 0.5366727500222623, - 0.6615774999372661, - 0.4582476660143584, - 0.4948458329308778, - 0.45291787502355874, - 0.44190216693095863, - 0.41307812510058284, - 0.4135475419461727, - 0.41516958293505013, - 0.42436575004830956, - 0.414385125041008, - 0.4160092498641461, - 0.42138849990442395, - 0.4265117079485208, - 0.540221834089607, - 0.4262571670114994 - ], - "mean_time": 0.4253093556838272, - "std_time": 0.04992897257866057, + 1.3229237091727555, + 1.3306279168464243, + 1.3294181250967085, + 1.382545916363597, + 1.3657994158565998 + ], + "mean_time": 1.3306279168464243, + "std_time": 0.025491440316625855, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Resize(target_size=512, interpolation=bilinear, p=1.0)": { + "Perspective(scale=(0.05, 0.1), interpolation=bilinear, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 2339.4549065927768, - 2369.1014700836113, - 1752.099781829852, - 2133.892505731186, - 2232.724297026835, - 2327.0777602433013, - 2395.231812140959, - 2399.251431428603, - 2371.283282185992, - 2384.0492782286365, - 2371.4133206756874, - 2397.686474299354, - 2371.758057604355, - 2385.317421196361, - 2390.9269129416366, - 2172.9726003042747, - 2375.449493981629, - 2152.7275933920337, - 2401.2505696374396, - 2377.6347772882023 - ], - "median_throughput": 2371.5856891400213, - "std_throughput": 156.4515673421889, + 1239.3560939318638, + 1247.4469898230147, + 1221.9113134590411, + 1216.9117572193973, + 1208.6098648953293 + ], + "median_throughput": 1221.9113134590411, + "std_throughput": 16.097361267167592, "times": [ - 0.4274500000756234, - 0.4221009579487145, - 0.5707437500823289, - 0.46862716716714203, - 0.4478833330795169, - 0.4297235000412911, - 0.4174961249809712, - 0.4167966670356691, - 0.4217125838622451, - 0.4194544169586152, - 0.42168945888988674, - 0.4170687079895288, - 0.4216281659901142, - 0.4192314159590751, - 0.418247832916677, - 0.46019908390007913, - 0.4209729579742998, - 0.4645269578322768, - 0.41644966695457697, - 0.42058604187332094 - ], - "mean_time": 0.4216588102125956, - "std_time": 0.02781648668377854, + 1.6137412078678608, + 1.6032745409756899, + 1.6367800002917647, + 1.6435045418329537, + 1.6547937081195414 + ], + "mean_time": 1.6367800002917647, + "std_time": 0.021562807946334972, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomGamma(gamma=120, p=1.0)": { + "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True)": { "supported": true, - "warmup_iterations": 19, + "warmup_iterations": 21, "throughputs": [ - 9026.102415510788, - 8879.815071677473, - 9120.918319481852, - 9244.326426870657, - 8988.285989347596, - 8794.401147154107, - 8646.473815105182, - 8518.138456875884, - 9049.917080425213, - 9001.247817172924, - 9101.914130798981, - 9078.60823846364, - 7497.551583006516, - 9037.931041862346, - 8794.085379511449, - 8891.523381643628, - 9040.69214735793, - 9059.106114382765, - 9130.766219236935, - 8807.184368019894 - ], - "median_throughput": 9013.675116341856, - "std_throughput": 371.2021271942723, + 358.5406133174547, + 358.22902934816824, + 372.057461475605, + 356.6500378556215, + 366.0063238600809 + ], + "median_throughput": 358.5406133174547, + "std_throughput": 6.549288107077513, "times": [ - 0.11078979098238051, - 0.11261495784856379, - 0.10963808302767575, - 0.10817445791326463, - 0.11125591699965298, - 0.1137087089009583, - 0.11565408296883106, - 0.11739654210396111, - 0.11049824999645352, - 0.1110957080963999, - 0.10986700002104044, - 0.11014904198236763, - 0.13337687496095896, - 0.11064479197375476, - 0.11371279181912541, - 0.11246666708029807, - 0.11061100009828806, - 0.11038616695441306, - 0.1095198339316994, - 0.11354366596788168 - ], - "mean_time": 0.11094253865296222, - "std_time": 0.004568847424914273, + 5.57816862501204, + 5.583020459394902, + 5.375513750128448, + 5.6077380841597915, + 5.464386458974332 + ], + "mean_time": 5.57816862501204, + "std_time": 0.1018937104419957, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Grayscale(p=1.0, num_output_channels=3)": { + "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 11322.153937061083, - 11433.286257383686, - 11398.62561093383, - 11590.540963864905, - 11018.312431037859, - 12550.305876367664, - 11977.09974476899, - 11346.584266818469, - 11033.605192902682, - 11293.28332946681, - 11527.676518125836, - 11668.702110429487, - 10998.972542170985, - 11106.812411256831, - 10553.013043304023, - 9717.626093612604, - 12104.18071862603, - 12022.969875495979, - 10525.826393701587, - 14364.677311271269 - ], - "median_throughput": 11372.60493887615, - "std_throughput": 923.1985673139618, + 967.8612594198834, + 1038.6202053545278, + 951.5190346312303, + 924.9313751900758, + 1038.700801408656 + ], + "median_throughput": 967.8612594198834, + "std_throughput": 51.912392251918206, "times": [ - 0.0883224168792367, - 0.08746391697786748, - 0.08772987499833107, - 0.08627724996767938, - 0.09075800003483891, - 0.0796793329063803, - 0.0834926669485867, - 0.08813224988989532, - 0.09063220792450011, - 0.08854820788837969, - 0.08674774994142354, - 0.0856993340421468, - 0.09091758308932185, - 0.09003483294509351, - 0.094759666826576, - 0.10290579102002084, - 0.08261608309112489, - 0.08317412505857646, - 0.09500441700220108, - 0.06961520807817578 - ], - "mean_time": 0.08793060212454903, - "std_time": 0.007137978180086127, + 2.0664118751883507, + 1.9256317079998553, + 2.10190225020051, + 2.1623225826770067, + 1.9254822921939194 + ], + "mean_time": 2.0664118751883507, + "std_time": 0.11083446390146501, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5, p=1.0)": { + "ChannelShuffle()": { "supported": true, - "warmup_iterations": 28, + "warmup_iterations": 16, "throughputs": [ - 663.7988895851149, - 714.3535778458653, - 674.9499713096541, - 680.8038036762316, - 703.6967330631392, - 725.502435393903, - 717.2677976509062, - 667.6755244487383, - 700.6547676327622, - 683.8418095631827, - 686.6830386345109, - 601.7514276368507, - 644.2492275487069, - 712.0240416133241, - 701.3846209126009, - 721.7261094249191, - 704.9648409198285, - 700.1571678644112, - 720.0095541552897, - 653.4512682074301 - ], - "median_throughput": 700.4059677485867, - "std_throughput": 31.19256783657957, + 8082.329284140838, + 8161.669046094768, + 8260.916925715383, + 7793.6665737099265, + 8175.155457427395 + ], + "median_throughput": 8161.669046094768, + "std_throughput": 179.83335845494875, "times": [ - 1.5064803748391569, - 1.3998670000582933, - 1.4815912919584662, - 1.46885195793584, - 1.4210667081642896, - 1.37835512496531, - 1.3941794170532376, - 1.497733499854803, - 1.4272364168427885, - 1.4623265000991523, - 1.4562759581021965, - 1.6618157499469817, - 1.5521943329367787, - 1.4044469590298831, - 1.4257512500043958, - 1.3855671659111977, - 1.4185104588977993, - 1.428250749828294, - 1.38887045904994, - 1.5303360000252724 - ], - "mean_time": 1.4277434031786458, - "std_time": 0.06358452812735725, + 0.24745341716334224, + 0.24504791712388396, + 0.24210387514904141, + 0.25661862501874566, + 0.2446436658501625 + ], + "mean_time": 0.24504791712388396, + "std_time": 0.005399360065924721, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "PlankianJitter(mode=blackbody, p=1.0)": { + "Grayscale(num_output_channels=1)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 2385.696321534154, - 2167.6461101731425, - 1850.2139256676992, - 915.4796043205038, - 1830.4205356804118, - 2141.795043576952, - 2082.217754739512, - 2384.2956005911064, - 2256.7808489331637, - 1895.0563574726411, - 1769.1755211040108, - 2467.01016003854, - 2216.8293761794944, - 2233.903880525671, - 2115.202198802671, - 2119.8956461650505, - 2210.465414504765, - 2119.2541391340706, - 2362.3393510036763, - 2360.802649726586 - ], - "median_throughput": 2154.7205768750473, - "std_throughput": 340.194674458262, + 37211.60995822495, + 38248.07909025624, + 38065.51086192335, + 33769.04828434356, + 35866.55848439714 + ], + "median_throughput": 37211.60995822495, + "std_throughput": 1856.4082141821268, "times": [ - 0.4191648329142481, - 0.4613299169577658, - 0.5404780420940369, - 1.0923236249946058, - 0.5463225420098752, - 0.4668980829883367, - 0.4802571670152247, - 0.4194110829848796, - 0.4431090420112014, - 0.527688791975379, - 0.5652350420132279, - 0.40534895891323686, - 0.4510947079397738, - 0.44764683418907225, - 0.4727680410724133, - 0.4717213329859078, - 0.4523934160824865, - 0.47186412499286234, - 0.42330920812673867, - 0.42358474992215633 - ], - "mean_time": 0.4640972990800887, - "std_time": 0.0732732732364235, + 0.05374666675925255, + 0.05229020770639181, + 0.052540999837219715, + 0.05922583257779479, + 0.05576224997639656 + ], + "mean_time": 0.05374666675925255, + "std_time": 0.0026813070912222723, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomPerspective(scale=(0.05, 0.1), p=1.0, interpolation=bilinear)": { + "RGBShift(pixel_shift=100)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 406.3920457344824, - 389.27814442808375, - 372.856714822064, - 327.94901179144915, - 397.8585066781208, - 409.33111888804393, - 403.7411938060417, - 410.69619218262307, - 392.9845382713275, - 405.01472363782136, - 409.7481683836211, - 409.74779080626035, - 403.6042464806563, - 341.9997542631436, - 397.31903690513434, - 389.4007643121203, - 349.48698074924414, - 392.05329533809515, - 405.40725450923156, - 413.1790978151985 - ], - "median_throughput": 400.73137657938855, - "std_throughput": 24.49942924217862, + 3526.388404286177, + 3576.3996081018918, + 3566.368787604189, + 3330.0028704067986, + 3321.677705147184 + ], + "median_throughput": 3526.388404286177, + "std_throughput": 127.68719559749705, "times": [ - 2.4606780828908086, - 2.5688572921790183, - 2.68199541606009, - 3.049254500074312, - 2.5134563751053065, - 2.4430099590681493, - 2.4768342080060393, - 2.4348898748867214, - 2.544629374984652, - 2.4690460411366075, - 2.4405234169680625, - 2.4405256658792496, - 2.4776746248826385, - 2.9239787091501057, - 2.5168690828140825, - 2.568048374960199, - 2.861336916917935, - 2.5506736249662936, - 2.4666554159484804, - 2.420257959049195 - ], - "mean_time": 2.495437239119934, - "std_time": 0.15256301762536092, + 0.5671525001525879, + 0.5592216248624027, + 0.5607944997027516, + 0.6006000828929245, + 0.6021053749136627 + ], + "mean_time": 0.5671525001525879, + "std_time": 0.020536056701119985, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianBlur(sigma=2.0, kernel_size=(5, 5), p=1.0)": { + "GaussianBlur(sigma=2.0, kernel_size=(5, 5))": { "supported": true, - "warmup_iterations": 19, + "warmup_iterations": 16, "throughputs": [ - 1581.4811717902933, - 1610.986822041706, - 1706.7670387803203, - 1773.9675570427287, - 1452.4877621664752, - 1688.8258204218762, - 1655.0571306353681, - 1779.30574146266, - 1775.520631859384, - 1369.487655901637, - 1826.9076540371555, - 1718.6828433320832, - 1639.8296032028584, - 1650.1780628303793, - 1263.633220422084, - 1587.0191360850963, - 1590.7967095338445, - 1692.5267116304017, - 1672.214354719308, - 1800.3061429026764 - ], - "median_throughput": 1663.635742677338, - "std_throughput": 143.80741050581113, + 946.5295964602162, + 945.7227450910851, + 921.0377809407206, + 936.5579907659577, + 942.7464207067845 + ], + "median_throughput": 942.7464207067845, + "std_throughput": 10.528215207111163, "times": [ - 0.6323186249937862, - 0.6207375419326127, - 0.5859030419960618, - 0.5637081670574844, - 0.6884739589877427, - 0.5921273750718683, - 0.6042087499517947, - 0.5620169579051435, - 0.5632150829769671, - 0.7302000829949975, - 0.5473730419762433, - 0.5818409160710871, - 0.6098194580990821, - 0.6059952089563012, - 0.7913688749540597, - 0.6301121248397976, - 0.6286158338189125, - 0.5908326250500977, - 0.5980094580445439, - 0.555461083073169 - ], - "mean_time": 0.6010931205353106, - "std_time": 0.05195947821962958, + 2.1129820002242923, + 2.11478470871225, + 2.1714635831303895, + 2.135479083750397, + 2.1214612498879433 + ], + "mean_time": 2.1214612498879433, + "std_time": 0.023691631282590733, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MedianBlur(blur_limit=5, p=1.0)": { + "GaussianNoise(mean=0, std=0.44, per_channel=True)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 807.2352221043649, - 768.5568041045487, - 800.6510094274117, - 799.5237774503358, - 743.0480424750505, - 851.5122019129403, - 791.0758467880139, - 813.768198783057, - 805.6304981239407, - 858.8037530579253, - 852.1621216627169, - 857.9551872278904, - 843.2366802410377, - 858.6657312199663, - 865.9857780570901, - 862.7287483965443, - 864.6059818376751, - 862.94136052356, - 831.3057557689207, - 851.6710233953651 - ], - "median_throughput": 847.374441076989, - "std_throughput": 36.051832746824125, + 237.18882853164928, + 228.38826228505314, + 233.82363062471833, + 245.78720349523212, + 228.4101644706014 + ], + "median_throughput": 233.82363062471833, + "std_throughput": 7.23336905856073, "times": [ - 1.2387962921056896, - 1.3011399998795241, - 1.248983624856919, - 1.2507445409428328, - 1.3458080000709742, - 1.1743812921922654, - 1.2641012920066714, - 1.228851166088134, - 1.2412638328969479, - 1.1644103748258203, - 1.1734856250695884, - 1.1655620420351624, - 1.1859066658653319, - 1.1645975420251489, - 1.154753375099972, - 1.159112875116989, - 1.1565962079912424, - 1.1588272920344025, - 1.2029268329497427, - 1.1741622909903526 - ], - "mean_time": 1.1801158396151625, - "std_time": 0.05020842830426871, + 8.43210033280775, + 8.757017457857728, + 8.55345541704446, + 8.13712012488395, + 8.756177749950439 + ], + "mean_time": 8.55345541704446, + "std_time": 0.2646024253071688, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MotionBlur(kernel_size=5, angle=45, direction=0.0, p=1.0)": { + "Invert()": { "supported": true, - "warmup_iterations": 18, + "warmup_iterations": 16, "throughputs": [ - 3924.1468855928247, - 4001.968968816861, - 3976.8197697547525, - 4071.3642231387694, - 4131.256205131547, - 4067.3926312271715, - 4006.5928478916685, - 4005.533643497983, - 4051.217517426638, - 2707.1118193720313, - 3846.862790987829, - 3878.8474436257206, - 3927.9226180219343, - 3761.0221400081723, - 1549.3797986553895, - 3594.4512364328516, - 1931.9345644237399, - 2878.893240928294, - 3927.539517283191, - 3955.406745543456 - ], - "median_throughput": 3927.7310676525626, - "std_throughput": 742.4529084220972, + 69454.69412356419, + 59691.024065199825, + 35494.006124105596, + 34905.56251315267, + 31485.609284570623 + ], + "median_throughput": 35494.006124105596, + "std_throughput": 17186.362728452077, "times": [ - 0.2548324589151889, - 0.2498769999947399, - 0.25145720900036395, - 0.24561791704036295, - 0.24205712508410215, - 0.24585774983279407, - 0.2495886250399053, - 0.24965462507680058, - 0.24683937500230968, - 0.36939737503416836, - 0.2599520841613412, - 0.2578085409477353, - 0.2545875001233071, - 0.2658851670566946, - 0.6454195419792086, - 0.27820658404380083, - 0.5176158749964088, - 0.34735570801422, - 0.2546123331412673, - 0.252818499924615 - ], - "mean_time": 0.2545999160267501, - "std_time": 0.04812662702262265, + 0.028795749880373478, + 0.033505875151604414, + 0.056347541976720095, + 0.057297457940876484, + 0.06352108297869563 + ], + "mean_time": 0.05634754197672009, + "std_time": 0.02728374170789643, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Posterize(bits=4, p=1.0)": { + "Posterize(bits=4)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 8920.39103080024, - 9310.029855639745, - 9146.442553735083, - 9375.164855998586, - 8458.743006801598, - 8900.409960148925, - 9640.962450670417, - 8832.901405278835, - 8846.28259361947, - 8889.418938240959, - 8692.269761746493, - 9144.097321221934, - 9462.72608549812, - 8633.745740455333, - 9067.11819950243, - 8385.079191828863, - 9000.630065667043, - 9261.199381459297, - 9232.981586087146, - 9287.778337401018 - ], - "median_throughput": 9033.874132584737, - "std_throughput": 331.01824138927736, + 12949.642590158088, + 13217.081795492102, + 15256.475655960452, + 16225.216821074422, + 14146.489266693607 + ], + "median_throughput": 14146.489266693607, + "std_throughput": 1380.548267969441, "times": [ - 0.11210270901210606, - 0.10741104115732014, - 0.10933212493546307, - 0.10666479100473225, - 0.1182208750396967, - 0.11235437518917024, - 0.1037240840960294, - 0.11321308300830424, - 0.11304183304309845, - 0.11249329196289182, - 0.1150447498075664, - 0.10936016589403152, - 0.10567779210396111, - 0.11582458298653364, - 0.11028862511739135, - 0.11925945803523064, - 0.11110333306714892, - 0.1079773751553148, - 0.10830737510696054, - 0.10766837489791214 - ], - "mean_time": 0.11069448005624181, - "std_time": 0.004056055196469045, + 0.15444441698491573, + 0.15131933288648725, + 0.13109187502413988, + 0.12326491670683026, + 0.14137783320620656 + ], + "mean_time": 0.14137783320620656, + "std_time": 0.013796986593813693, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "JpegCompression(quality=50, p=1.0)": { + "Solarize(threshold=0.5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 895.9263231975085, - 909.2034915677435, - 897.6915195626713, - 909.6506203686774, - 893.0054781519034, - 773.4736936388164, - 849.6490137392127, - 795.3665659924866, - 894.7712470316475, - 881.5651721743994, - 915.4797091085687, - 908.5625667717921, - 908.8097977394475, - 913.213097341246, - 906.9298058148959, - 913.501946800198, - 905.0822177194083, - 871.1697795199128, - 916.7299430365374, - 923.3778015625085 - ], - "median_throughput": 906.0060117671521, - "std_throughput": 39.891994836311305, + 11507.322621951876, + 11556.17919875995, + 12920.025351599057, + 14062.497265240912, + 13139.766354329748 + ], + "median_throughput": 12920.025351599057, + "std_throughput": 1096.5017405024514, "times": [ - 1.116163209080696, - 1.099863792071119, - 1.113968415884301, - 1.0993231660686433, - 1.1198139591142535, - 1.292868792079389, - 1.1769565830472857, - 1.2572819159831852, - 1.1176040840800852, - 1.1343460830394179, - 1.0923234999645501, - 1.1006396659649909, - 1.1003402499482036, - 1.0950346670579165, - 1.102621166035533, - 1.0946884169243276, - 1.104871999938041, - 1.1478818750474602, - 1.0908337919972837, - 1.0829803340602666 - ], - "mean_time": 1.103745435474003, - "std_time": 0.048598581731979916, + 0.17380237486213446, + 0.17306758277118206, + 0.15479845786467195, + 0.14222224988043308, + 0.1522097080014646 + ], + "mean_time": 0.15479845786467195, + "std_time": 0.013137495775478535, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianNoise(mean=127, var=0.01, per_channel=True, p=1.0)": { + "Sharpen(alpha=(0.2, 0.5), lightness=(0.5, 1))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 182.42877367707575, - 185.1676542615163, - 186.4234410236641, - 185.8323607311278, - 181.55803390979784, - 186.36642331276965, - 185.18723853628893, - 187.09914884572586, - 184.302947185153, - 179.17153591949776, - 176.46395915057946, - 184.8084099089121, - 179.41048897849328, - 185.82358092459648, - 166.97479198308434, - 183.82435026775715, - 176.38155836006553, - 175.2491237491372, - 180.6536160834147, - 179.41076525179926 - ], - "median_throughput": 183.12656197241645, - "std_throughput": 5.05243991941347, + 2440.4360723928717, + 2425.93923266951, + 2375.014138561294, + 2368.106810517858, + 2354.3597914082297 + ], + "median_throughput": 2375.014138561294, + "std_throughput": 37.98401012552096, "times": [ - 5.481591416988522, - 5.400511250132695, - 5.364132292103022, - 5.381194083020091, - 5.5078807501122355, - 5.365773416822776, - 5.399940124945715, - 5.344759749947116, - 5.425849207909778, - 5.581243666121736, - 5.6668795419391245, - 5.411009166156873, - 5.5738101250026375, - 5.381448334082961, - 5.9889279580675066, - 5.439975708024576, - 5.669526957906783, - 5.70616262499243, - 5.535455208038911, - 5.57380154193379 - ], - "mean_time": 5.4607042759347255, - "std_time": 0.15066017717298802, + 0.819525667000562, + 0.8244229587726295, + 0.842100250069052, + 0.8445565002039075, + 0.8494878341443837 + ], + "mean_time": 0.842100250069052, + "std_time": 0.013467854319681182, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True, p=1.0)": { + "AutoContrast()": { "supported": true, - "warmup_iterations": 19, + "warmup_iterations": 16, + "throughputs": [ + 1534.4768664273545, + 1530.932832144905, + 1526.9498544235453, + 1713.349491963015, + 1763.9827133191286 + ], + "median_throughput": 1534.4768664273545, + "std_throughput": 115.28977387310482, + "times": [ + 1.3033757912926376, + 1.3063930422067642, + 1.3098007077351213, + 1.1673041661269963, + 1.133797958958894 + ], + "mean_time": 1.3033757912926376, + "std_time": 0.09792646832119653, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Equalize()": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1331.8873105139846, + 1327.1772957537648, + 1302.8775570103724, + 1207.7623793566393, + 1204.8663647740614 + ], + "median_throughput": 1302.8775570103724, + "std_throughput": 63.59123774202713, + "times": [ + 1.5016285418532789, + 1.5069576660171151, + 1.5350636667571962, + 1.6559548750519753, + 1.6599351251497865 + ], + "mean_time": 1.5350636667571962, + "std_time": 0.07492384687775203, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))": { + "supported": true, + "warmup_iterations": 16, "throughputs": [ - 228.91659990420868, - 230.3580084588522, - 228.45467517789558, - 233.3873543786942, - 221.92658933103553, - 210.14295421253053, - 218.74146625969482, - 235.44880752092325, - 243.6783787278612, - 243.4752364899938, - 233.1226034633408, - 234.90984891031832, - 201.6365054374185, - 175.4951359412666, - 205.95273956553845, - 215.09418032823564, - 211.93762700878443, - 226.8445431424017, - 242.73050459939998, - 247.4153701430718 - ], - "median_throughput": 228.68563754105213, - "std_throughput": 17.47520349847134, + 1592.6768181564914, + 1594.153389204078, + 2024.654130014656, + 1797.0527661688634, + 1902.9190940476753 + ], + "median_throughput": 1797.0527661688634, + "std_throughput": 190.30122973616997, "times": [ - 4.368403166998178, - 4.341068959096447, - 4.3772358749993145, - 4.284722292097285, - 4.505994540872052, - 4.758665374945849, - 4.571606916142628, - 4.247207749867812, - 4.103769916808233, - 4.10719387489371, - 4.289588333107531, - 4.256952208001167, - 4.959419415798038, - 5.698163625085726, - 4.855482874903828, - 4.6491262500640005, - 4.718369334004819, - 4.408305292017758, - 4.119795332895592, - 4.0417860839515924 - ], - "mean_time": 4.37281506067685, - "std_time": 0.3341523056199391, + 1.2557475422509015, + 1.2545844167470932, + 0.9878230411559343, + 1.112933374941349, + 1.0510168331675231 + ], + "mean_time": 1.112933374941349, + "std_time": 0.11785552091343719, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), p=1.0)": { + "Erasing(scale=(0.02, 0.33), ratio=(0.3, 3.3), fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 1298.5398244460744, - 1287.3323699192222, - 1206.3193031696821, - 1383.1697070238788, - 1372.9234892353402, - 1415.5093106090922, - 1347.3012544507887, - 1392.2207925653581, - 1430.5854885365252, - 1419.5371717661749, - 1329.7471526754177, - 1280.5107032554051, - 1318.824651192704, - 1345.2291951693187, - 1443.4123696693139, - 1358.5103798686887, - 1484.95352263898, - 1318.672190105303, - 1328.8063114143317, - 1350.7674637356556 - ], - "median_throughput": 1349.034359093222, - "std_throughput": 65.00791962377136, + 28031.84859955734, + 23340.94516244196, + 24091.148722283244, + 37385.594062352975, + 25410.7271287308 + ], + "median_throughput": 25410.7271287308, + "std_throughput": 5726.589256121194, "times": [ - 0.7700957499910146, - 0.77680016704835, - 0.8289679170120507, - 0.7229770829435438, - 0.7283727081958205, - 0.7064595001284033, - 0.7422245000489056, - 0.7182768748607486, - 0.6990145000163466, - 0.7044549589045346, - 0.7520226668566465, - 0.7809384157881141, - 0.7582509161438793, - 0.7433677499648184, - 0.6928027090616524, - 0.7361003749538213, - 0.6734217500779778, - 0.7583385829348117, - 0.7525551251601428, - 0.7403198750689626 - ], - "mean_time": 0.7412709641229361, - "std_time": 0.035720723442159104, + 0.07134741730988026, + 0.08568633301183581, + 0.08301804214715958, + 0.053496541921049356, + 0.07870691735297441 + ], + "mean_time": 0.07870691735297441, + "std_time": 0.01773747697232757, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Clahe(clip_limit=(1, 4), tile_grid_size=(8, 8), p=1.0)": { + "JpegCompression(quality=50)": { "supported": true, - "warmup_iterations": 20, + "warmup_iterations": 16, "throughputs": [ - 465.3788031150073, - 474.0241202523972, - 466.22472832073584, - 478.4851735218444, - 464.82091973484563, - 476.05848332487324, - 465.192675197861, - 471.4698561698571, - 479.79551111982113, - 439.86522750843255, - 466.9416864046196, - 475.6579375220471, - 473.2696884776294, - 470.69844322272377, - 476.7420781159498, - 471.48932525181186, - 479.29122428453314, - 473.29015593778877, - 461.4112806139873, - 398.20049879267253 - ], - "median_throughput": 471.4795907108345, - "std_throughput": 18.33313260054542, + 1364.45926435335, + 1353.8698466203641, + 1348.7235419441608, + 1330.9205960754896, + 1392.069299937516 + ], + "median_throughput": 1353.8698466203641, + "std_throughput": 22.576779498216926, "times": [ - 2.148787167156115, - 2.1095972910989076, - 2.1448883751872927, - 2.089928915956989, - 2.1513661660719663, - 2.100582249928266, - 2.1496469168923795, - 2.121026375098154, - 2.084221250144765, - 2.2734236249234527, - 2.1415950409136713, - 2.1023511248640716, - 2.112960166996345, - 2.1245024588424712, - 2.0975702500436455, - 2.1209387921262532, - 2.08641416602768, - 2.112868791911751, - 2.1672638750169426, - 2.5112977081444114 - ], - "mean_time": 2.12098258270805, - "std_time": 0.08247282745284784, + 1.4657821250148118, + 1.4772468749433756, + 1.4828835842199624, + 1.5027192500419915, + 1.4367100833915174 + ], + "mean_time": 1.4772468749433756, + "std_time": 0.02463418255697266, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Brightness(brightness_limit=(0.2, 0.2), p=1.0)": { + "RandomGamma(gamma=120)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 9262.243083017953, - 8499.519541952239, - 8318.071952067801, - 9086.665195708783, - 9239.134201218676, - 9899.103389085838, - 10842.503157155217, - 9729.397075183238, - 9132.534775718643, - 9201.83300366596, - 10233.328397392555, - 10664.694912203304, - 10626.079822660535, - 9516.290928438746, - 9098.884442003877, - 9528.615483247502, - 9205.563638116262, - 9031.044186889065, - 8944.027179087678, - 10331.52135831708 - ], - "median_throughput": 9250.688642118315, - "std_throughput": 709.1623547430191, + 14493.729534601047, + 12623.118135186754, + 12585.20242080893, + 12630.904243144763, + 14926.07398446572 + ], + "median_throughput": 12630.904243144763, + "std_throughput": 1158.735925172245, "times": [ - 0.10796520789153874, - 0.11765370913781226, - 0.12022016709670424, - 0.11005137511529028, - 0.10823524999432266, - 0.1010192499961704, - 0.09222962497733533, - 0.10278129181824625, - 0.10949862492270768, - 0.10867400001734495, - 0.09771991684101522, - 0.09376733307726681, - 0.09410808281973004, - 0.10508295800536871, - 0.10990358283743262, - 0.10494704102165997, - 0.1086299589369446, - 0.1107291670050472, - 0.1118064580950886, - 0.09679116611368954 - ], - "mean_time": 0.10810006029680942, - "std_time": 0.008287003948972305, + 0.13799070799723268, + 0.158439458347857, + 0.15891679236665368, + 0.15834179101511836, + 0.133993708062917 + ], + "mean_time": 0.15834179101511836, + "std_time": 0.014525984693844269, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Contrast(contrast_limit=(0.2, 0.2), p=1.0)": { + "PlankianJitter(mode=blackbody)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 10585.548513424366, - 10030.136354471706, - 9237.235296404233, - 8862.802703438301, - 7864.579803782532, - 8783.802063008707, - 8789.122582557982, - 9325.364364138219, - 9556.533094353661, - 10812.00398452694, - 10863.321776618523, - 10576.684862536562, - 8361.559384255685, - 8899.136034629908, - 9375.42484231676, - 9055.69134662856, - 6604.478143993113, - 8681.4221796211, - 9390.255494356301, - 8765.413435658631 - ], - "median_throughput": 9146.463321516396, - "std_throughput": 1034.1438188756329, + 3351.387766829782, + 3387.0302311413143, + 3401.558198911732, + 3296.9981230672392, + 3333.8736987347484 + ], + "median_throughput": 3351.387766829782, + "std_throughput": 41.87403839030633, "times": [ - 0.094468415947631, - 0.09969954192638397, - 0.10825749998912215, - 0.112831125035882, - 0.12715237494558096, - 0.1138459169305861, - 0.11377699999138713, - 0.10723441583104432, - 0.10464045801199973, - 0.09248979203402996, - 0.09205287485383451, - 0.09454758395440876, - 0.11959491693414748, - 0.11237045889720321, - 0.10666183312423527, - 0.11042779195122421, - 0.1514124171808362, - 0.11518850014545023, - 0.10649337503127754, - 0.11408474994823337 - ], - "mean_time": 0.10933187668807155, - "std_time": 0.012361596008051014, + 0.5967677091248333, + 0.5904877912253141, + 0.5879658330231905, + 0.6066124169155955, + 0.599902749992907 + ], + "mean_time": 0.5967677091248333, + "std_time": 0.00745633621072343, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "CoarseDropout(hole_height_range=(16, 16), hole_width_range=(16, 16), num_holes_range=(1, 1), p=1.0)": { + "MedianBlur(blur_limit=5)": { "supported": true, - "warmup_iterations": 23, + "warmup_iterations": 16, "throughputs": [ - 12146.111669882064, - 12844.438413310823, - 13921.11375358947, - 14511.20809649814, - 14633.726854110291, - 14465.011438913743, - 14463.582086568676, - 14556.33212776048, - 14059.333891643171, - 14065.719827027859, - 13784.602801091773, - 17817.33228191328, - 18114.24643104558, - 18290.062049987057, - 18307.138798029875, - 18278.5559681027, - 18281.84209822525, - 14536.133902348169, - 12712.56471632674, - 14269.126411249774 - ], - "median_throughput": 14488.10976770594, - "std_throughput": 2107.744661799796, + 1271.7088308512925, + 1257.3428491560242, + 1258.1617010038424, + 1259.3607892615319, + 1274.5535091477543 + ], + "median_throughput": 1259.3607892615319, + "std_throughput": 8.22304634935277, "times": [ - 0.08233087486587465, - 0.0778547078371048, - 0.07183333300054073, - 0.0689122499898076, - 0.06833529216237366, - 0.06913233385421336, - 0.06913916580379009, - 0.06869862484745681, - 0.07112712506204844, - 0.0710948328487575, - 0.07254470908083022, - 0.05612512491643429, - 0.0552051670383662, - 0.05467450013384223, - 0.054623500211164355, - 0.0547089169267565, - 0.054699083091691136, - 0.06879408285021782, - 0.07866233307868242, - 0.07008137507364154 - ], - "mean_time": 0.06902211648264871, - "std_time": 0.010041406359765737, + 1.5726870424114168, + 1.590656042098999, + 1.5896207923069596, + 1.5881072501651943, + 1.5691769593395293 + ], + "mean_time": 1.5881072501651943, + "std_time": 0.01036960943774436, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Blur(radius=5, p=1.0)": { + "MotionBlur(kernel_size=5, angle_range=(0, 360), direction_range=(-1, 1))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 5437.304247327801, - 6080.304103706773, - 6120.475443976756, - 6146.339753965599, - 6101.805560886684, - 6117.7592413594875, - 6128.406961830858, - 6104.5464397113665, - 5760.108731510341, - 5697.91641145246, - 5799.376385000703, - 5694.204172793645, - 5808.956507773419, - 5914.290102401735, - 5894.010944620799, - 5439.58043435473, - 5464.036740325403, - 5701.39105350364, - 5069.780226198483, - 5460.132167020559 - ], - "median_throughput": 5804.16644638706, - "std_throughput": 305.3617565521425, + 3588.208784466163, + 3610.2223446541016, + 3606.3657739239356, + 3638.593102857099, + 3608.055433957421 + ], + "median_throughput": 3608.055433957421, + "std_throughput": 18.09035046352654, "times": [ - 0.18391466699540615, - 0.1644654581323266, - 0.16338599985465407, - 0.1626984579488635, - 0.16388591704890132, - 0.16345854103565216, - 0.16317454213276505, - 0.16381233395077288, - 0.1736078339163214, - 0.1755027500912547, - 0.17243233299814165, - 0.1756171660963446, - 0.1721479578409344, - 0.16908200015313923, - 0.16966375010088086, - 0.18383770808577538, - 0.18301487481221557, - 0.17539579211734235, - 0.19724720902740955, - 0.18314574984833598 - ], - "mean_time": 0.17229002807500007, - "std_time": 0.009064313729691329, + 0.5573811670765281, + 0.553982499986887, + 0.5545749170705676, + 0.5496629998087883, + 0.5543152084574103 + ], + "mean_time": 0.5543152084574103, + "std_time": 0.0027792689363584934, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "HSV(hue=0.015, saturation=0.7, value=0.4, p=1.0)": { + "CLAHE(clip_limit=(1, 4), tile_grid_size=(8, 8))": { + "supported": true, + "warmup_iterations": 22, + "throughputs": [ + 646.6836740929765, + 630.2396301119834, + 653.0860684323634, + 666.9930672436326, + 648.5652027812911 + ], + "median_throughput": 648.5652027812911, + "std_throughput": 13.208783754509591, + "times": [ + 3.0927021666429937, + 3.173396124970168, + 3.0623834999278188, + 2.998531916178763, + 3.0837300419807434 + ], + "mean_time": 3.0837300419807434, + "std_time": 0.06280374449189215, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Brightness(brightness_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 1211.7356599051832, - 1231.3604110622557, - 1234.238073129746, - 1201.559745195675, - 1193.2537014926932, - 1228.0857055349456, - 1237.4928147616367, - 1189.3680010258981, - 1251.133057372916, - 1335.0792469069418, - 1340.4173656156413, - 1220.7040561597491, - 1243.7269524872177, - 1246.253320072416, - 1269.3393770968987, - 1335.3464425483517, - 1266.3398074951174, - 1246.9979833026325, - 1242.059296054026, - 1245.684545287845 - ], - "median_throughput": 1242.8931242706217, - "std_throughput": 43.67190635608972, + 11187.301297885302, + 11429.951181122533, + 11254.393592802668, + 10372.663877781064, + 11276.66935806975 + ], + "median_throughput": 11254.393592802668, + "std_throughput": 418.46999609601517, "times": [ - 0.8252624999731779, - 0.8121099160052836, - 0.8102164580486715, - 0.8322515829931945, - 0.8380447500385344, - 0.8142754170112312, - 0.808085500029847, - 0.8407826670445502, - 0.7992755000013858, - 0.7490192078985274, - 0.7460362911224365, - 0.819199375109747, - 0.8040349998045713, - 0.8024050840176642, - 0.7878113749902695, - 0.7488693331833929, - 0.789677457883954, - 0.8019259159918875, - 0.8051145409699529, - 0.802771459100768 - ], - "mean_time": 0.8045744082676772, - "std_time": 0.0282705709189535, + 0.17877412494271994, + 0.17497887508943677, + 0.17770837526768446, + 0.19281450007110834, + 0.17735733278095722 + ], + "mean_time": 0.17770837526768446, + "std_time": 0.00660769702883458, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Contrast(contrast_limit=(0.2, 0.2))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 11619.870479365214, + 11492.466785855826, + 11196.241416858828, + 11010.224828887947, + 11254.913507479887 + ], + "median_throughput": 11254.913507479887, + "std_throughput": 242.40566858135233, + "times": [ + 0.17211895808577538, + 0.17402704199776053, + 0.1786313750781119, + 0.18164933333173394, + 0.1777001661248505 + ], + "mean_time": 0.1777001661248505, + "std_time": 0.00382726420313086, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "CoarseDropout(hole_height_range=(0.1, 0.1), hole_width_range=(0.1, 0.1), num_holes_range=(4, 4))": { + "supported": true, + "warmup_iterations": 17, + "throughputs": [ + 15759.535731036343, + 15518.79323730862, + 16957.211969602355, + 15863.997955238829, + 15535.901252524387 + ], + "median_throughput": 15759.535731036343, + "std_throughput": 594.3360148043158, + "times": [ + 0.12690729182213545, + 0.1288760001771152, + 0.11794391693547368, + 0.12607162492349744, + 0.12873408291488886 + ], + "mean_time": 0.12690729182213545, + "std_time": 0.004786027669751433, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Blur(radius=5, border_mode=constant)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 7300.944303847169, + 7490.608655933182, + 7403.338996468258, + 7307.851460388761, + 7563.04387162866 + ], + "median_throughput": 7403.338996468258, + "std_throughput": 114.2827330969362, + "times": [ + 0.27393716713413596, + 0.26700099976733327, + 0.2701483750715852, + 0.2736782501451671, + 0.264443791937083 + ], + "mean_time": 0.2701483750715852, + "std_time": 0.004170185190709894, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "HSV(hue=0.015, saturation=0.7, value=0.4)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1228.1173474231578, + 1318.8884276893202, + 1276.8424538628128, + 1308.123362351091, + 1095.1846674745643 + ], + "median_throughput": 1276.8424538628128, + "std_throughput": 91.086124651681, + "times": [ + 1.6285088751465082, + 1.5164284999482334, + 1.5663639581762254, + 1.5289077907800674, + 1.8261760408058763 + ], + "mean_time": 1.5663639581762254, + "std_time": 0.11173972349737471, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "ChannelDropout()": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 10478.59912081127, + 11013.577190029446, + 10811.412220953469, + 10987.853816223893, + 11082.657912440778 + ], + "median_throughput": 10987.853816223893, + "std_throughput": 243.02177412293497, + "times": [ + 0.19086520792916417, + 0.18159404210746288, + 0.18498970894142985, + 0.1820191671140492, + 0.18046212522313 + ], + "mean_time": 0.1820191671140492, + "std_time": 0.004025774428407619, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "LinearIllumination(gain=(0.01, 0.2))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 400.21897316198164, + 496.5128249808623, + 371.99839724547667, + 471.7688275959681, + 461.58283115084447 + ], + "median_throughput": 461.58283115084447, + "std_throughput": 52.14081329622919, + "times": [ + 4.9972643330693245, + 4.028093332890421, + 5.376367249991745, + 4.239364457782358, + 4.332916792016476 + ], + "mean_time": 4.332916792016476, + "std_time": 0.48945019232484527, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "CornerIllumination(gain=(0.01, 0.2))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 426.93552973785916, + 520.8784015786131, + 463.73936412350525, + 440.76883638433475, + 524.2886664328471 + ], + "median_throughput": 463.73936412350525, + "std_throughput": 45.11776041742755, + "times": [ + 4.6845480422489345, + 3.8396677495911717, + 4.31276737479493, + 4.537525875028223, + 3.8146924166940153 + ], + "mean_time": 4.31276737479493, + "std_time": 0.41959432432454347, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "GaussianIllumination(gain=(0.01, 0.2))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 670.2558213789785, + 571.6768356551163, + 752.2538701157132, + 782.9365248346513, + 605.1736598823903 + ], + "median_throughput": 670.2558213789785, + "std_throughput": 91.07923300027198, + "times": [ + 2.983935291878879, + 3.498480041977018, + 2.658676916733384, + 2.554485499858856, + 3.3048364999704063 + ], + "mean_time": 2.983935291878879, + "std_time": 0.40547881724865065, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Hue(hue=20)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1614.387854663288, + 1611.0004470198319, + 1846.2746341396582, + 2020.046691531331, + 1971.7608513328826 + ], + "median_throughput": 1846.2746341396582, + "std_throughput": 193.28132182099841, + "times": [ + 1.2388596669770777, + 1.241464584134519, + 1.083262458909303, + 0.9900761246681213, + 1.0143217919394374 + ], + "mean_time": 1.083262458909303, + "std_time": 0.11340371365423704, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "PlasmaBrightness(roughness=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 163.40645985501476, + 161.0682648586371, + 163.49467357737794, + 163.92722361684105, + 162.61481312974848 + ], + "median_throughput": 163.40645985501476, + "std_throughput": 1.1293677030112492, + "times": [ + 12.239418207667768, + 12.417095333803445, + 12.23281441675499, + 12.200536041986197, + 12.29900254169479 + ], + "mean_time": 12.23941820766777, + "std_time": 0.08459153719903321, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "PlasmaContrast(roughness=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 136.29259385264893, + 137.09988025491322, + 142.31128125259838, + 145.64566301748314, + 138.397894725334 + ], + "median_throughput": 138.397894725334, + "std_throughput": 3.9346238063624197, + "times": [ + 14.674311666283756, + 14.587904790882021, + 14.053699625190347, + 13.731957125011832, + 14.45108687505126 + ], + "mean_time": 14.451086875051258, + "std_time": 0.41084144061029515, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "PlasmaShadow(roughness=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 194.77658462244503, + 191.75460395917287, + 188.19252349327778, + 190.25717878447844, + 189.41825644830024 + ], + "median_throughput": 190.25717878447844, + "std_throughput": 2.534533197231916, + "times": [ + 10.268174708355218, + 10.429997291881591, + 10.62741474993527, + 10.512086917180568, + 10.558644332922995 + ], + "mean_time": 10.512086917180568, + "std_time": 0.14003799191179359, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Rain(drop_width=5, drop_height=20, brightness_coefficient=1.0)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 2121.0547836166597, + 2140.407712670023, + 2149.7223376714774, + 2063.7620799154893, + 1995.9790164432393 + ], + "median_throughput": 2121.0547836166597, + "std_throughput": 64.2512443195918, + "times": [ + 0.9429270830005407, + 0.9344014171510935, + 0.9303527087904513, + 0.9691039579920471, + 1.0020145419985056 + ], + "mean_time": 0.9429270830005407, + "std_time": 0.028563259588290393, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "SaltAndPepper(amount=(0.01, 0.06), salt_vs_pepper=(0.4, 0.6))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 2233.3379376671105, + 2231.9383852810347, + 2185.8643159969165, + 2239.055463603848, + 2283.7188576286144 + ], + "median_throughput": 2233.3379376671105, + "std_throughput": 34.699386845204955, + "times": [ + 0.8955205418169498, + 0.8960820841602981, + 0.9149698750115931, + 0.8932337909936905, + 0.8757645422592759 + ], + "mean_time": 0.8955205418169497, + "std_time": 0.013913708796257241, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Saturation(saturation_factor=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1617.2626071022478, + 1581.1710459212195, + 1566.020947255692, + 1613.6537702072103, + 1313.9116754264924 + ], + "median_throughput": 1581.1710459212195, + "std_throughput": 127.34768118748049, + "times": [ + 1.2366575417108834, + 1.2648852919228375, + 1.277122125029564, + 1.239423249848187, + 1.5221723327413201 + ], + "mean_time": 1.2648852919228375, + "std_time": 0.10187399352526999, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Snow(snow_point_range=(0.5, 0.5))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 575.607861325682, + 630.1422975489292, + 648.8052737492451, + 584.6288575949653, + 587.7905253585991 + ], + "median_throughput": 587.7905253585991, + "std_throughput": 32.114266421412246, + "times": [ + 3.474587708711624, + 3.17388629168272, + 3.0825889999978244, + 3.420973792206496, + 3.40257270867005 + ], + "mean_time": 3.4025727086700495, + "std_time": 0.18590147641082203, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "OpticalDistortion(distort_limit=0.5)": { + "supported": true, + "warmup_iterations": 19, + "throughputs": [ + 709.4726183904862, + 686.5372674334461, + 623.9205686675298, + 647.8548776405804, + 710.4017933942197 + ], + "median_throughput": 686.5372674334461, + "std_throughput": 38.4665158072132, + "times": [ + 2.8189953328110278, + 2.913170333020389, + 3.205536250025034, + 3.087111124768853, + 2.8153082081116736 + ], + "mean_time": 2.913170333020389, + "std_time": 0.16322422391308353, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Shear(shear=10)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1364.130395861408, + 1355.459476973854, + 1335.7458756583628, + 1331.573031020628, + 1321.8152554555581 + ], + "median_throughput": 1335.7458756583628, + "std_throughput": 17.506041740942603, + "times": [ + 1.4661354999989271, + 1.4755144170485437, + 1.4972907919436693, + 1.5019829580560327, + 1.5130707500502467 + ], + "mean_time": 1.4972907919436693, + "std_time": 0.019623219940077062, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "ThinPlateSpline(num_control_points=2, distortion_scale=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 80.58679165079867, + 79.85679919156763, + 69.79150603216426, + 74.95792506502985, + 71.84500926274121 + ], + "median_throughput": 74.95792506502985, + "std_throughput": 4.771115471398106, + "times": [ + 24.81796283274889, + 25.044830499682575, + 28.656782375182956, + 26.681635040789843, + 27.837702583987266 + ], + "mean_time": 26.681635040789846, + "std_time": 1.698301568978463, "variance_stable": true, "early_stopped": false, "early_stop_reason": null diff --git a/output/augly_results.json b/output/augly_results.json index aeac814..440dc75 100644 --- a/output/augly_results.json +++ b/output/augly_results.json @@ -1,16 +1,16 @@ { "metadata": { "system_info": { - "python_version": "3.12.7 | packaged by Anaconda, Inc. | (main, Oct 4 2024, 08:22:19) [Clang 14.0.6 ]", - "platform": "macOS-15.0.1-arm64-arm-64bit", + "python_version": "3.12.8 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 10:37:40) [Clang 14.0.6 ]", + "platform": "macOS-15.1-arm64-arm-64bit", "processor": "arm", - "cpu_count": "10", - "timestamp": "2024-11-02T18:08:28.741550+00:00" + "cpu_count": "16", + "timestamp": "2025-01-23T23:58:28.656651+00:00" }, "library_versions": { "augly": "1.0.0", - "numpy": "2.1.3", - "pillow": "11.0.0", + "numpy": "2.2.2", + "pillow": "11.1.0", "opencv-python-headless": "not installed", "torch": "not installed", "opencv-python": "not installed" @@ -22,8 +22,8 @@ "pillow": "{'threads': 'unknown', 'simd': False}" }, "benchmark_params": { - "num_images": 1000, - "num_runs": 20, + "num_images": 2000, + "num_runs": 5, "max_warmup_iterations": 1000, "warmup_window": 5, "warmup_threshold": 0.05, @@ -31,764 +31,418 @@ } }, "results": { - "HorizontalFlip(p=1.0)": { + "Resize(target_size=512, interpolation=bilinear)": { "supported": true, - "warmup_iterations": 17, + "warmup_iterations": 16, "throughputs": [ - 3241.7275142736635, - 2447.834353994278, - 3941.7689085790753, - 4588.910146525562, - 4299.941713671053, - 2908.0172317779125, - 2988.5270463732772, - 4469.517606307445, - 2759.910233412848, - 5017.293985910462, - 5159.97980972829, - 2495.8407867992337, - 3918.2726685516004, - 3666.236235304671, - 2729.5773617971886, - 4326.416589274426, - 5096.199248560114, - 5369.300488044128, - 5140.6822516239545, - 4900.589508095937 + 1050.16530288884, + 1049.9860510307838, + 1082.5044280722686, + 1087.871679027065, + 1093.8230356231938 ], - "median_throughput": 4120.855311125064, - "std_throughput": 1001.4279081202058, + "median_throughput": 1082.5044280722686, + "std_throughput": 21.190095982696217, "times": [ - 0.3084775002207607, - 0.4085243751760572, - 0.25369320809841156, - 0.2179166660644114, - 0.23256129189394414, - 0.3438769169151783, - 0.3346129998099059, - 0.2237377918791026, - 0.3623306250665337, - 0.19931062497198582, - 0.19379920791834593, - 0.4006665830966085, - 0.25521450000815094, - 0.2727592920418829, - 0.3663570829667151, - 0.2311381669715047, - 0.19622466689907014, - 0.18624399998225272, - 0.1945267089176923, - 0.20405708299949765 + 1.9044620827771723, + 1.9047872093506157, + 1.8475675000809133, + 1.8384521249681711, + 1.8284493330866098 ], - "mean_time": 0.2426680687624004, - "std_time": 0.058971877952675264, + "mean_time": 1.847567500080913, + "std_time": 0.03616625636436747, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "VerticalFlip(p=1.0)": { + "RandomCrop128(height=128, width=128)": { "supported": true, - "warmup_iterations": 20, + "warmup_iterations": 17, "throughputs": [ - 7459.279346779039, - 2961.789944536651, - 5355.779992614105, - 6511.356314098547, - 6940.983977380074, - 6784.747643520724, - 4846.782115601181, - 8159.022074621719, - 8127.977680566088, - 8527.439156392345, - 8065.502656102923, - 7657.444235659582, - 7892.23419263678, - 8131.99304848842, - 7264.034684864436, - 8038.819449628358, - 7925.945235265317, - 7894.059075213587, - 7942.401700703985, - 7623.033382848522 + 45395.178885371504, + 44765.30306763063, + 45504.747706990885, + 45787.93861034798, + 43448.50832548043 ], - "median_throughput": 7774.839214148181, - "std_throughput": 1376.0591057961178, + "median_throughput": 45395.178885371504, + "std_throughput": 934.352639617186, "times": [ - 0.1340612079948187, - 0.33763366704806685, - 0.18671416700817645, - 0.15357783413492143, - 0.14407179201953113, - 0.1473894170485437, - 0.20632245810702443, - 0.1225637081079185, - 0.12303183390758932, - 0.11726850015111268, - 0.12398483301512897, - 0.1305918749421835, - 0.12670683301985264, - 0.12297108396887779, - 0.13766454090364277, - 0.1243963751476258, - 0.126167916925624, - 0.1266775419935584, - 0.12590650003403425, - 0.13118137489072978 + 0.044057541992515326, + 0.0446774591691792, + 0.0439514578320086, + 0.043679625261574984, + 0.0460314997471869 ], - "mean_time": 0.12862002318713686, - "std_time": 0.022764297655480013, + "mean_time": 0.044057541992515326, + "std_time": 0.0009068205405622298, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Rotate(angle=45, p=1.0, interpolation=nearest, mode=reflect)": { + "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear)": { + "supported": false + }, + "CenterCrop128(height=128, width=128)": { + "supported": false + }, + "HorizontalFlip()": { "supported": true, - "warmup_iterations": 18, + "warmup_iterations": 16, "throughputs": [ - 1054.2010901319004, - 970.9313673725524, - 865.349522749395, - 1098.8069156786494, - 1126.0607144689773, - 1112.9027298381525, - 980.1091743136664, - 1074.9493664896847, - 1113.0224177806704, - 1116.191176342393, - 1142.1434127066893, - 1060.0281573116697, - 1091.6621886020762, - 1115.7984463171078, - 1120.2862030806095, - 1133.9253205876755, - 1100.5746869887369, - 862.9818232433488, - 1075.2937731905001, - 1080.9803851157428 + 8808.419076819217, + 10534.412990935896, + 10430.039221544415, + 8496.262432067686, + 8638.537700325796 ], - "median_throughput": 1095.2345521403627, - "std_throughput": 81.99355443772939, + "median_throughput": 8808.419076819217, + "std_throughput": 1011.5215189058365, "times": [ - 0.9485856250394136, - 1.0299389159772545, - 1.1556024169549346, - 0.9100779998116195, - 0.8880515829659998, - 0.8985511250793934, - 1.0202945000492036, - 0.9302763750310987, - 0.8984545001294464, - 0.8959038748871535, - 0.8755467911250889, - 0.9433711671736091, - 0.9160342919640243, - 0.8962192081380635, - 0.8926290418021381, - 0.8818922920618206, - 0.9086162091698498, - 1.1587729579769075, - 0.9299784160684794, - 0.9250861660111696 + 0.22705550026148558, + 0.18985395785421133, + 0.19175383308902383, + 0.2353976252488792, + 0.23152066580951214 ], - "mean_time": 0.9130464319681565, - "std_time": 0.06835423716084629, + "mean_time": 0.22705550026148555, + "std_time": 0.026074091445630724, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Affine(angle=25.0, shift=(50, 50), scale=2.0, shear=[10.0, 15.0], p=1.0, interpolation=bilinear, mode=reflect)": { - "supported": false - }, - "Equalize(p=1.0)": { - "supported": false - }, - "RandomCrop80(height=80, width=80, p=1.0)": { + "VerticalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 25475.272986829692, - 26308.462709782492, - 11394.133933124403, - 6749.706822012376, - 10327.986689891564, - 21511.698927281792, - 24163.90355998447, - 24841.917275947522, - 24281.02844523507, - 27265.105194369655, - 24276.926974131078, - 25585.944915680175, - 26690.74741012952, - 25973.576718949385, - 25512.02107965949, - 24907.99612671042, - 26485.739482112098, - 22455.84640347615, - 25833.924195868327, - 26468.943708731284 + 16829.922650066146, + 15771.896351022997, + 19943.137137215206, + 16380.363057512666, + 18072.05768429302 ], - "median_throughput": 25191.634556770055, - "std_throughput": 5964.147781493371, + "median_throughput": 16829.922650066146, + "std_throughput": 1653.3735077678014, "times": [ - 0.039253750117495656, - 0.038010582793504, - 0.08776445896364748, - 0.14815458306111395, - 0.0968242920935154, - 0.04648633301258087, - 0.04138404200784862, - 0.04025454190559685, - 0.041184416972100735, - 0.03667691699229181, - 0.04119137488305569, - 0.03908395813778043, - 0.037466167006641626, - 0.03850066591985524, - 0.03919720812700689, - 0.04014774993993342, - 0.03775616688653827, - 0.04453183291479945, - 0.03870879206806421, - 0.03778012492693961 + 0.1188359591178596, + 0.12680783309042454, + 0.10028512496501207, + 0.12209741584956646, + 0.11066808411851525 ], - "mean_time": 0.03969571715350474, - "std_time": 0.009398005630096705, + "mean_time": 0.11883595911785962, + "std_time": 0.011674458086405664, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear, p=1.0)": { + "Pad(padding=10, fill=0, border_mode=constant)": { "supported": false }, - "ShiftRGB(pixel_shift=100, p=1.0, per_channel=True)": { - "supported": false - }, - "Resize(target_size=512, interpolation=bilinear, p=1.0)": { + "Rotate(angle=45, interpolation=nearest, mode=constant, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 635.712483602099, - 562.4114024492757, - 631.1280562142102, - 560.9313555107776, - 583.4973811917799, - 631.8223821905177, - 647.0883787351574, - 640.4503646662301, - 548.6261406633939, - 633.783864928797, - 635.363254352138, - 556.415965351621, - 631.6657016567384, - 558.8388111807304, - 632.4853822981329, - 646.7242069751262, - 644.3728519500512, - 643.3501907141231, - 644.7784271638051, - 567.4249293975661 + 1554.7296913344674, + 1582.3085769976494, + 1740.8390427286595, + 1787.9325720526006, + 1738.68266049048 ], - "median_throughput": 632.1538822443254, - "std_throughput": 37.90384998845349, + "median_throughput": 1738.68266049048, + "std_throughput": 104.91271567837464, "times": [ - 1.5730381670873612, - 1.7780578339006752, - 1.5844644999597222, - 1.782749333186075, - 1.7138037499971688, - 1.582723290892318, - 1.545383958145976, - 1.5614012500736862, - 1.822734875138849, - 1.577824957901612, - 1.573902792064473, - 1.7972165830433369, - 1.5831158750224859, - 1.7894247500225902, - 1.581064207945019, - 1.5462541671004146, - 1.5518965409137309, - 1.5543634158093482, - 1.550920374924317, - 1.762347666081041 + 1.2863972503691912, + 1.26397595833987, + 1.1488712918944657, + 1.1186104170046747, + 1.1502961670048535 ], - "mean_time": 1.5818933144090117, - "std_time": 0.09485008092368623, + "mean_time": 1.1502961670048535, + "std_time": 0.06940927028101866, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomGamma(gamma=120, p=1.0)": { + "Affine(angle=25.0, shift=(20, 20), scale=2.0, shear=(10.0, 15.0), interpolation=bilinear, mode=constant, fill=0)": { "supported": false }, - "Grayscale(p=1.0, num_output_channels=3)": { + "Perspective(scale=(0.05, 0.1), interpolation=bilinear, fill=0)": { + "supported": false + }, + "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True)": { + "supported": false + }, + "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 3267.6521620006183, - 3369.7524034031917, - 3371.88806404848, - 3392.753163406204, - 3356.693119753887, - 3472.342283177366, - 3408.308544537698, - 3354.785793030886, - 3401.7365854143645, - 3333.2370342568433, - 3461.1287864214264, - 3361.395846007976, - 3309.2265344636808, - 3389.670594796287, - 3241.8457465137126, - 3338.676149277705, - 3349.9303739943707, - 3248.129925436118, - 3257.3068875910008, - 3395.4478573379774 + 414.24576333610673, + 424.4618571116887, + 412.80352445109884, + 419.7383278254062, + 418.3226141895712 ], - "median_throughput": 3359.0444828809314, - "std_throughput": 64.52743476205183, + "median_throughput": 418.3226141895712, + "std_throughput": 4.635258623118236, "times": [ - 0.30603012512438, - 0.2967577080707997, - 0.2965697499457747, - 0.29474587505683303, - 0.297912250040099, - 0.28799004200845957, - 0.29340066690929234, - 0.2980816247873008, - 0.293967500096187, - 0.30000866716727614, - 0.28892308310605586, - 0.29749545897357166, - 0.3021854169201106, - 0.29501391714438796, - 0.30846624984405935, - 0.29951991606503725, - 0.29851366695947945, - 0.3078694581054151, - 0.3070020831655711, - 0.29451195895671844 + 4.8280517919920385, + 4.711848583072424, + 4.8449198747985065, + 4.764873416163027, + 4.780998999718577 ], - "mean_time": 0.29770370862797746, - "std_time": 0.005718905103762403, + "mean_time": 4.780998999718577, + "std_time": 0.05297625824866935, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5, p=1.0)": { + "ChannelShuffle()": { + "supported": false + }, + "Grayscale(num_output_channels=1)": { "supported": true, - "warmup_iterations": 16, + "warmup_iterations": 21, "throughputs": [ - 252.9440500085872, - 264.118088540553, - 237.92881771104078, - 262.06974206512, - 256.63915057362874, - 213.91957565324768, - 222.26461099091068, - 233.23641456561217, - 229.8020117810596, - 226.23618847846961, - 238.5572818563759, - 259.01613861079915, - 248.14402999045248, - 230.93240893461316, - 259.979897045149, - 261.0878601810458, - 251.52984116405293, - 254.01410823433721, - 251.76300980953778, - 258.8090791991561 + 6057.422865374584, + 6087.9626901404645, + 6276.162933843943, + 6022.44639934216, + 6205.354593139259 ], - "median_throughput": 251.64642548679535, - "std_throughput": 15.201506480691371, + "median_throughput": 6087.9626901404645, + "std_throughput": 106.82250021344477, "times": [ - 3.953443459002301, - 3.786185208009556, - 4.202937708934769, - 3.815778166987002, - 3.8965216248761863, - 4.6746539999730885, - 4.499141791136935, - 4.287495166063309, - 4.351571999955922, - 4.4201593331526965, - 4.191865334054455, - 3.860763292061165, - 4.029917625011876, - 4.330271375132725, - 3.8464512501377612, - 3.8301282920874655, - 3.9756714168470353, - 3.9367892080917954, - 3.9719893750734627, - 3.8638520839158446 + 0.3301734160631895, + 0.3285171249881387, + 0.31866604182869196, + 0.33209095895290375, + 0.3223022907041013 ], - "mean_time": 3.9738295430406305, - "std_time": 0.2400518721251011, + "mean_time": 0.3285171249881387, + "std_time": 0.005764329126227944, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "PlankianJitter(mode=blackbody, p=1.0)": { + "RGBShift(pixel_shift=100)": { "supported": false }, - "RandomPerspective(scale=(0.05, 0.1), p=1.0, interpolation=bilinear)": { - "supported": false - }, - "GaussianBlur(sigma=2.0, kernel_size=(5, 5), p=1.0)": { + "GaussianBlur(sigma=2.0, kernel_size=(5, 5))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 196.752559653053, - 210.34504264202883, - 244.62537168234107, - 243.2928100170488, - 223.13416535608945, - 241.63069792313303, - 228.62408395889264, - 231.94846795293424, - 236.58705432260373, - 208.4081865987477, - 180.40522757216527, - 237.36361893033276, - 229.9423095589955, - 210.26057962019834, - 233.24473789345066, - 238.73219594401615, - 239.46647112074905, - 241.85740196519401, - 238.4033981604823, - 241.89139480399234 + 384.41777910508904, + 386.7694861044822, + 381.51304764292047, + 391.020845001914, + 390.8052512936959 ], - "median_throughput": 234.9158961080272, - "std_throughput": 17.651184506925034, + "median_throughput": 386.7694861044822, + "std_throughput": 4.1057862174494915, "times": [ - 5.082525999983773, - 4.754093500087038, - 4.0878834158647805, - 4.110273542115465, - 4.481608625035733, - 4.1385470000095665, - 4.373992375098169, - 4.311302457936108, - 4.22677395795472, - 4.798276000190526, - 5.543076625093818, - 4.212945541134104, - 4.348916917107999, - 4.756003249902278, - 4.287342166993767, - 4.188794041983783, - 4.175949957920238, - 4.134667749982327, - 4.194571082945913, - 4.134086707839742 + 5.202672999817878, + 5.17103875009343, + 5.242284667212516, + 5.114816832821816, + 5.117638499941677 ], - "mean_time": 4.256842625669509, - "std_time": 0.3198519804214654, + "mean_time": 5.17103875009343, + "std_time": 0.054893626288541914, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MedianBlur(blur_limit=5, p=1.0)": { + "Invert()": { + "supported": false + }, + "Posterize(bits=4)": { + "supported": false + }, + "Solarize(threshold=0.5)": { + "supported": false + }, + "Sharpen(alpha=(0.2, 0.5), lightness=(0.5, 1))": { + "supported": false + }, + "AutoContrast()": { + "supported": false + }, + "Equalize()": { "supported": false }, - "MotionBlur(kernel_size=5, angle=45, direction=0.0, p=1.0)": { + "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))": { "supported": false }, - "Posterize(bits=4, p=1.0)": { + "Erasing(scale=(0.02, 0.33), ratio=(0.3, 3.3), fill=0)": { "supported": false }, - "JpegCompression(quality=50, p=1.0)": { + "JpegCompression(quality=50)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 759.4699977592936, - 757.2306296942144, - 737.114410831614, - 764.6067850404668, - 753.0550506559146, - 758.932925184639, - 755.7650704004087, - 723.0610720641112, - 752.826297958913, - 756.2226964442727, - 755.2833251672663, - 752.3127740811364, - 746.327648294097, - 715.983340430127, - 758.113640413622, - 753.5395638688225, - 762.3420070480083, - 753.992057893477, - 748.1027417418138, - 722.744078532869 + 1201.8376696245994, + 1224.4720535145607, + 1213.4784694469554, + 1176.566502170569, + 1191.4178003304642 ], - "median_throughput": 753.7658108811497, - "std_throughput": 13.773952444115814, + "median_throughput": 1201.8376696245994, + "std_throughput": 18.672360638219956, "times": [ - 1.3167077079415321, - 1.3206016249023378, - 1.356641500024125, - 1.3078617919236422, - 1.3279241658747196, - 1.3176394999027252, - 1.3231625000480562, - 1.3830090411938727, - 1.3283276669681072, - 1.322361791972071, - 1.3240064578130841, - 1.3292343749199063, - 1.3398940830957144, - 1.3966805420350283, - 1.3190634578932077, - 1.3270703330636024, - 1.31174720893614, - 1.3262739169877023, - 1.3367147909011692, - 1.383615625090897 + 1.6641182503663003, + 1.6333570000715554, + 1.6481544999405742, + 1.6998614156618714, + 1.6786722503602505 ], - "mean_time": 1.3266720055012886, - "std_time": 0.02424296359548707, + "mean_time": 1.6641182503663003, + "std_time": 0.02585458660585085, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianNoise(mean=127, var=0.01, per_channel=True, p=1.0)": { - "supported": true, - "warmup_iterations": 20, - "throughputs": [ - 67.8011792789446, - 68.64781672227694, - 68.82963685730876, - 71.37720342221878, - 71.02533628850576, - 71.98643674804471, - 70.39510838559134, - 70.00159801810064, - 68.62886210731787, - 70.15852998202955, - 71.13338524143973, - 70.31489503071334, - 69.50143743302345, - 67.81451971789608, - 69.28990890326153, - 69.06508110477932, - 68.61157045409217, - 68.34592334694966, - 69.81046824413826, - 70.64910136132018 - ], - "median_throughput": 69.65595283858086, - "std_throughput": 1.2076533615818505, - "times": [ - 14.749006000114605, - 14.567105666967109, - 14.528625250095502, - 14.010075374972075, - 14.079482791014016, - 13.891505749896169, - 14.205532499821857, - 14.285388167016208, - 14.571128957904875, - 14.253434333018959, - 14.058096583001316, - 14.221737792016938, - 14.388191625010222, - 14.746104582911357, - 14.432115957839414, - 14.47909687506035, - 14.574801208917052, - 14.631450582994148, - 14.324499249923974, - 14.15446170908399 - ], - "mean_time": 14.356274794164076, - "std_time": 0.24890052907814417, - "variance_stable": true, - "early_stopped": false, - "early_stop_reason": null + "RandomGamma(gamma=120)": { + "supported": false }, - "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True, p=1.0)": { + "PlankianJitter(mode=blackbody)": { "supported": false }, - "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), p=1.0)": { + "MedianBlur(blur_limit=5)": { "supported": false }, - "Clahe(clip_limit=(1, 4), tile_grid_size=(8, 8), p=1.0)": { + "MotionBlur(kernel_size=5, angle_range=(0, 360), direction_range=(-1, 1))": { "supported": false }, - "Brightness(brightness_limit=(0.2, 0.2), p=1.0)": { + "CLAHE(clip_limit=(1, 4), tile_grid_size=(8, 8))": { + "supported": false + }, + "Brightness(brightness_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 1299.0015165599787, - 1297.4918512133286, - 1293.8389712488533, - 1298.4586809869807, - 1305.0944958798796, - 1298.8557140999667, - 1284.4985546932025, - 1143.8674495886692, - 1305.3892996990257, - 1295.7203004316589, - 1283.7481335968328, - 1252.1084989142894, - 1289.178262816638, - 1301.8530087568586, - 1292.0250660186216, - 1292.0133127177578, - 1301.5689762839859, - 1304.5703113690877, - 1299.0835718926917, - 1188.3335343721235 + 2125.948262993417, + 2083.5362614465307, + 2108.3773603554478, + 2103.5255344652905, + 2168.398458281695 ], - "median_throughput": 1296.6060758224937, - "std_throughput": 41.72055467929612, + "median_throughput": 2108.3773603554478, + "std_throughput": 31.9883765351776, "times": [ - 0.7698220419697464, - 0.770717749837786, - 0.772893707966432, - 0.7701438749209046, - 0.7662280418444425, - 0.7699084579944611, - 0.7785139160696417, - 0.8742271671071649, - 0.7660550000146031, - 0.7717715001199394, - 0.7789690000936389, - 0.7986528330948204, - 0.7756879159715027, - 0.7681358749978244, - 0.7739787921309471, - 0.7739858329296112, - 0.7683035000227392, - 0.766535917064175, - 0.7697734169196337, - 0.8415145841427147 + 0.940756666008383, + 0.9599064998328686, + 0.9485967918299139, + 0.9507847502827644, + 0.9223397076129913 ], - "mean_time": 0.7712442650445367, - "std_time": 0.02481612505978197, + "mean_time": 0.9485967918299139, + "std_time": 0.014392144370209475, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Contrast(contrast_limit=(0.2, 0.2), p=1.0)": { + "Contrast(contrast_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 885.1025516702621, - 879.5878339052148, - 876.6517714994122, - 885.2466560856083, - 877.732197232541, - 875.6465829718582, - 888.3717246890324, - 880.2167975355675, - 886.2027751918422, - 849.8745175850174, - 882.7392368286675, - 873.320114107716, - 879.030045622893, - 887.9338335380628, - 881.5880664187727, - 880.3832775466961, - 879.8433174561546, - 861.3894763931858, - 873.2626622701156, - 875.4916618211894 + 1368.873627555974, + 1325.1797963257934, + 1379.3160522085602, + 1384.2671744712575, + 1383.8236780291913 ], - "median_throughput": 879.7155756806847, - "std_throughput": 9.044965584299083, + "median_throughput": 1379.3160522085602, + "std_throughput": 24.884580291443484, "times": [ - 1.129812582861632, - 1.1368961250409484, - 1.1407037919852883, - 1.1296286669094115, - 1.1392996669746935, - 1.1420132499188185, - 1.1256549169775099, - 1.1360837498214096, - 1.1284099170006812, - 1.1766442919615656, - 1.1328373751603067, - 1.1450555000919849, - 1.137617542175576, - 1.1262100420426577, - 1.1343166248407215, - 1.1358689169865102, - 1.136566000059247, - 1.160915041808039, - 1.145130833145231, - 1.1422153329476714 + 1.4610552499070764, + 1.5092291668988764, + 1.4499940001405776, + 1.444807792082429, + 1.445270833093673 ], - "mean_time": 1.1367310385816969, - "std_time": 0.011687519701604107, + "mean_time": 1.4499940001405776, + "std_time": 0.02615969854105174, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "CoarseDropout(hole_height_range=(16, 16), hole_width_range=(16, 16), num_holes_range=(1, 1), p=1.0)": { + "CoarseDropout(hole_height_range=(0.1, 0.1), hole_width_range=(0.1, 0.1), num_holes_range=(4, 4))": { "supported": false }, - "Blur(radius=5, p=1.0)": { + "Blur(radius=5, border_mode=constant)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 243.48089046250112, - 243.15675341289452, - 243.28203027519785, - 244.1412979970703, - 240.8076544035112, - 243.17949899867136, - 244.3248653384007, - 244.39103977859614, - 238.5083141746531, - 241.45891403936918, - 243.30027576382122, - 243.02256888424964, - 242.11874726111546, - 243.6799374835546, - 243.2645223208831, - 243.25223618073278, - 243.84561110003733, - 209.82980782180633, - 215.99684706332698, - 238.76649410249775 + 381.5071408115098, + 383.425916315969, + 386.2404914786257, + 386.9946357581195, + 392.64244018626266 ], - "median_throughput": 243.21586758970207, - "std_throughput": 9.356063902649074, + "median_throughput": 386.2404914786257, + "std_throughput": 4.2382017453845755, "times": [ - 4.107098500011489, - 4.112573415972292, - 4.110455666901544, - 4.095988709013909, - 4.152691917028278, - 4.112188749946654, - 4.092911290936172, - 4.0918030419852585, - 4.192725957836956, - 4.141491333954036, - 4.110147417057306, - 4.1148441669065505, - 4.130204749992117, - 4.103743666084483, - 4.110751499887556, - 4.11095912498422, - 4.100955500034615, - 4.765767125179991, - 4.629697208991274, - 4.188192333094776 + 5.242365832906216, + 5.216131499968469, + 5.178121000062674, + 5.168030290864408, + 5.0936928750015795 ], - "mean_time": 4.111573845531206, - "std_time": 0.15816462971957562, + "mean_time": 5.178121000062674, + "std_time": 0.05681931838959619, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "HSV(hue=0.015, saturation=0.7, value=0.4, p=1.0)": { + "HSV(hue=0.015, saturation=0.7, value=0.4)": { + "supported": false + }, + "ChannelDropout()": { + "supported": false + }, + "LinearIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "CornerIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "GaussianIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "Hue(hue=20)": { + "supported": false + }, + "PlasmaBrightness(roughness=0.5)": { + "supported": false + }, + "PlasmaContrast(roughness=0.5)": { + "supported": false + }, + "PlasmaShadow(roughness=0.5)": { + "supported": false + }, + "Rain(drop_width=5, drop_height=20)": { + "supported": false + }, + "SaltAndPepper(amount=(0.01, 0.06), salt_vs_pepper=(0.4, 0.6))": { + "supported": false + }, + "Saturation(saturation_factor=0.5)": { + "supported": false + }, + "Snow(snow_point_range=(0.5, 0.5))": { + "supported": false + }, + "OpticalDistortion(distort_limit=0.5)": { + "supported": false + }, + "Shear(shear=10)": { + "supported": false + }, + "ThinPlateSpline(num_control_points=4, distortion_scale=0.5)": { "supported": false } } diff --git a/output/comparison.md b/output/comparison.md index bc7142a..97886db 100644 --- a/output/comparison.md +++ b/output/comparison.md @@ -2,55 +2,78 @@ ### System Information -- Platform: macOS-15.0.1-arm64-arm-64bit +- Platform: macOS-15.1-arm64-arm-64bit - Processor: arm -- CPU Count: 10 -- Python Version: 3.12.7 +- CPU Count: 16 +- Python Version: 3.12.8 ### Benchmark Parameters -- Number of images: 1000 -- Runs per transform: 20 +- Number of images: 2000 +- Runs per transform: 5 - Max warmup iterations: 1000 ### Library Versions -- albumentations: 1.4.21 +- albumentations: 2.0.2 - augly: 1.0.0 - imgaug: 0.4.0 -- kornia: 0.7.3 +- kornia: 0.8.0 - torchvision: 0.20.1 ## Performance Comparison -| Transform | albumentations
1.4.21 | augly
1.0.0 | imgaug
0.4.0 | kornia
0.7.3 | torchvision
0.20.1 | -|:------------------|:---------------------------|:-----------------|:------------------|:------------------|:------------------------| -| HorizontalFlip | **8622 ± 891** | 4121 ± 1001 | 6162 ± 393 | 571 ± 84 | 861 ± 38 | -| VerticalFlip | **23951 ± 5013** | 7775 ± 1376 | 11663 ± 2258 | 1590 ± 100 | 3156 ± 402 | -| Rotate | 1163 ± 84 | 1095 ± 82 | **1224 ± 75** | 167 ± 11 | 160 ± 11 | -| Affine | **907 ± 49** | - | 890 ± 34 | 181 ± 6 | 129 ± 16 | -| Equalize | **852 ± 90** | - | 610 ± 35 | 184 ± 9 | 416 ± 44 | -| RandomCrop80 | **107764 ± 3630** | 25192 ± 5964 | 12343 ± 2013 | 1492 ± 22 | 28767 ± 858 | -| ShiftRGB | **2351 ± 276** | - | 1674 ± 63 | - | - | -| Resize | **2372 ± 156** | 632 ± 38 | 2025 ± 74 | 332 ± 18 | 180 ± 11 | -| RandomGamma | **9014 ± 371** | - | 2592 ± 143 | 128 ± 10 | - | -| Grayscale | **11373 ± 923** | 3359 ± 65 | 1849 ± 75 | 628 ± 75 | 1497 ± 317 | -| RandomPerspective | 401 ± 24 | - | **596 ± 38** | 98 ± 7 | 106 ± 4 | -| GaussianBlur | **1664 ± 144** | 235 ± 18 | 1043 ± 142 | 165 ± 12 | 82 ± 3 | -| MedianBlur | 847 ± 36 | - | **849 ± 32** | 4 ± 0 | - | -| MotionBlur | **3928 ± 742** | - | 663 ± 36 | 75 ± 6 | - | -| Posterize | **9034 ± 331** | - | 2400 ± 142 | 363 ± 69 | 3052 ± 380 | -| JpegCompression | **906 ± 40** | 754 ± 14 | 443 ± 79 | 69 ± 3 | 606 ± 42 | -| GaussianNoise | 183 ± 5 | 70 ± 1 | **204 ± 18** | 65 ± 2 | - | -| Elastic | 229 ± 17 | - | **251 ± 22** | 1 ± 0 | 3 ± 0 | -| Clahe | **471 ± 18** | - | 422 ± 12 | 90 ± 2 | - | -| Brightness | **9251 ± 709** | 1297 ± 42 | 742 ± 39 | 519 ± 15 | 449 ± 14 | -| Contrast | **9146 ± 1034** | 880 ± 9 | 510 ± 9 | 476 ± 116 | 358 ± 4 | -| CoarseDropout | **14488 ± 2108** | - | 653 ± 85 | 526 ± 86 | - | -| Blur | **5804 ± 305** | 243 ± 9 | 3857 ± 385 | - | - | -| ColorJitter | **700 ± 31** | 252 ± 15 | - | 50 ± 4 | 47 ± 2 | -| RandomResizedCrop | **2879 ± 158** | - | - | 321 ± 10 | 462 ± 47 | -| Normalize | **1349 ± 65** | - | - | 645 ± 40 | 528 ± 20 | -| PlankianJitter | **2155 ± 340** | - | - | 1023 ± 114 | - | -| HSV | **1243 ± 44** | - | - | - | - | +| Transform | albumentations
2.0.2 | augly
1.0.0 | imgaug
0.4.0 | kornia
0.8.0 | torchvision
0.20.1 | +|:---------------------|:--------------------------|:-----------------|:------------------|:------------------|:------------------------| +| Resize | **3662 ± 54** | 1083 ± 21 | 2995 ± 70 | 645 ± 13 | 260 ± 9 | +| RandomCrop128 | **116784 ± 2222** | 45395 ± 934 | 21408 ± 622 | 2946 ± 42 | 31450 ± 249 | +| HorizontalFlip | **12649 ± 238** | 8808 ± 1012 | 9599 ± 495 | 1297 ± 13 | 2486 ± 107 | +| VerticalFlip | **24989 ± 904** | 16830 ± 1653 | 19935 ± 1708 | 2872 ± 37 | 4696 ± 161 | +| Rotate | **3066 ± 83** | 1739 ± 105 | 2574 ± 10 | 256 ± 2 | 258 ± 4 | +| Affine | **1503 ± 29** | - | 1328 ± 16 | 248 ± 6 | 188 ± 2 | +| Perspective | **1222 ± 16** | - | 908 ± 8 | 154 ± 3 | 147 ± 5 | +| Elastic | 359 ± 7 | - | **395 ± 14** | 1 ± 0 | 3 ± 0 | +| ChannelShuffle | **8162 ± 180** | - | 1252 ± 26 | 1328 ± 44 | 4417 ± 234 | +| Grayscale | **37212 ± 1856** | 6088 ± 107 | 3100 ± 24 | 1201 ± 52 | 2600 ± 23 | +| GaussianBlur | 943 ± 11 | 387 ± 4 | **1460 ± 23** | 254 ± 5 | 127 ± 4 | +| GaussianNoise | 234 ± 7 | - | **263 ± 9** | 125 ± 1 | - | +| Invert | **35494 ± 17186** | - | 3682 ± 79 | 2881 ± 43 | 4244 ± 30 | +| Posterize | **14146 ± 1381** | - | 3111 ± 95 | 836 ± 30 | 4247 ± 26 | +| Solarize | **12920 ± 1097** | - | 3843 ± 80 | 263 ± 6 | 1032 ± 14 | +| Sharpen | **2375 ± 38** | - | 1101 ± 30 | 201 ± 2 | 220 ± 3 | +| Equalize | **1303 ± 64** | - | 814 ± 11 | 306 ± 1 | 795 ± 3 | +| JpegCompression | **1354 ± 23** | 1202 ± 19 | 687 ± 26 | 120 ± 1 | 889 ± 7 | +| RandomGamma | **12631 ± 1159** | - | 3504 ± 72 | 230 ± 3 | - | +| MedianBlur | **1259 ± 8** | - | 1152 ± 14 | 6 ± 0 | - | +| MotionBlur | **3608 ± 18** | - | 928 ± 37 | 159 ± 1 | - | +| CLAHE | **649 ± 13** | - | 555 ± 14 | 165 ± 3 | - | +| Brightness | **11254 ± 418** | 2108 ± 32 | 1076 ± 32 | 1127 ± 27 | 854 ± 13 | +| Contrast | **11255 ± 242** | 1379 ± 25 | 717 ± 5 | 1109 ± 41 | 602 ± 13 | +| CoarseDropout | **15760 ± 594** | - | 1190 ± 22 | - | - | +| Blur | **7403 ± 114** | 386 ± 4 | 5381 ± 125 | 265 ± 11 | - | +| Saturation | **1581 ± 127** | - | 495 ± 3 | 155 ± 2 | - | +| Shear | **1336 ± 18** | - | 1244 ± 14 | 261 ± 1 | - | +| ColorJitter | **968 ± 52** | 418 ± 5 | - | 104 ± 4 | 87 ± 1 | +| RandomResizedCrop | **4521 ± 17** | - | - | 661 ± 16 | 837 ± 37 | +| Pad | **31866 ± 530** | - | - | - | 4889 ± 183 | +| AutoContrast | **1534 ± 115** | - | - | 541 ± 8 | 344 ± 1 | +| Normalize | **1797 ± 190** | - | - | 1251 ± 14 | 1018 ± 7 | +| Erasing | **25411 ± 5727** | - | - | 1210 ± 27 | 3577 ± 49 | +| CenterCrop128 | **119630 ± 3484** | - | - | - | - | +| RGBShift | **3526 ± 128** | - | - | 896 ± 9 | - | +| PlankianJitter | **3351 ± 42** | - | - | 2150 ± 52 | - | +| HSV | **1277 ± 91** | - | - | - | - | +| ChannelDropout | **10988 ± 243** | - | - | 2283 ± 24 | - | +| LinearIllumination | 462 ± 52 | - | - | **708 ± 6** | - | +| CornerIllumination | **464 ± 45** | - | - | 452 ± 3 | - | +| GaussianIllumination | **670 ± 91** | - | - | 436 ± 13 | - | +| Hue | **1846 ± 193** | - | - | 150 ± 1 | - | +| PlasmaBrightness | **163 ± 1** | - | - | 85 ± 1 | - | +| PlasmaContrast | **138 ± 4** | - | - | 84 ± 0 | - | +| PlasmaShadow | 190 ± 3 | - | - | **216 ± 5** | - | +| Rain | **2121 ± 64** | - | - | 1493 ± 9 | - | +| SaltAndPepper | **2233 ± 35** | - | - | 480 ± 12 | - | +| Snow | **588 ± 32** | - | - | 143 ± 1 | - | +| OpticalDistortion | **687 ± 38** | - | - | 174 ± 0 | - | +| ThinPlateSpline | **75 ± 5** | - | - | 58 ± 0 | - | diff --git a/output/imgaug_results.json b/output/imgaug_results.json index 9c61193..3a76eac 100644 --- a/output/imgaug_results.json +++ b/output/imgaug_results.json @@ -1,19 +1,19 @@ { "metadata": { "system_info": { - "python_version": "3.12.7 | packaged by Anaconda, Inc. | (main, Oct 4 2024, 08:22:19) [Clang 14.0.6 ]", - "platform": "macOS-15.0.1-arm64-arm-64bit", + "python_version": "3.12.8 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 10:37:40) [Clang 14.0.6 ]", + "platform": "macOS-15.1-arm64-arm-64bit", "processor": "arm", - "cpu_count": "10", - "timestamp": "2024-11-02T16:41:56.062018+00:00" + "cpu_count": "16", + "timestamp": "2025-01-25T02:20:05.295158+00:00" }, "library_versions": { "imgaug": "0.4.0", "numpy": "1.26.4", - "pillow": "11.0.0", + "pillow": "11.1.0", "opencv-python-headless": "not installed", "torch": "not installed", - "opencv-python": "4.10.0.84" + "opencv-python": "4.11.0.86" }, "thread_settings": { "environment": "{'OMP_NUM_THREADS': '1', 'OPENBLAS_NUM_THREADS': '1', 'MKL_NUM_THREADS': '1', 'VECLIB_MAXIMUM_THREADS': '1', 'NUMEXPR_NUM_THREADS': '1'}", @@ -22,8 +22,8 @@ "pillow": "{'threads': 'unknown', 'simd': False}" }, "benchmark_params": { - "num_images": 1000, - "num_runs": 20, + "num_images": 2000, + "num_runs": 5, "max_warmup_iterations": 1000, "warmup_window": 5, "warmup_threshold": 0.05, @@ -31,1284 +31,770 @@ } }, "results": { - "HorizontalFlip(p=1.0)": { + "Resize(target_size=512, interpolation=bilinear)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 4574.235843561762, - 6243.33391255051, - 6166.598368616923, - 5905.164521741738, - 6436.122980066613, - 5868.359490263609, - 6204.729708611467, - 6113.6636952986255, - 6284.747780513081, - 5992.699410558621, - 6079.225990733306, - 6364.1334562872535, - 6158.248490519357, - 6146.80570057985, - 6172.46484716778, - 6247.122105291933, - 6212.1447382427505, - 5644.349547275563, - 6117.690600790493, - 6267.054848616496 - ], - "median_throughput": 6162.42342956814, - "std_throughput": 392.9200185307556, + 2871.140178629343, + 3032.837097878637, + 2991.0565509426106, + 3051.8363965283115, + 2995.316446395427 + ], + "median_throughput": 2995.316446395427, + "std_throughput": 70.36260602183674, "times": [ - 0.21861575008369982, - 0.1601708340458572, - 0.1621639581862837, - 0.16934329201467335, - 0.15537304105237126, - 0.17040537507273257, - 0.1611673750448972, - 0.1635680419858545, - 0.15911537501960993, - 0.16686970787122846, - 0.16449462505988777, - 0.1571305829565972, - 0.16238383390009403, - 0.16268612490966916, - 0.1620098331477493, - 0.16007370804436505, - 0.16097500012256205, - 0.17716833297163248, - 0.16346037504263222, - 0.1595645840279758 - ], - "mean_time": 0.16227382156212522, - "std_time": 0.01034668157811335, + 0.6965873748995364, + 0.6594485412351787, + 0.6686600423417985, + 0.6553431246429682, + 0.6677090837620199 + ], + "mean_time": 0.6677090837620199, + "std_time": 0.015685071022958717, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "VerticalFlip(p=1.0)": { + "RandomCrop128(height=128, width=128)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 12203.592431960249, - 12082.852199825746, - 12858.070450925306, - 10621.334804164884, - 10289.803775445678, - 10494.48259066556, - 11783.368664961052, - 10713.482124669652, - 4442.313770650139, - 7178.108890835767, - 12066.50449385896, - 12221.340595093901, - 12933.82189644121, - 10331.823672006734, - 11000.379084401742, - 10387.137351469002, - 11541.907547708268, - 12889.435411780772, - 14263.35993260443, - 14302.698719679263 - ], - "median_throughput": 11662.63810633466, - "std_throughput": 2257.5478482280355, + 20358.711935300194, + 21708.966050684176, + 21407.765629167334, + 21892.217294699953, + 20923.639092158137 + ], + "median_throughput": 21407.765629167334, + "std_throughput": 622.2032628991525, "times": [ - 0.08194308402016759, - 0.0827619160991162, - 0.07777216681279242, - 0.09415012504905462, - 0.09718358307145536, - 0.09528816607780755, - 0.08486537495627999, - 0.09334033401682973, - 0.22510791709646583, - 0.13931245892308652, - 0.0828740419819951, - 0.08182408404536545, - 0.07731666695326567, - 0.09678833396174014, - 0.09090595808811486, - 0.09627291583456099, - 0.0866407910361886, - 0.07758291717618704, - 0.07010970800183713, - 0.06991687510162592 - ], - "mean_time": 0.08574389352412827, - "std_time": 0.016597526268001907, + 0.09823804209008813, + 0.09212783304974437, + 0.09342404222115874, + 0.0913566667586565, + 0.09558566706255078 + ], + "mean_time": 0.09342404222115874, + "std_time": 0.002715311112339289, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Rotate(angle=45, p=1.0, interpolation=nearest, mode=reflect)": { + "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear)": { + "supported": false + }, + "CenterCrop128(height=128, width=128)": { + "supported": false + }, + "HorizontalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 1220.8781777596732, - 1220.8946976345624, - 1227.658909766594, - 1233.6147693531161, - 1239.488683573918, - 1219.0352965754973, - 1220.5579798653466, - 1254.8886399178011, - 1230.8364533142403, - 1223.095342259764, - 1216.7273864668207, - 1185.001845788932, - 1179.1860678204616, - 903.2934077095716, - 1224.3714808053014, - 1227.264289373592, - 1240.1294099647644, - 1206.639169517073, - 1252.9085756750574, - 1268.025376979914 - ], - "median_throughput": 1223.7334115325327, - "std_throughput": 75.08195317895603, + 9251.012958631156, + 9891.91635859715, + 10287.247788146442, + 9049.04525061468, + 9598.792464054242 + ], + "median_throughput": 9598.792464054242, + "std_throughput": 495.39175643024885, "times": [ - 0.8190825409255922, - 0.8190714579541236, - 0.8145584999583662, - 0.8106258329935372, - 0.8067842919845134, - 0.8203207920305431, - 0.8192974168341607, - 0.7968834589701146, - 0.8124556250404567, - 0.8175977501086891, - 0.8218767910730094, - 0.8438805420883, - 0.8480425840243697, - 1.1070600000675768, - 0.8167455838993192, - 0.8148204169701785, - 0.8063674580771476, - 0.828748167026788, - 0.7981428329367191, - 0.7886277500074357 - ], - "mean_time": 0.8171714448391648, - "std_time": 0.05013741357585128, + 0.21619254117831588, + 0.20218529226258397, + 0.19441545894369483, + 0.2210177918896079, + 0.20835954183712602 + ], + "mean_time": 0.20835954183712604, + "std_time": 0.010753394219766153, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Affine(angle=25.0, shift=(50, 50), scale=2.0, shear=[10.0, 15.0], p=1.0, interpolation=bilinear, mode=reflect)": { + "VerticalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 889.4446272355084, - 907.2248095097814, - 888.8491214924832, - 889.397294572027, - 903.715547540026, - 889.9047312891619, - 862.4478037946034, - 883.582550042376, - 897.2275559150794, - 892.6025119716812, - 886.8749269044044, - 889.6415587665109, - 903.8857254340578, - 905.7670527839788, - 888.4659136512427, - 904.0742216108487, - 893.9980878948367, - 895.7905570184519, - 816.0645571557836, - 765.1006722552042 - ], - "median_throughput": 889.7731450278363, - "std_throughput": 34.0655395880381, + 19935.26025297504, + 20238.852204531526, + 16544.039779585644, + 20703.656835937985, + 18332.316786177922 + ], + "median_throughput": 19935.26025297504, + "std_throughput": 1708.4871565275241, "times": [ - 1.1242970831226557, - 1.1022626250050962, - 1.1250503328628838, - 1.1243569168727845, - 1.1065428748261184, - 1.1237157920841128, - 1.1594904591329396, - 1.1317561669275165, - 1.1145444579888135, - 1.1203195000998676, - 1.127554708858952, - 1.1240482081193477, - 1.1063345419242978, - 1.10403662500903, - 1.125535582890734, - 1.106103875208646, - 1.118570625083521, - 1.1163323749788105, - 1.225393250118941, - 1.3070175419561565 - ], - "mean_time": 1.1238819755216543, - "std_time": 0.04302854738127393, + 0.10032474994659424, + 0.09881983324885368, + 0.12088945787400007, + 0.09660129202529788, + 0.10909695830196142 + ], + "mean_time": 0.10032474994659424, + "std_time": 0.008598008984608678, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Equalize(p=1.0)": { + "Pad(padding=10, fill=0, border_mode=constant)": { + "supported": false + }, + "Rotate(angle=45, interpolation=nearest, mode=constant, fill=0)": { "supported": true, - "warmup_iterations": 30, + "warmup_iterations": 16, "throughputs": [ - 573.2450349341254, - 611.7189290752481, - 604.3954661882544, - 617.0327257371468, - 627.19277368235, - 604.7106964611817, - 591.7149844113849, - 620.6518970554868, - 612.5559732345624, - 634.9820165558556, - 637.467977268458, - 527.4834827041075, - 609.0243555498454, - 625.763235589292, - 603.423948077534, - 615.4168851444887, - 621.473799956126, - 516.1050138204116, - 596.6796416983349, - 534.120567764543 - ], - "median_throughput": 610.3716423125468, - "std_throughput": 35.01688004633133, + 2591.2262810032353, + 2566.0960890941196, + 2573.7254364560426, + 2585.6486711696143, + 2574.4302638597546 + ], + "median_throughput": 2574.4302638597546, + "std_throughput": 10.07348965076161, "times": [ - 1.7444547079503536, - 1.634737707907334, - 1.6545458328910172, - 1.6206595830153674, - 1.5944061251357198, - 1.65368333295919, - 1.6900028330273926, - 1.6112091250251979, - 1.632503875065595, - 1.5748477499000728, - 1.5687062498182058, - 1.8957939590327442, - 1.6419704579748213, - 1.5980485000181943, - 1.6572096669115126, - 1.6249147921334952, - 1.6090782911051065, - 1.9375901671592146, - 1.6759412088431418, - 1.872236458119005 - ], - "mean_time": 1.6383461004368551, - "std_time": 0.0939915371166528, + 0.7718353332020342, + 0.7793940408155322, + 0.7770836669951677, + 0.7735002911649644, + 0.7768709170632064 + ], + "mean_time": 0.7768709170632064, + "std_time": 0.003039818655363745, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomCrop80(height=80, width=80, p=1.0)": { + "Affine(angle=25.0, shift=(20, 20), scale=2.0, shear=(10.0, 15.0), interpolation=bilinear, mode=constant, fill=0)": { "supported": true, - "warmup_iterations": 17, + "warmup_iterations": 16, "throughputs": [ - 10500.166633657102, - 12732.980281912345, - 11510.824494609986, - 10936.58638321019, - 13169.338556211147, - 13236.121267227825, - 13184.241508509485, - 12475.069338241357, - 12791.779231830444, - 12211.13670459124, - 12173.150878774692, - 12547.759916234198, - 12791.55422906641, - 7007.246058254994, - 11302.819490185064, - 11319.702789307226, - 5771.360345885648, - 11570.00085246907, - 13218.166280024408, - 13475.91608296471 - ], - "median_throughput": 12343.103021416298, - "std_throughput": 2012.8963927217767, + 1344.8196623617882, + 1328.1363721044956, + 1331.6815308897264, + 1307.0851389516781, + 1308.6957546327799 + ], + "median_throughput": 1328.1363721044956, + "std_throughput": 16.045803663440147, "times": [ - 0.09523658384568989, - 0.07853620895184577, - 0.08687474997714162, - 0.09143620915710926, - 0.07593395793810487, - 0.07555083394981921, - 0.07584812515415251, - 0.08015987509861588, - 0.07817520783282816, - 0.08189245802350342, - 0.08214800013229251, - 0.07969549996778369, - 0.07817658293060958, - 0.1427094170358032, - 0.08847349998541176, - 0.08834154205396771, - 0.17326937499456108, - 0.08643041714094579, - 0.07565345894545317, - 0.07420645793899894 - ], - "mean_time": 0.08101690460372224, - "std_time": 0.013212126216832345, + 1.4871882498264313, + 1.5058694588951766, + 1.5018605827353895, + 1.5301222088746727, + 1.5282390830107033 + ], + "mean_time": 1.5058694588951769, + "std_time": 0.018193075792296547, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Perspective(scale=(0.05, 0.1), interpolation=bilinear, fill=0)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 910.1977647389754, + 894.7672279102222, + 907.7090425540082, + 908.6570940235168, + 893.7570344195453 + ], + "median_throughput": 907.7090425540082, + "std_throughput": 8.049767174303797, + "times": [ + 2.197324666660279, + 2.235218208283186, + 2.203349207993597, + 2.2010503336787224, + 2.2377446251921356 + ], + "mean_time": 2.203349207993597, + "std_time": 0.019539794467762852, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 418.20951854291206, + 395.32852801451503, + 400.6208287393228, + 381.3922200428911, + 389.02032284877214 + ], + "median_throughput": 395.32852801451503, + "std_throughput": 13.901341682850362, + "times": [ + 4.78229191666469, + 5.0590834161266685, + 4.992251666728407, + 5.243945457972586, + 5.141119583044201 + ], + "mean_time": 5.0590834161266685, + "std_time": 0.1778977285621959, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear, p=1.0)": { + "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5)": { "supported": false }, - "ShiftRGB(pixel_shift=100, p=1.0, per_channel=True)": { + "ChannelShuffle()": { "supported": true, "warmup_iterations": 17, "throughputs": [ - 1680.6428474423465, - 1537.3347522488725, - 1609.5507528037494, - 1660.426115773741, - 1656.978978563198, - 1722.6050357705149, - 1620.3510677921704, - 1788.3190554219855, - 1704.483595056454, - 1694.697193115982, - 1665.3612090907268, - 1666.064686857084, - 1798.499959631848, - 1648.6626988912308, - 1667.854896834741, - 1683.0188301079788, - 1757.5962761044948, - 1701.9519110725344, - 1658.5636626516266, - 1770.4870446771336 - ], - "median_throughput": 1674.248872138544, - "std_throughput": 62.599333087173214, + 1218.2024729832947, + 1264.7629120321144, + 1251.8559093899385, + 1231.3666967775625, + 1283.5330699776564 + ], + "median_throughput": 1251.8559093899385, + "std_throughput": 26.00058607724153, "times": [ - 0.5950104161165655, - 0.6504764161072671, - 0.6212913747876883, - 0.602255041943863, - 0.6035079581197351, - 0.5805161248426884, - 0.6171502089127898, - 0.5591843340080231, - 0.5866879581008106, - 0.5900759168434888, - 0.6004703331273049, - 0.6002167910337448, - 0.5560189171228558, - 0.6065522078424692, - 0.5995725418906659, - 0.594170416938141, - 0.5689588750246912, - 0.5875606669578701, - 0.602931333007291, - 0.5648163328878582 - ], - "mean_time": 0.5972827675987529, - "std_time": 0.022332105780895534, + 1.6417632079683244, + 1.5813240418210626, + 1.597627957817167, + 1.6242115409113467, + 1.5581990419887006 + ], + "mean_time": 1.597627957817167, + "std_time": 0.03318214414698574, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Resize(target_size=512, interpolation=bilinear, p=1.0)": { + "Grayscale(num_output_channels=1)": { "supported": true, - "warmup_iterations": 38, + "warmup_iterations": 16, "throughputs": [ - 2083.3778217922463, - 2079.4794383942412, - 2030.8625106841264, - 1871.6208471511134, - 1962.6493111055545, - 1938.9928206083941, - 1879.0038931914028, - 2093.480169691493, - 2067.2888765820758, - 2096.2771144472795, - 2042.4535860574858, - 2018.8437176951993, - 2079.4055660151957, - 2041.3004391724753, - 1907.0685488736772, - 1939.8686009000023, - 1980.280202985163, - 2092.835390074406, - 1963.8219801910636, - 2001.0857568648837 - ], - "median_throughput": 2024.8531141896628, - "std_throughput": 74.08669810638884, + 3099.634657317826, + 3149.0975682261987, + 3099.592618414442, + 3126.5893489180585, + 3091.4616631509616 + ], + "median_throughput": 3099.634657317826, + "std_throughput": 24.029234590990832, "times": [ - 0.479989750077948, - 0.4808895830065012, - 0.4924016247969121, - 0.5342962499707937, - 0.5095153751317412, - 0.5157316671684384, - 0.5321968749631196, - 0.47767350007779896, - 0.48372533288784325, - 0.4770361671689898, - 0.48960720910690725, - 0.4953330419957638, - 0.4809066669549793, - 0.48988379212096334, - 0.5243650001939386, - 0.5154988330323249, - 0.5049790421035141, - 0.4778206660412252, - 0.5092111250851303, - 0.49972870806232095 - ], - "mean_time": 0.49386298343926816, - "std_time": 0.01806979355864447, + 0.6452373331412673, + 0.6351025830954313, + 0.6452460843138397, + 0.6396746668033302, + 0.6469431673176587 + ], + "mean_time": 0.6452373331412673, + "std_time": 0.005002060229360453, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomGamma(gamma=120, p=1.0)": { + "RGBShift(pixel_shift=100)": { + "supported": false + }, + "GaussianBlur(sigma=2.0, kernel_size=(5, 5))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 2693.9325543340165, - 2456.5206102190077, - 2499.6406766811283, - 2452.4488073665198, - 2714.3401367458696, - 2473.989612097606, - 2505.456414318121, - 2650.3739335843075, - 2497.972739229228, - 2516.1959103423933, - 2570.2607572732254, - 2613.0247525086547, - 2647.487384783739, - 2761.8428335035896, - 2845.48112373348, - 2849.2166137351714, - 2836.3580980598695, - 2720.7907555134916, - 2452.822510053094, - 2436.4069880192487 - ], - "median_throughput": 2591.64275489094, - "std_throughput": 142.89724484960064, + 1464.7046456946862, + 1459.958626435828, + 1461.423400666134, + 1451.9304843830894, + 1410.2126416306055 + ], + "median_throughput": 1459.958626435828, + "std_throughput": 22.53901540546559, "times": [ - 0.3712045419961214, - 0.4070798330940306, - 0.40005749999545515, - 0.40775570808909833, - 0.3684136657975614, - 0.40420541586354375, - 0.39912887499667704, - 0.37730525014922023, - 0.4003246249631047, - 0.397425333969295, - 0.3890655830036849, - 0.38269825000315905, - 0.3777166251093149, - 0.3620770841371268, - 0.3514344170689583, - 0.35097366594709456, - 0.3525647909846157, - 0.3675402079243213, - 0.40769358398392797, - 0.4104404579848051 - ], - "mean_time": 0.38585565009405837, - "std_time": 0.021275196669771238, + 1.3654630002565682, + 1.3699018340557814, + 1.3685287912376225, + 1.3774764160625637, + 1.418225834146142 + ], + "mean_time": 1.3699018340557814, + "std_time": 0.02114870790354961, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Grayscale(p=1.0, num_output_channels=3)": { + "GaussianNoise(mean=0, std=0.44, per_channel=True)": { + "supported": true, + "warmup_iterations": 27, + "throughputs": [ + 273.03574107225467, + 275.88964205875817, + 252.88516952632162, + 262.5485159050665, + 260.55877382647566 + ], + "median_throughput": 262.5485159050665, + "std_throughput": 9.429468044005166, + "times": [ + 7.325048333033919, + 7.2492754170671105, + 7.908727916888893, + 7.617639707867056, + 7.67581137502566 + ], + "mean_time": 7.617639707867057, + "std_time": 0.27358863541262596, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Invert()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 1906.4600153562774, - 1894.0087438110831, - 1945.8854134671303, - 1934.475914762276, - 1932.1232250115686, - 1842.2308867201655, - 1896.1668511574537, - 1839.6786034134464, - 1853.1703757466685, - 1905.2315569682416, - 1827.6803558005931, - 1845.2508087283543, - 1722.0090466151455, - 1787.3823758866383, - 1837.8238383280273, - 1832.5326309388925, - 1754.1198959112276, - 1704.8368996971562, - 1942.938802253141, - 1965.7460571305423 - ], - "median_throughput": 1849.2105922375113, - "std_throughput": 74.58439344266874, + 3796.9354565325107, + 3734.2200048752507, + 3680.615794283468, + 3682.4085345857943, + 3582.386566135254 + ], + "median_throughput": 3682.4085345857943, + "std_throughput": 79.01865483638375, "times": [ - 0.5245323751587421, - 0.5279806670732796, - 0.5139048749115318, - 0.5169358751736581, - 0.5175653328187764, - 0.54282012488693, - 0.5273797500412911, - 0.5435732079204172, - 0.5396157919894904, - 0.5248705840203911, - 0.5471416250802577, - 0.5419317500200123, - 0.5807170420885086, - 0.5594773751217872, - 0.5441217918414623, - 0.5456928750500083, - 0.5700864589307457, - 0.5865663748700172, - 0.5146842498797923, - 0.5087127080187201 - ], - "mean_time": 0.5407712913811608, - "std_time": 0.0218109819012394, + 0.5267405840568244, + 0.5355870830826461, + 0.5433873329311609, + 0.5431227907538414, + 0.5582870421931148 + ], + "mean_time": 0.5431227907538414, + "std_time": 0.0116545548744169, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5, p=1.0)": { - "supported": false + "Posterize(bits=4)": { + "supported": true, + "warmup_iterations": 20, + "throughputs": [ + 3044.9935861170466, + 3110.9553347216774, + 3188.8913912410408, + 3269.70554571535, + 3057.497580329957 + ], + "median_throughput": 3110.9553347216774, + "std_throughput": 94.51725155741237, + "times": [ + 0.6568158334121108, + 0.6428893329575658, + 0.6271772081963718, + 0.6116758747957647, + 0.654129708185792 + ], + "mean_time": 0.6428893329575658, + "std_time": 0.01953230640393092, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "PlankianJitter(mode=blackbody, p=1.0)": { - "supported": false + "Solarize(threshold=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 3691.9274270365577, + 3842.584984057338, + 3845.148504364967, + 3901.0837983613524, + 3774.770456240433 + ], + "median_throughput": 3842.584984057338, + "std_throughput": 80.26460410510607, + "times": [ + 0.5417224578559399, + 0.5204829582944512, + 0.5201359577476978, + 0.5126780411228538, + 0.5298335417173803 + ], + "mean_time": 0.5204829582944512, + "std_time": 0.010871941353095962, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "RandomPerspective(scale=(0.05, 0.1), p=1.0, interpolation=bilinear)": { + "Sharpen(alpha=(0.2, 0.5), lightness=(0.5, 1))": { "supported": true, - "warmup_iterations": 21, + "warmup_iterations": 18, "throughputs": [ - 607.6190568610984, - 557.1734606392391, - 595.0163071729478, - 614.48441161514, - 513.3172897077534, - 580.5217675790329, - 597.4219747710771, - 603.2038418445499, - 595.963553518221, - 595.532848547545, - 598.8100445415452, - 612.0052635230226, - 603.0128635948906, - 605.7634606886487, - 585.6239137351283, - 609.9692769812177, - 488.87862241276315, - 570.8580803231105, - 573.5731341522537, - 498.5589465288964 - ], - "median_throughput": 595.748201032883, - "std_throughput": 37.72663395009009, + 1081.0426601997349, + 1143.276180553824, + 1106.7739407828021, + 1101.4567661653368, + 1064.1400196991879 + ], + "median_throughput": 1101.4567661653368, + "std_throughput": 29.84946972475073, "times": [ - 1.6457680000457913, - 1.7947732091415673, - 1.6806262079626322, - 1.6273805829696357, - 1.9481128340121359, - 1.7225882918573916, - 1.6738587501458824, - 1.657814374892041, - 1.6779549589846283, - 1.6791685000061989, - 1.6699786670506, - 1.6339728750754148, - 1.6583394159097224, - 1.650809375103563, - 1.7075805419590324, - 1.6394268330186605, - 2.0454975001048297, - 1.7517488750163466, - 1.7434568330645561, - 2.005780874984339 - ], - "mean_time": 1.6785615101585576, - "std_time": 0.10629738461093054, + 1.8500657500699162, + 1.7493585837073624, + 1.8070537499152124, + 1.815777124837041, + 1.8794519170187414 + ], + "mean_time": 1.8157771248370407, + "std_time": 0.04920754584259583, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianBlur(sigma=2.0, kernel_size=(5, 5), p=1.0)": { + "Equalize()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 813.1901062110176, - 886.7296037612235, - 712.5122799233043, - 1113.8608524894253, - 1060.205537942633, - 1051.305274218424, - 904.1627085800652, - 893.555166541277, - 932.2976337843883, - 1034.8770826854766, - 1066.3196617421777, - 1079.468442679411, - 1143.4702599628026, - 948.5833442799286, - 680.541779274933, - 929.9648511424404, - 1133.8808020460453, - 1146.0560038152562, - 1083.1617765187627, - 1155.245445807226 - ], - "median_throughput": 1043.0911784519503, - "std_throughput": 142.24286502401756, + 813.6298872283359, + 811.5786299565627, + 801.7671484233234, + 819.8315613702307, + 830.8606718884582 + ], + "median_throughput": 813.6298872283359, + "std_throughput": 10.749101171567563, "times": [ - 1.2297247499227524, - 1.127739500021562, - 1.403484582901001, - 0.8977782079018652, - 0.9432133338414133, - 0.9511985001154244, - 1.1059956250246614, - 1.1191250830888748, - 1.0726188330445439, - 0.9662983331363648, - 0.9378050840459764, - 0.9263818750623614, - 0.8745308339130133, - 1.0542036248371005, - 1.4694175000768155, - 1.075309457955882, - 0.8819269170053303, - 0.8725577080622315, - 0.9232231248170137, - 0.865616915980354 - ], - "mean_time": 0.9586889628230757, - "std_time": 0.130733216382138, + 2.4581201248802245, + 2.464333000127226, + 2.4944898327812552, + 2.43952550040558, + 2.4071424580179155 + ], + "mean_time": 2.4581201248802245, + "std_time": 0.03247494017730034, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MedianBlur(blur_limit=5, p=1.0)": { + "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))": { + "supported": false + }, + "Erasing(scale=(0.02, 0.33), ratio=(0.3, 3.3), fill=0)": { + "supported": false + }, + "JpegCompression(quality=50)": { "supported": true, - "warmup_iterations": 16, + "warmup_iterations": 28, "throughputs": [ - 871.1906508520815, - 827.0109777283358, - 857.988926451302, - 800.7038187586309, - 821.6193238929377, - 766.4387708019078, - 853.0985307784908, - 783.8887857006174, - 790.604691116027, - 846.5622499362712, - 845.8925466309306, - 816.3941474541554, - 861.2383531008277, - 865.0617554756707, - 856.7648708625062, - 867.8653025129299, - 850.961684739552, - 868.4932573087439, - 873.8532082195351, - 847.8611401040373 - ], - "median_throughput": 849.4114124217947, - "std_throughput": 31.949672566345548, + 710.883522957997, + 686.7234161194074, + 704.212437467886, + 672.8538853097876, + 645.8282469585869 + ], + "median_throughput": 686.7234161194074, + "std_throughput": 26.07657824135371, "times": [ - 1.147854374954477, - 1.2091737920418382, - 1.1655162079259753, - 1.2489012498408556, - 1.21710866689682, - 1.3047356659080833, - 1.1721975409891456, - 1.2756911672186106, - 1.2648546248674393, - 1.1812480418011546, - 1.182183250086382, - 1.224898540880531, - 1.1611187499947846, - 1.1559868340846151, - 1.1671813749708235, - 1.152252540923655, - 1.1751410409342498, - 1.151419417001307, - 1.1443569590337574, - 1.179438415914774 - ], - "mean_time": 1.1772858068257588, - "std_time": 0.04428230595330274, + 2.813400417100638, + 2.9123806660063565, + 2.840052083134651, + 2.9724135412834585, + 3.096798582933843 + ], + "mean_time": 2.9123806660063565, + "std_time": 0.11059026170226777, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MotionBlur(kernel_size=5, angle=45, direction=0.0, p=1.0)": { + "RandomGamma(gamma=120)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 670.8377497213378, - 667.2207195788003, - 660.384429570762, - 667.3749553130407, - 678.3428694897254, - 657.41272438562, - 674.5897798247232, - 665.1047604357523, - 677.7094335737195, - 634.124121544672, - 666.006801847919, - 652.1161796299843, - 657.417802788998, - 654.4833860352944, - 521.926524771135, - 588.7584956959106, - 637.0605516234338, - 662.6703961645563, - 672.8161692088397, - 662.3393279009848 - ], - "median_throughput": 662.5048620327706, - "std_throughput": 36.49095799396928, + 3373.338793926833, + 3451.9872438559846, + 3554.0570584365505, + 3503.9514393894638, + 3528.4746428371286 + ], + "median_throughput": 3503.9514393894638, + "std_throughput": 71.66126289694787, "times": [ - 1.4906734160613269, - 1.4987544161267579, - 1.5142695000395179, - 1.4984080418944359, - 1.4741807498503476, - 1.521114458097145, - 1.4823823750484735, - 1.5035225418396294, - 1.4755586250685155, - 1.5769783328287303, - 1.501486166846007, - 1.5334690830204636, - 1.5211027078330517, - 1.527922665933147, - 1.9159784999210387, - 1.6984892911277711, - 1.5697095000650734, - 1.509045833023265, - 1.486290083033964, - 1.509800124913454 - ], - "mean_time": 1.509422884734294, - "std_time": 0.08313944581926785, + 0.5928844157606363, + 0.579376416746527, + 0.5627371668815613, + 0.5707841659896076, + 0.566817166749388 + ], + "mean_time": 0.5707841659896076, + "std_time": 0.011673424955776057, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Posterize(bits=4, p=1.0)": { + "PlankianJitter(mode=blackbody)": { + "supported": false + }, + "MedianBlur(blur_limit=5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 2609.3797665210545, - 2367.547551605153, - 2414.1371852855373, - 2402.388457913028, - 2206.439841930576, - 2241.4124484104336, - 2343.12074431921, - 2329.8466844405107, - 2385.736868343803, - 2427.2539369115334, - 2220.59995139367, - 2422.1708609684856, - 2728.064790552168, - 2509.237387274668, - 2342.670632315165, - 2490.348344351137, - 2396.7320544531894, - 2641.199635982728, - 2630.4866584853235, - 2368.8765149260607 - ], - "median_throughput": 2399.560256183109, - "std_throughput": 141.67699586899403, + 1124.6715514763257, + 1144.9700214628517, + 1152.0990904051016, + 1153.000970812465, + 1162.4353777021936 + ], + "median_throughput": 1152.0990904051016, + "std_throughput": 14.159765258203405, "times": [ - 0.38323283288627863, - 0.42237800010479987, - 0.4142266670241952, - 0.4162524160929024, - 0.45321879209950566, - 0.4461472500115633, - 0.42678124993108213, - 0.42921279184520245, - 0.41915770899504423, - 0.4119882080703974, - 0.4503287498373538, - 0.4128527909051627, - 0.3665602090768516, - 0.3985274590086192, - 0.4268632500898093, - 0.4015502498950809, - 0.41723479190841317, - 0.37861583288758993, - 0.38015779200941324, - 0.4221410418394953 - ], - "mean_time": 0.4167430250702113, - "std_time": 0.024605716688782697, + 1.7782969591207802, + 1.7467706250026822, + 1.7359617906622589, + 1.734603916760534, + 1.7205257499590516 + ], + "mean_time": 1.735961790662259, + "std_time": 0.02133567473293023, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "JpegCompression(quality=50, p=1.0)": { + "MotionBlur(kernel_size=5, angle_range=(0, 360), direction_range=(-1, 1))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 473.83513021122894, - 430.6699062079495, - 472.2493676658715, - 476.54431033264063, - 456.26670345165354, - 460.4608237257955, - 426.49924386669187, - 358.19362234635025, - 335.3949408579424, - 366.75221819766574, - 395.9653898412258, - 216.9070417040135, - 312.04258944585393, - 350.58246273866797, - 323.94081778601816, - 495.9948724026886, - 493.12498510653614, - 504.6839083141943, - 486.5122191392196, - 485.4353416863566 - ], - "median_throughput": 443.4683048298015, - "std_throughput": 79.4614787650676, + 929.4528626531693, + 938.8847268556485, + 927.9316652488782, + 864.724934931641, + 864.4812840777104 + ], + "median_throughput": 927.9316652488782, + "std_throughput": 37.20141283706308, "times": [ - 2.1104387079831213, - 2.32196395797655, - 2.1175253340043128, - 2.0984407500363886, - 2.1917005830910057, - 2.171737417113036, - 2.3446700419299304, - 2.7917861670721322, - 2.9815595829859376, - 2.726636542007327, - 2.5254732500761747, - 4.610269874799997, - 3.2046907499898225, - 2.8523959589656442, - 3.086983625078574, - 2.0161498750094324, - 2.0278834579512477, - 1.9814382498152554, - 2.055446832906455, - 2.0600065840408206 - ], - "mean_time": 2.2549525842298683, - "std_time": 0.404046613786264, + 2.151803582906723, + 2.130186957772821, + 2.1553311250172555, + 2.312874209135771, + 2.3135260841809213 + ], + "mean_time": 2.1553311250172555, + "std_time": 0.08640869364107034, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianNoise(mean=127, var=0.01, per_channel=True, p=1.0)": { + "CLAHE(clip_limit=(1, 4), tile_grid_size=(8, 8))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 197.1848057001005, - 172.6055675586084, - 191.767504157589, - 162.04781771841064, - 193.7190707901989, - 209.40172199241118, - 190.80058781773815, - 208.68766943088843, - 227.60800721658987, - 221.8762103560513, - 216.2180589580602, - 228.12909715973709, - 216.54125443002172, - 213.2269113392473, - 191.24571160046844, - 203.90973986039407, - 174.67476724054276, - 203.61050632339897, - 220.26065624222778, - 198.1975550885994 - ], - "median_throughput": 203.7601230918965, - "std_throughput": 18.311840051759827, + 538.623139251688, + 554.7656179663326, + 561.994964098679, + 563.4941049770804, + 532.47282174052 + ], + "median_throughput": 554.7656179663326, + "std_throughput": 14.008490600932484, "times": [ - 5.071384666021913, - 5.793555875075981, - 5.214647833025083, - 6.171017999993637, - 5.162114374805242, - 4.775509916944429, - 5.24107400001958, - 4.7918499580118805, - 4.393518541939557, - 4.507017667172477, - 4.624960582936183, - 4.383482915814966, - 4.6180576658807695, - 4.689839540980756, - 5.228875417029485, - 4.904130625072867, - 5.724925332935527, - 4.911337916972116, - 4.540075459051877, - 5.045470916898921 - ], - "mean_time": 4.907731624941141, - "std_time": 0.4410558610251429, + 3.7131713330745697, + 3.60512608429417, + 3.5587507500313222, + 3.549282915890217, + 3.7560602501034737 + ], + "mean_time": 3.60512608429417, + "std_time": 0.09103371447593257, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True, p=1.0)": { + "Brightness(brightness_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 256.19991247644475, - 263.55424912434245, - 264.63680827830797, - 265.48470510588106, - 266.2791358623671, - 265.39495011211744, - 251.46375745357946, - 222.37517927701808, - 183.53488652614894, - 228.93137196152495, - 252.68512958549172, - 240.84430379177294, - 249.23082438505335, - 199.47826125265686, - 230.73944543356953, - 254.80093534278262, - 243.4262833259242, - 248.1887366480074, - 253.20769842871158, - 251.46851324926283 - ], - "median_throughput": 251.46613535142114, - "std_throughput": 22.145426751383148, + 1075.8805796458748, + 1038.5933721669198, + 1108.4349586630126, + 1120.4200381577537, + 1072.5596428625588 + ], + "median_throughput": 1075.8805796458748, + "std_throughput": 32.32133296210586, "times": [ - 3.903201957931742, - 3.7942852498963475, - 3.77876383299008, - 3.766695334110409, - 3.7554575831163675, - 3.7679692080710083, - 3.9767162080388516, - 4.496904750121757, - 5.448555415961891, - 4.368121290812269, - 3.957494458183646, - 4.152059999993071, - 4.012344791088253, - 5.013077584095299, - 4.333892707945779, - 3.9246323748957366, - 4.108019833918661, - 4.029191709123552, - 3.949326999951154, - 3.976641000015661 - ], - "mean_time": 3.9766786036716675, - "std_time": 0.35020717445048144, + 1.8589423750527203, + 1.92568145878613, + 1.804345834068954, + 1.785044833086431, + 1.8646981669589877 + ], + "mean_time": 1.8589423750527203, + "std_time": 0.055845877877285684, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), p=1.0)": { - "supported": false - }, - "Clahe(clip_limit=(1, 4), tile_grid_size=(8, 8), p=1.0)": { + "Contrast(contrast_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 409.895008963993, - 422.6299681323419, - 405.12039770734765, - 373.31056546747834, - 424.79308388423544, - 413.81005550703054, - 422.4325483373865, - 428.2338351318377, - 422.11868850817683, - 421.94226354136623, - 423.83656862676935, - 417.40180846041056, - 426.5002899702718, - 413.3624298222498, - 422.27141054473896, - 412.33401700769997, - 419.9657822221248, - 424.12926529780316, - 423.6970962515612, - 423.8800378121953 - ], - "median_throughput": 422.19504952645786, - "std_throughput": 12.039992181242159, + 716.329385227429, + 713.1190749014858, + 716.5529110850094, + 725.40078647961, + 722.6922164146862 + ], + "median_throughput": 716.5529110850094, + "std_throughput": 5.053320823847988, "times": [ - 2.439649125095457, - 2.3661360419355333, - 2.468402000144124, - 2.6787347921635956, - 2.3540872908197343, - 2.416567665990442, - 2.367241832893342, - 2.3351727910339832, - 2.3690019589848816, - 2.3699924999382347, - 2.3593999999575317, - 2.395773041062057, - 2.344664291013032, - 2.41918454086408, - 2.3681451668962836, - 2.425218290882185, - 2.381146375089884, - 2.3577717498410493, - 2.3601766659412533, - 2.3591580418869853 - ], - "mean_time": 2.368573485458011, - "std_time": 0.06754604602208823, + 2.792011665645987, + 2.8045807080343366, + 2.79114070860669, + 2.757096542045474, + 2.7674298333004117 + ], + "mean_time": 2.79114070860669, + "std_time": 0.01968386318288044, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Brightness(brightness_limit=(0.2, 0.2), p=1.0)": { + "CoarseDropout(hole_height_range=(0.1, 0.1), hole_width_range=(0.1, 0.1), num_holes_range=(4, 4))": { "supported": true, - "warmup_iterations": 21, + "warmup_iterations": 19, "throughputs": [ - 723.5106691819041, - 751.8645771670815, - 693.9797431293288, - 785.2509714197083, - 702.4835309198019, - 727.0605360750681, - 792.6997633296459, - 789.8301988262405, - 745.4743416421054, - 738.8693948264613, - 688.0040021806711, - 728.0854692339782, - 745.8224850861413, - 755.2919531826226, - 723.2629135533309, - 640.9645920134444, - 758.6483784152414, - 757.8692165347029, - 796.246123774138, - 712.9416918660814 - ], - "median_throughput": 742.1718682342834, - "std_throughput": 39.14978378270765, + 1190.0629149547021, + 1200.9542786575405, + 1148.1085912908477, + 1169.3380272979236, + 1193.6629622212095 + ], + "median_throughput": 1190.0629149547021, + "std_throughput": 21.545623485797723, "times": [ - 1.38214962487109, - 1.3300267499871552, - 1.440964249894023, - 1.2734782081097364, - 1.4235209168400615, - 1.375401291064918, - 1.2615116671659052, - 1.2660949169658124, - 1.3414277918636799, - 1.3534191658254713, - 1.4534799170214683, - 1.3734651249833405, - 1.340801625046879, - 1.3239913331344724, - 1.3826230838894844, - 1.5601485830266029, - 1.3181337078567594, - 1.3194888751022518, - 1.2558930839877576, - 1.4026392500381917 - ], - "mean_time": 1.3473967995837959, - "std_time": 0.0710755764681801, + 1.6805834169499576, + 1.6653423327952623, + 1.7419955004006624, + 1.7103694169782102, + 1.6755148340016603 + ], + "mean_time": 1.6805834169499576, + "std_time": 0.030426305267614726, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Contrast(contrast_limit=(0.2, 0.2), p=1.0)": { + "Blur(radius=5, border_mode=constant)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 515.0459513820163, - 508.4484320532241, - 500.4080828113525, - 514.6175396275573, - 517.3942334856164, - 509.77776049961557, - 526.7694926984328, - 516.8852632729596, - 511.47641184120374, - 509.0061859418022, - 500.9050728496612, - 490.41795866782036, - 505.362740858865, - 497.7789414327062, - 526.2278539984809, - 520.577258387195, - 501.35796991896444, - 511.1732787079466, - 506.249299559127, - 516.7633730729013 - ], - "median_throughput": 510.4755196037811, - "std_throughput": 9.385401972349491, + 5410.364912631314, + 5380.896264867456, + 5569.602676523225, + 5239.906378715559, + 5302.7019871236225 + ], + "median_throughput": 5380.896264867456, + "std_throughput": 124.97079700040217, "times": [ - 1.9415743339341134, - 1.9667677918914706, - 1.9983689999207854, - 1.943190666846931, - 1.9327621671836823, - 1.9616391249001026, - 1.8983635420445353, - 1.9346653330139816, - 1.9551243749447167, - 1.9646126660518348, - 1.9963862500153482, - 2.039077040972188, - 1.9787766670342535, - 2.008923875167966, - 1.9003175001125783, - 1.9209444590378553, - 1.9945828330237418, - 1.9562837919220328, - 1.9753113749902695, - 1.9351216671057045 - ], - "mean_time": 1.9589577983605877, - "std_time": 0.03601662700447094, + 0.3696608329191804, + 0.3716852921061218, + 0.3590920423157513, + 0.38168620876967907, + 0.3771662078797817 + ], + "mean_time": 0.3716852921061218, + "std_time": 0.008632355076440688, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "CoarseDropout(hole_height_range=(16, 16), hole_width_range=(16, 16), num_holes_range=(1, 1), p=1.0)": { + "HSV(hue=0.015, saturation=0.7, value=0.4)": { + "supported": false + }, + "ChannelDropout()": { + "supported": false + }, + "LinearIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "CornerIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "GaussianIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "Hue(hue=20)": { + "supported": false + }, + "PlasmaBrightness(roughness=0.5)": { + "supported": false + }, + "PlasmaContrast(roughness=0.5)": { + "supported": false + }, + "PlasmaShadow(roughness=0.5)": { + "supported": false + }, + "Rain(drop_width=5, drop_height=20)": { + "supported": false + }, + "SaltAndPepper(amount=(0.01, 0.06), salt_vs_pepper=(0.4, 0.6))": { + "supported": false + }, + "Saturation(saturation_factor=0.5)": { "supported": true, - "warmup_iterations": 24, + "warmup_iterations": 20, "throughputs": [ - 624.2552989630692, - 677.6610201111757, - 670.5060774996252, - 690.6949064557821, - 694.9695122741031, - 718.3954923329285, - 718.6857605496845, - 683.0367619466206, - 738.1068839998785, - 592.974131288875, - 530.9913547765179, - 540.8539557786319, - 606.4553228374768, - 682.2252105717728, - 620.4056380579053, - 583.4018243914021, - 488.4245716222362, - 656.9454252522706, - 408.24859477922047, - 648.8087819259746 - ], - "median_throughput": 652.8771035891226, - "std_throughput": 84.90350101222614, + 494.79401451226363, + 492.68746599391733, + 499.43315893273706, + 499.0212737420179, + 494.9602630319581 + ], + "median_throughput": 494.9602630319581, + "std_throughput": 2.9267039661334704, "times": [ - 1.601908708922565, - 1.4756640419363976, - 1.4914107918739319, - 1.4478172499220818, - 1.4389120419509709, - 1.3919909168034792, - 1.3914287090301514, - 1.4640500419773161, - 1.3548173329327255, - 1.6864142080303282, - 1.8832698329351842, - 1.8489279579371214, - 1.6489260829985142, - 1.4657916249707341, - 1.6118486658670008, - 1.7140844580717385, - 2.0473990419413894, - 1.5221964588854462, - 2.4494879168923944, - 1.5412861660588533 - ], - "mean_time": 1.5316818349159529, - "std_time": 0.1991877943127207, + 4.0420860829763114, + 4.059368540998548, + 4.00453987531364, + 4.007845166604966, + 4.040728416759521 + ], + "mean_time": 4.040728416759521, + "std_time": 0.023892859218548494, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Blur(radius=5, p=1.0)": { + "Snow(snow_point_range=(0.5, 0.5))": { + "supported": false + }, + "OpticalDistortion(distort_limit=0.5)": { + "supported": false + }, + "Shear(shear=10)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 3205.584127976634, - 2914.2917689244246, - 3500.8213800517883, - 3698.9048255180023, - 3941.5190231302313, - 3999.6566843632877, - 3947.2879146790906, - 4071.8518977291365, - 4009.8086660553267, - 3746.730980461005, - 4078.2604638622183, - 3687.944571579371, - 3885.9845759981026, - 3849.473394886233, - 2696.318380805882, - 3531.174231944559, - 3584.313435489876, - 4103.708930658076, - 3863.949682574971, - 3883.825715485313 - ], - "median_throughput": 3856.711538730602, - "std_throughput": 385.1328460434264, + 1229.1511007588956, + 1258.9243643295654, + 1244.39771533353, + 1255.4906135025917, + 1231.1267310857158 + ], + "median_throughput": 1244.39771533353, + "std_throughput": 13.610423019276789, "times": [ - 0.31195562495850027, - 0.34313654201105237, - 0.28564725001342595, - 0.2703502920921892, - 0.2537092918064445, - 0.250021459069103, - 0.2533385001588613, - 0.2455885000526905, - 0.249388457974419, - 0.2668993331026286, - 0.24520258302800357, - 0.27115374989807606, - 0.2573350409511477, - 0.25977579201571643, - 0.370876083150506, - 0.2831919169984758, - 0.27899345802143216, - 0.24368200008757412, - 0.2588025419972837, - 0.2574780830182135 - ], - "mean_time": 0.2592882537253849, - "std_time": 0.025892634722625797, + 1.627139249816537, + 1.58865779126063, + 1.6072032079100609, + 1.5930027500726283, + 1.6245281249284744 + ], + "mean_time": 1.6072032079100609, + "std_time": 0.01757855649207104, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "HSV(hue=0.015, saturation=0.7, value=0.4, p=1.0)": { + "ThinPlateSpline(num_control_points=4, distortion_scale=0.5)": { "supported": false } } diff --git a/output/kornia_results.json b/output/kornia_results.json index 158b0c1..fdf78d1 100644 --- a/output/kornia_results.json +++ b/output/kornia_results.json @@ -1,16 +1,16 @@ { "metadata": { "system_info": { - "python_version": "3.12.7 | packaged by Anaconda, Inc. | (main, Oct 4 2024, 08:22:19) [Clang 14.0.6 ]", - "platform": "macOS-15.0.1-arm64-arm-64bit", + "python_version": "3.12.8 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 10:37:40) [Clang 14.0.6 ]", + "platform": "macOS-15.1-arm64-arm-64bit", "processor": "arm", - "cpu_count": "10", - "timestamp": "2024-11-02T17:20:07.232589+00:00" + "cpu_count": "16", + "timestamp": "2025-01-24T00:15:32.941638+00:00" }, "library_versions": { - "kornia": "0.7.3", - "numpy": "2.1.2", - "pillow": "11.0.0", + "kornia": "0.8.0", + "numpy": "2.2.2", + "pillow": "11.1.0", "opencv-python-headless": "not installed", "torch": "2.5.1", "opencv-python": "not installed" @@ -22,8 +22,8 @@ "pillow": "{'threads': 'unknown', 'simd': False}" }, "benchmark_params": { - "num_images": 1000, - "num_runs": 20, + "num_images": 2000, + "num_runs": 5, "max_warmup_iterations": 1000, "warmup_window": 5, "warmup_threshold": 0.05, @@ -31,1305 +31,1165 @@ } }, "results": { - "HorizontalFlip(p=1.0)": { + "Resize(target_size=512, interpolation=bilinear)": { "supported": true, - "warmup_iterations": 31, + "warmup_iterations": 16, + "throughputs": [ + 644.7656953409474, + 663.3667305599287, + 640.9704206198182, + 634.6939585353954, + 663.0867441529274 + ], + "median_throughput": 644.7656953409474, + "std_throughput": 13.14530391092543, + "times": [ + 3.1019020001403987, + 3.0149235827848315, + 3.120268791913986, + 3.151124999858439, + 3.0161966253072023 + ], + "mean_time": 3.101902000140399, + "std_time": 0.06324071641589311, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "RandomCrop128(height=128, width=128)": { + "supported": true, + "warmup_iterations": 16, "throughputs": [ - 448.90339368568414, - 582.5339005238167, - 426.21103374890384, - 384.7583186333275, - 437.2840397592497, - 633.3908620162621, - 482.47101390846115, - 612.4119366317673, - 497.3432235674168, - 661.7584224897213, - 614.088447779998, - 544.4787654187323, - 656.7029325460327, - 619.0276406680366, - 545.8733791418315, - 649.7195267877577, - 524.4746306352084, - 617.9378715500508, - 605.4939495827058, - 559.0303299951007 - ], - "median_throughput": 570.7821152594587, - "std_throughput": 84.42443071446293, + 2925.6031890083214, + 2926.465427171909, + 2945.8886283954366, + 3015.9263512901225, + 2999.29947492858 + ], + "median_throughput": 2945.8886283954366, + "std_throughput": 42.2619385999278, "times": [ - 2.22765079094097, - 1.7166382919531316, - 2.3462555420119315, - 2.5990341249853373, - 2.2868431250099093, - 1.578803958138451, - 2.0726633749436587, - 1.6328878328204155, - 2.010683875065297, - 1.5111254591029137, - 1.6284299169201404, - 1.836618916131556, - 1.522758541861549, - 1.61543674999848, - 1.831926666898653, - 1.5391256669536233, - 1.9066699161194265, - 1.6182856659870595, - 1.6515441660303622, - 1.7888117090333253 - ], - "mean_time": 1.7519820142672708, - "std_time": 0.2591358072059728, + 0.6836197087541223, + 0.6834182906895876, + 0.6789122917689383, + 0.663146167062223, + 0.6668223752640188 + ], + "mean_time": 0.6789122917689383, + "std_time": 0.009739726516783884, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "VerticalFlip(p=1.0)": { + "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear)": { "supported": true, - "warmup_iterations": 17, + "warmup_iterations": 16, "throughputs": [ - 1333.8192882378512, - 1301.6779707232533, - 1583.4321289138873, - 1508.9048020415003, - 1656.4322156562291, - 1630.0873912862626, - 1612.0498587014215, - 1587.858494526367, - 1482.1376467903867, - 1571.510298113317, - 1640.736647726363, - 1627.7654460331044, - 1644.6339389462164, - 1666.9715835128625, - 1591.2530933806665, - 1641.7392500628682, - 1493.0440013811615, - 1589.196640820623, - 1630.2880365148492, - 1559.7159677564389 - ], - "median_throughput": 1590.2248671006448, - "std_throughput": 100.37184406286515, + 660.8593649632422, + 644.0930827322514, + 628.4053021936505, + 660.7794702014885, + 667.5635382966091 + ], + "median_throughput": 660.7794702014885, + "std_throughput": 15.940841871701629, "times": [ - 0.7497267499566078, - 0.7682391670532525, - 0.6315395410638303, - 0.6627323331777006, - 0.6037071668542922, - 0.6134640420787036, - 0.6203282079659402, - 0.6297790410462767, - 0.6747011670377105, - 0.6363305421546102, - 0.6094823330640793, - 0.6143391251098365, - 0.6080380419734865, - 0.5998902500141412, - 0.6284355418756604, - 0.6091101251076907, - 0.6697726249694824, - 0.6292487501632422, - 0.6133885409217328, - 0.6411423750687391 - ], - "mean_time": 0.6288418831125663, - "std_time": 0.03969125419793744, + 3.026362500153482, + 3.105141249950975, + 3.1826593331061304, + 3.0267284172587097, + 2.995969499927014 + ], + "mean_time": 3.0267284172587097, + "std_time": 0.07301770297644782, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Rotate(angle=45, p=1.0, interpolation=nearest, mode=reflect)": { + "HorizontalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 169.18501379334677, - 172.81314915510623, - 189.11317827920212, - 167.64005352158242, - 167.36758467808872, - 174.86363259798256, - 156.20285236262816, - 160.98850916642493, - 161.45900057345102, - 156.30007707915294, - 149.30521751322766, - 162.0415397668111, - 180.12345751758141, - 166.67417047645256, - 164.89972037489636, - 159.04951267927896, - 165.5322831178411, - 188.62377771847278, - 171.96316313215365, - 188.36420171743455 - ], - "median_throughput": 167.02087757727065, - "std_throughput": 11.153124923680892, + 1283.84482508159, + 1296.8850978758257, + 1301.2028397006554, + 1302.862704918969, + 1273.0037405817716 + ], + "median_throughput": 1296.8850978758257, + "std_throughput": 12.776451491492057, "times": [ - 5.910689000040293, - 5.786596707999706, - 5.28783879103139, - 5.9651615410111845, - 5.974872624967247, - 5.718741999939084, - 6.401931750122458, - 6.211623457958922, - 6.193522791843861, - 6.3979495000094175, - 6.69768958282657, - 6.171257082838565, - 5.551747750025243, - 5.999729875009507, - 6.064291666029021, - 6.287350292084739, - 6.041117666987702, - 5.301558542065322, - 5.815198916941881, - 5.308864374877885 - ], - "mean_time": 5.98727545026435, - "std_time": 0.39981128118784054, + 1.5578206656500697, + 1.542156666982919, + 1.537039375398308, + 1.535081165842712, + 1.5710872923955321 + ], + "mean_time": 1.542156666982919, + "std_time": 0.015192779900286037, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Affine(angle=25.0, shift=(50, 50), scale=2.0, shear=[10.0, 15.0], p=1.0, interpolation=bilinear, mode=reflect)": { + "VerticalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 161.6525187380257, - 176.73343371325092, - 182.51605825213016, - 180.21642641609188, - 178.9242314611872, - 182.3429191557247, - 185.2092566577304, - 184.82481674161116, - 183.12657961289753, - 176.50189007762856, - 180.26090513890537, - 166.28748499627946, - 182.14801185800388, - 184.5483893149201, - 177.2574156493185, - 180.6655928221952, - 182.33280232427873, - 184.77442565235688, - 178.1114015192512, - 182.45058320907665 - ], - "median_throughput": 181.40680234009955, - "std_throughput": 6.0165338295916655, + 2871.8061629027006, + 2824.2220122797003, + 2800.25027164949, + 2883.6660586390904, + 2878.9648965733804 + ], + "median_throughput": 2871.8061629027006, + "std_throughput": 37.32138164389234, "times": [ - 6.186108374968171, - 5.658238959033042, - 5.478969957912341, - 5.548883749870583, - 5.58895791717805, - 5.484172374941409, - 5.399298167089, - 5.410528832813725, - 5.460703749908134, - 5.665661707986146, - 5.5475145829841495, - 6.01368166715838, - 5.490040708100423, - 5.418633040972054, - 5.641512916889042, - 5.535088249947876, - 5.484476667130366, - 5.41200437489897, - 5.614463709061965, - 5.480936165899038 - ], - "mean_time": 5.512472449215055, - "std_time": 0.18282653432816254, + 0.696425833273679, + 0.7081596245989203, + 0.7142218751832843, + 0.6935615842230618, + 0.6946941250935197 + ], + "mean_time": 0.696425833273679, + "std_time": 0.00905060189856321, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Equalize(p=1.0)": { + "Pad(padding=10, fill=0, border_mode=constant)": { + "supported": false + }, + "Rotate(angle=45, interpolation=nearest, mode=constant, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 184.45298512608164, - 179.4629736395413, - 170.08004802381163, - 183.9997032101173, - 191.1989635224967, - 163.6177331638272, - 171.15927066865146, - 194.10481988886065, - 173.63691048062108, - 186.10078813829804, - 190.39871781642094, - 187.04494886377356, - 181.47556967413055, - 170.2030257627126, - 190.29377272344956, - 185.09469016263316, - 176.35515600735232, - 193.4023293647398, - 176.96879574360807, - 193.76481301121308 - ], - "median_throughput": 184.22634416809947, - "std_throughput": 9.092721994113337, + 256.32680097434985, + 255.5175365430951, + 257.84906800402086, + 256.8825209177794, + 251.56144845552927 + ], + "median_throughput": 256.32680097434985, + "std_throughput": 2.426125041825789, "times": [ - 5.421435707947239, - 5.572180042043328, - 5.879584416979924, - 5.434791374951601, - 5.230153875192627, - 6.1118069579824805, - 5.8425114578567445, - 5.151855582837015, - 5.759144166018814, - 5.373432375025004, - 5.252136209048331, - 5.3463085000403225, - 5.51038358383812, - 5.875336208147928, - 5.255032709101215, - 5.4026401250157505, - 5.670375749934465, - 5.170568541157991, - 5.650713708018884, - 5.160895750159398 - ], - "mean_time": 5.428105326171692, - "std_time": 0.26791093808282607, + 7.802539540920407, + 7.827251417096704, + 7.756475582718849, + 7.785660125315189, + 7.950343791861087 + ], + "mean_time": 7.802539540920407, + "std_time": 0.07385078929751547, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomCrop80(height=80, width=80, p=1.0)": { + "Affine(angle=25.0, shift=(20, 20), scale=2.0, shear=(10.0, 15.0), interpolation=bilinear, mode=constant, fill=0)": { "supported": true, - "warmup_iterations": 18, + "warmup_iterations": 16, "throughputs": [ - 1461.8730705600462, - 1481.8141585703654, - 1466.9560800757356, - 1475.6564643050335, - 1482.0434677487153, - 1508.2023584776662, - 1510.345583823351, - 1447.1864683378303, - 1477.1951530972517, - 1491.5295111058422, - 1435.6886827992473, - 1491.6987891454617, - 1492.850832558665, - 1492.6168630352147, - 1507.457770294344, - 1488.0498435843292, - 1501.0404096100176, - 1498.5311584051944, - 1510.665486825241, - 1517.2958447925737 - ], - "median_throughput": 1491.614150125652, - "std_throughput": 21.591696278819782, + 240.6435265327651, + 251.47925071405578, + 251.1661447960612, + 248.41935036819268, + 239.97075596100476 + ], + "median_throughput": 248.41935036819268, + "std_throughput": 5.63569563313897, "times": [ - 0.6840539169497788, - 0.6748484580311924, - 0.6816836670041084, - 0.6776644999627024, - 0.6747440421022475, - 0.6630410000216216, - 0.6621001251041889, - 0.6909959579352289, - 0.6769586252048612, - 0.6704527081456035, - 0.6965298340655863, - 0.6703766251448542, - 0.6698592908214778, - 0.6699642920866609, - 0.6633685000706464, - 0.6720205000601709, - 0.6662045828998089, - 0.6673201250378042, - 0.661959916818887, - 0.6590672500897199 - ], - "mean_time": 0.6704146644866308, - "std_time": 0.009704513607116699, + 8.311048415955156, + 7.952942417003214, + 7.962856624741107, + 8.050902625080198, + 8.33434887509793 + ], + "mean_time": 8.050902625080198, + "std_time": 0.18264453513682877, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear, p=1.0)": { + "Perspective(scale=(0.05, 0.1), interpolation=bilinear, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 322.37306976803745, - 296.70557055058055, - 304.4296376610489, - 302.9430845274185, - 328.4189496776167, - 324.41588854244134, - 306.34171775080847, - 316.5159736741713, - 318.10448319487705, - 324.0018854929, - 328.56278869329964, - 318.9028381964616, - 326.73444566539763, - 304.47756330477836, - 320.25195713564307, - 319.8936459558546, - 325.2775017173808, - 329.6541911350349, - 329.9608175736375, - 325.87214664708733 - ], - "median_throughput": 321.31251345184023, - "std_throughput": 10.187046603911316, + 154.49844877894185, + 152.9661718177519, + 159.00516036092952, + 160.6556840453454, + 154.4154966493015 + ], + "median_throughput": 154.49844877894185, + "std_throughput": 3.3241875149978792, "times": [ - 3.101996083976701, - 3.3703445410355926, - 3.2848312919959426, - 3.300950082950294, - 3.044891291996464, - 3.0824630830902606, - 3.2643285000231117, - 3.1593982079066336, - 3.1436212088447064, - 3.0864017920102924, - 3.043558292090893, - 3.1357513330876827, - 3.06058945809491, - 3.2843142501078546, - 3.122541416902095, - 3.1260389590170234, - 3.074298083083704, - 3.0334818330593407, - 3.030662874924019, - 3.0686881658621132 - ], - "mean_time": 3.1122348434459104, - "std_time": 0.09867179168312143, + 12.945113791152835, + 13.074786250013858, + 12.578208125196397, + 12.448983749840409, + 12.952067916747183 + ], + "mean_time": 12.945113791152835, + "std_time": 0.2785269754154475, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ShiftRGB(pixel_shift=100, p=1.0, per_channel=True)": { - "supported": false + "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True)": { + "supported": true, + "warmup_iterations": 9, + "throughputs": [], + "median_throughput": 1.3831325440910864, + "std_throughput": 0.046585282290123875, + "times": [], + "mean_time": 0.6887213625013828, + "std_time": 0.0, + "variance_stable": false, + "early_stopped": true, + "early_stop_reason": "Transform timeout: 65.4 sec > 60 sec limit" + }, + "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 107.30183559129244, + 105.3372677454116, + 99.27335934118732, + 97.52889692690357, + 103.72190945676807 + ], + "median_throughput": 103.72190945676807, + "std_throughput": 4.112051390739836, + "times": [ + 18.639010124839842, + 18.986632583197206, + 20.146391874644905, + 20.506742750294507, + 19.282329167239368 + ], + "mean_time": 19.282329167239368, + "std_time": 0.7644472501916144, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "ChannelShuffle()": { + "supported": true, + "warmup_iterations": 19, + "throughputs": [ + 1342.1933007547862, + 1394.949330437687, + 1327.547769542175, + 1278.525332187731, + 1306.046040344834 + ], + "median_throughput": 1327.547769542175, + "std_throughput": 43.57875100212765, + "times": [ + 1.4900983329862356, + 1.4337438330985606, + 1.506537124980241, + 1.5643022079020739, + 1.5313395839184523 + ], + "mean_time": 1.506537124980241, + "std_time": 0.04945434563730737, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Grayscale(num_output_channels=1)": { + "supported": true, + "warmup_iterations": 19, + "throughputs": [ + 1241.6737694777662, + 1282.9062445637646, + 1167.624033368525, + 1160.7703443509472, + 1200.5851047282176 + ], + "median_throughput": 1200.5851047282176, + "std_throughput": 51.53623958566827, + "times": [ + 1.610729041043669, + 1.5589603749103844, + 1.7128801248036325, + 1.722993708215654, + 1.6658544172532856 + ], + "mean_time": 1.6658544172532856, + "std_time": 0.07150836040219227, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "RGBShift(pixel_shift=100)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 897.398620856475, + 887.2161579412557, + 895.9063408650005, + 887.417091052965, + 910.2947395732891 + ], + "median_throughput": 895.9063408650005, + "std_throughput": 9.440633005414849, + "times": [ + 2.2286640000529587, + 2.254242083057761, + 2.232376208063215, + 2.2537316670641303, + 2.197090582922101 + ], + "mean_time": 2.232376208063215, + "std_time": 0.023523713974383093, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "GaussianBlur(sigma=2.0, kernel_size=(5, 5))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 251.96149793084138, + 254.1544281402825, + 255.97368047109893, + 258.2244583860759, + 245.10739844739888 + ], + "median_throughput": 254.1544281402825, + "std_throughput": 5.020123625058147, + "times": [ + 7.937720709014684, + 7.869231374934316, + 7.813303290866315, + 7.745199709199369, + 8.159688416868448 + ], + "mean_time": 7.869231374934316, + "std_time": 0.15543508183359978, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "Resize(target_size=512, interpolation=bilinear, p=1.0)": { + "GaussianNoise(mean=0, std=0.44, per_channel=True)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 272.1296975518267, - 275.39997000314276, - 332.703281166975, - 332.3197672445391, - 327.42055468230666, - 322.77246477654927, - 319.5565534686551, - 328.8152790035485, - 332.80127651063356, - 334.99101314520954, - 336.13851670414334, - 337.51408282733064, - 333.09927557724467, - 334.1363558802073, - 337.87974942105114, - 330.5041034261798, - 328.789638616184, - 332.5587531129312, - 335.5948417321734, - 331.3938141618272 - ], - "median_throughput": 332.43926017873514, - "std_throughput": 18.38326912117547, + 124.64705310527862, + 124.48139301108264, + 125.35794818730331, + 125.77558235456047, + 124.82963258982805 + ], + "median_throughput": 124.82963258982805, + "std_throughput": 0.5363129255690204, "times": [ - 3.6747183750849217, - 3.6310824579559267, - 3.005681207869202, - 3.009149916935712, - 3.0541759999468923, - 3.0981577089987695, - 3.1293365419842303, - 3.0412212079390883, - 3.0047961669042706, - 2.985154707916081, - 2.9749640410300344, - 2.9628393328748643, - 3.0021079999860376, - 2.9927901660557836, - 2.9596328330226243, - 3.0256810418795794, - 3.0414583750534803, - 3.006987459026277, - 2.9797835831996053, - 3.0175578338094056 - ], - "mean_time": 3.008068299340916, - "std_time": 0.16634054910340546, + 16.045305124949664, + 16.066658250056207, + 15.954313459340483, + 15.901337624993175, + 16.021836790721864 + ], + "mean_time": 16.021836790721864, + "std_time": 0.06883556399189145, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomGamma(gamma=120, p=1.0)": { + "Invert()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 117.73368714488889, - 136.14337881463436, - 130.9928219867886, - 128.6422065946435, - 136.4167753453396, - 127.65998052812725, - 118.0241221794838, - 100.77449990010722, - 117.25514269680114, - 112.01460849741979, - 114.05073230499691, - 125.2483158701366, - 138.29531548264913, - 127.70298329000659, - 136.30823016172639, - 120.68722929557723, - 127.94729663833166, - 133.43270139473339, - 138.54227904073596, - 136.39932029264054 - ], - "median_throughput": 127.82513996416913, - "std_throughput": 10.366667038641586, + 2881.425038649982, + 2813.240895310783, + 2816.4100253762836, + 2909.56260903906, + 2883.1772601322114 + ], + "median_throughput": 2881.425038649982, + "std_throughput": 43.40581047722923, "times": [ - 8.493745709070936, - 7.345197458053008, - 7.63400608394295, - 7.773498499998823, - 7.330476750154048, - 7.833308417117223, - 8.472844207892194, - 9.92314524995163, - 8.528410583967343, - 8.92740699998103, - 8.768027874873951, - 7.984139292035252, - 7.23090291605331, - 7.83067062520422, - 7.336314166896045, - 8.28588083293289, - 7.815718082943931, - 7.494414709042758, - 7.218013208126649, - 7.331414832966402 - ], - "mean_time": 7.823187209341697, - "std_time": 0.6344634318643296, + 0.6941009997390211, + 0.7109238328412175, + 0.7101238747127354, + 0.6873885421082377, + 0.693679166957736 + ], + "mean_time": 0.6941009997390211, + "std_time": 0.010455943167913538, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Grayscale(p=1.0, num_output_channels=3)": { + "Posterize(bits=4)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 654.7583405666858, - 536.2449647149244, - 630.324071673821, - 503.94801288564634, - 638.2722055553484, - 628.9066731344595, - 608.6808387837523, - 668.7185179881195, - 675.0260200504972, - 670.8184177804883, - 668.7739551370374, - 688.7255510293276, - 546.7492477179719, - 626.6162292308452, - 393.93324412032723, - 593.3419466738812, - 499.8985830738155, - 645.943489604318, - 599.1237667145969, - 572.4053674069161 - ], - "median_throughput": 627.7614511826523, - "std_throughput": 74.82154498648603, + 883.0192800123814, + 836.0568176221628, + 868.0846770285931, + 825.3826771407233, + 810.5405257453027 + ], + "median_throughput": 836.0568176221628, + "std_throughput": 30.12436294300012, "times": [ - 1.5272810410242528, - 1.8648193750996143, - 1.5864854999817908, - 1.9843316660262644, - 1.566729666898027, - 1.5900610419921577, - 1.6428971248678863, - 1.4953974999953061, - 1.4814243752043694, - 1.4907163749448955, - 1.4952735409606248, - 1.4519571671262383, - 1.828991999849677, - 1.5958731251303107, - 2.538501167204231, - 1.685368792153895, - 2.0004057500045747, - 1.5481230418663472, - 1.6691042077727616, - 1.7470136671327055 - ], - "mean_time": 1.5929617820847075, - "std_time": 0.18986170848092618, + 2.264956207945943, + 2.3921819161623716, + 2.303922708146274, + 2.4231184581294656, + 2.4674892080947757 + ], + "mean_time": 2.3921819161623716, + "std_time": 0.08619385040494222, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5, p=1.0)": { + "Solarize(threshold=0.5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 55.33753961290841, - 54.857085429582575, - 54.318391325645734, - 56.0295473701349, - 57.01364102018888, - 55.89716122217025, - 52.07322290216098, - 51.80112568108011, - 45.08984088786324, - 51.31239302351242, - 46.210687344315296, - 46.25838378549288, - 46.967157451880205, - 47.92630305171997, - 48.008039809526366, - 49.74744971392355, - 48.83381174498719, - 47.88207812478373, - 48.62028948440098, - 49.65887374767807 - ], - "median_throughput": 49.703161730800815, - "std_throughput": 3.7598942003546085, + 263.65340703333305, + 262.7294973191033, + 250.54983945535403, + 262.3589742757356, + 267.05876678867526 + ], + "median_throughput": 262.7294973191033, + "std_throughput": 6.27352152849296, "times": [ - 18.07091545802541, - 18.229185750009492, - 18.40997083298862, - 17.84772583283484, - 17.539662124821916, - 17.889996166806668, - 19.203727832995355, - 19.30459979106672, - 22.177944750059396, - 19.488469375064597, - 21.64001570781693, - 21.61770295817405, - 21.291473750025034, - 20.865369042148814, - 20.82984441705048, - 20.101532957982272, - 20.47761508403346, - 20.884640750009567, - 20.567545166937634, - 20.13738783285953 - ], - "mean_time": 20.119444421184674, - "std_time": 1.5219752578977497, + 7.5857164999470115, + 7.612392290960997, + 7.982443749904633, + 7.623143082950264, + 7.488988375291228 + ], + "mean_time": 7.612392290960997, + "std_time": 0.18177063256309609, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "PlankianJitter(mode=blackbody, p=1.0)": { + "Sharpen(alpha=(0.2, 0.5), lightness=(0.5, 1))": { "supported": true, "warmup_iterations": 25, "throughputs": [ - 767.9932910284563, - 1059.827902788466, - 1006.2403676951285, - 1130.2961092949763, - 983.1218061571395, - 1050.2433346261394, - 1082.7851027922802, - 851.3096828950969, - 838.2234360185529, - 780.9842317641084, - 1092.496140977911, - 942.4468143579008, - 1003.4272478650787, - 1058.0183769618716, - 1061.0516290096923, - 1116.0230584311446, - 1119.2887591348865, - 1040.4003488895164, - 938.4683820062788, - 879.315326436931 - ], - "median_throughput": 1023.3203582923225, - "std_throughput": 113.55961072496743, + 199.10706621979256, + 203.35691769768866, + 200.55870978113705, + 201.12821109969983, + 200.1543148018568 + ], + "median_throughput": 200.55870978113705, + "std_throughput": 1.5786128378137139, + "times": [ + 10.044846915639937, + 9.834924833849072, + 9.97214233269915, + 9.943905875086784, + 9.992290208581835 + ], + "mean_time": 9.97214233269915, + "std_time": 0.07849148971931139, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "AutoContrast()": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 541.121368537491, + 529.2012593373198, + 533.4434182795068, + 544.3193118731957, + 547.9447801857098 + ], + "median_throughput": 541.121368537491, + "std_throughput": 7.737620078069171, + "times": [ + 3.696028499864042, + 3.779280500020832, + 3.749226124957204, + 3.674313874915242, + 3.6500028329901397 + ], + "mean_time": 3.696028499864042, + "std_time": 0.05285036960739146, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Equalize()": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 305.6838472429545, + 305.6862436968788, + 305.1848910218173, + 303.7513865982437, + 305.8766377119709 + ], + "median_throughput": 305.6838472429545, + "std_throughput": 0.8689635335259419, + "times": [ + 6.542707500047982, + 6.542656207922846, + 6.553404374979436, + 6.584332082886249, + 6.538583707995713 + ], + "mean_time": 6.542707500047981, + "std_time": 0.018598870301281233, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1220.824488564296, + 1251.5065010577162, + 1250.5806085975646, + 1256.71070404207, + 1240.9480593033768 + ], + "median_throughput": 1250.5806085975646, + "std_throughput": 14.208866727752334, + "times": [ + 1.638237124774605, + 1.598073999863118, + 1.599257166031748, + 1.591456166934222, + 1.6116710002534091 + ], + "mean_time": 1.599257166031748, + "std_time": 0.018170465605596507, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Erasing(scale=(0.02, 0.33), ratio=(0.3, 3.3), fill=0)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1210.3796101078265, + 1216.3328568697054, + 1207.063949175758, + 1215.4146173615584, + 1153.0780266858044 + ], + "median_throughput": 1210.3796101078265, + "std_throughput": 26.751869928740373, + "times": [ + 1.652374166995287, + 1.6442867498844862, + 1.6569130420684814, + 1.6455290000885725, + 1.7344879996962845 + ], + "mean_time": 1.652374166995287, + "std_time": 0.03652085545718233, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "JpegCompression(quality=50)": { + "supported": true, + "warmup_iterations": 24, + "throughputs": [ + 120.69854220528356, + 121.34229422018227, + 119.07365577896734, + 119.88419157305417, + 119.9445733129475 + ], + "median_throughput": 119.9445733129475, + "std_throughput": 0.8640551955164559, "times": [ - 1.3020947079639882, - 0.9435494171921164, - 0.9937983329873532, - 0.8847239159513265, - 1.0171679579652846, - 0.952160291839391, - 0.9235442909412086, - 1.1746606670785695, - 1.1929993329104036, - 1.2804355828557163, - 0.9153350410051644, - 1.0610678340308368, - 0.9965844580437988, - 0.9451631670817733, - 0.9424612079747021, - 0.8960388340055943, - 0.8934245000127703, - 0.9611684589181095, - 1.0655660000629723, - 1.137248459039256 - ], - "mean_time": 0.977211087316548, - "std_time": 0.10844278604695666, + 16.570208417251706, + 16.482299208641052, + 16.796326499897987, + 16.682766708079726, + 16.674368374980986 + ], + "mean_time": 16.674368374980986, + "std_time": 0.12011860335495786, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomPerspective(scale=(0.05, 0.1), p=1.0, interpolation=bilinear)": { + "RandomGamma(gamma=120)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 84.55781356656627, - 99.6840141347062, - 96.87501114007674, - 101.01496809492694, - 102.68224946809036, - 76.58828278628864, - 92.58239995598323, - 83.41565937658451, - 92.98439626821857, - 87.03234268202861, - 93.12302702725702, - 101.46500972697316, - 100.42192144752285, - 100.71462312571592, - 97.63154337615349, - 98.92765146489766, - 99.44688100232038, - 99.90487307945435, - 96.99111848715478, - 101.9811131486392 - ], - "median_throughput": 98.27959742052558, - "std_throughput": 7.252255797762909, + 230.46597299090132, + 229.68810543448026, + 231.558707913479, + 231.99395474224403, + 225.4597215459908 + ], + "median_throughput": 230.46597299090132, + "std_throughput": 2.607441583786888, "times": [ - 11.82622820790857, - 10.031698750099167, - 10.322579458123073, - 9.899523000000045, - 9.738781582796946, - 13.056827540975064, - 10.801189000019804, - 11.988156749866903, - 10.754492582986131, - 11.489981415914372, - 10.738482542103156, - 9.855614291969687, - 9.957985125016421, - 9.929044750053436, - 10.242591332877055, - 10.108397249830887, - 10.055619542021304, - 10.009521749801934, - 10.310222374973819, - 9.805737250018865 - ], - "mean_time": 10.175051854568864, - "std_time": 0.7508382282956308, + 8.67807066719979, + 8.707460041157901, + 8.637118500191718, + 8.620914291590452, + 8.870764082763344 + ], + "mean_time": 8.67807066719979, + "std_time": 0.09818179244009823, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianBlur(sigma=2.0, kernel_size=(5, 5), p=1.0)": { + "PlankianJitter(mode=blackbody)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 161.88898653922638, - 178.3798388118364, - 153.4374917849696, - 157.1389152033167, - 139.22948464460362, - 147.38731208753296, - 159.44698576161574, - 177.55685494266442, - 161.60218654806812, - 156.26046212576247, - 154.21475379995744, - 163.48203881257, - 167.17175640059713, - 181.65963560191662, - 176.67658921895685, - 180.80803334119358, - 170.6040360471316, - 177.67741634393053, - 179.3270947965701, - 175.62545914998685 - ], - "median_throughput": 165.32689760658357, - "std_throughput": 12.382498349524843, + 2048.380353829186, + 2159.841695221613, + 2183.160626450853, + 2149.940235286015, + 2137.391338159479 + ], + "median_throughput": 2149.940235286015, + "std_throughput": 51.637411011604186, "times": [ - 6.177072457969189, - 5.606014708057046, - 6.517311957897618, - 6.363795999903232, - 7.182386708911508, - 6.784844542155042, - 6.271677041891962, - 5.631998833967373, - 6.188035083934665, - 6.399571500020102, - 6.484463874949142, - 6.116879916982725, - 5.981871708063409, - 5.5048002088442445, - 5.660059459041804, - 5.530727708945051, - 5.8615260410588235, - 5.628177292179316, - 5.5764021668583155, - 5.693935291841626 - ], - "mean_time": 6.048622544043786, - "std_time": 0.45302403754498577, + 0.9763811668381095, + 0.9259937913157046, + 0.9161030002869666, + 0.9302584170363843, + 0.9357200828380883 + ], + "mean_time": 0.9302584170363842, + "std_time": 0.022343010023774743, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MedianBlur(blur_limit=5, p=1.0)": { + "MedianBlur(blur_limit=5)": { "supported": true, "warmup_iterations": 11, "throughputs": [], - "median_throughput": 4.486480187602719, - "std_throughput": 0.21210241043331898, + "median_throughput": 6.465315898318219, + "std_throughput": 0.023474354432572935, "times": [], - "mean_time": 0.22117264168336986, + "mean_time": 0.15361908748745917, "std_time": 0.0, "variance_stable": false, "early_stopped": true, - "early_stop_reason": "Transform too slow: 0.221 sec/image > 0.1 sec/image threshold" + "early_stop_reason": "Transform too slow: 0.154 sec/image > 0.1 sec/image threshold" + }, + "MotionBlur(kernel_size=5, angle_range=(0, 360), direction_range=(-1, 1))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 160.537614244364, + 159.1824252718022, + 160.47934699269047, + 159.3406013105104, + 158.8920373500534 + ], + "median_throughput": 159.3406013105104, + "std_throughput": 0.7677743651039746, + "times": [ + 12.458139542024583, + 12.564201083034277, + 12.462662875186652, + 12.551728709135205, + 12.587163166608661 + ], + "mean_time": 12.551728709135205, + "std_time": 0.060479849212028446, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "CLAHE(clip_limit=(1, 4), tile_grid_size=(8, 8))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 160.05876344772156, + 164.7030907204295, + 159.6722599117252, + 166.48520992782892, + 166.76438479778213 + ], + "median_throughput": 164.7030907204295, + "std_throughput": 3.446087169162417, + "times": [ + 12.4954107911326, + 12.143062958028167, + 12.525657250080258, + 12.013079124968499, + 11.992968417238444 + ], + "mean_time": 12.143062958028167, + "std_time": 0.2540696308184202, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "MotionBlur(kernel_size=5, angle=45, direction=0.0, p=1.0)": { + "Brightness(brightness_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 81.63953883337517, - 82.58710066875497, - 81.04277468512622, - 70.49714324184723, - 74.06195786063755, - 75.7460670430658, - 55.671600687764034, - 70.67360318597117, - 76.06967126934575, - 76.07441344274494, - 77.23228926080081, - 76.12665015812304, - 67.30435977055866, - 66.32420440089415, - 76.66033370744424, - 75.11665052735101, - 66.73656951720362, - 67.7694482160036, - 78.85364127456455, - 74.24228991759489 - ], - "median_throughput": 75.4313587852084, - "std_throughput": 6.449254663783195, + 1128.6231363395634, + 1068.2678103592284, + 1127.3474449989983, + 1133.025663706024, + 1119.054637246726 + ], + "median_throughput": 1127.3474449989983, + "std_throughput": 26.75333453765415, "times": [ - 12.248966790968552, - 12.1084284579847, - 12.339162915945053, - 14.184971957933158, - 13.50220854114741, - 13.202005583094433, - 17.962479749927297, - 14.149554500123486, - 13.145843584090471, - 13.1450241249986, - 12.947952334070578, - 13.136004249798134, - 14.857878500130028, - 15.077451874967664, - 13.0445557909552, - 13.31262766616419, - 14.984288332983851, - 14.755911790998653, - 12.681722541106865, - 13.469412124948576 - ], - "mean_time": 13.257085860636696, - "std_time": 1.1334586064973702, + 1.7720707077533007, + 1.8721897080540657, + 1.7740759593434632, + 1.765185082796961, + 1.7872228338383138 + ], + "mean_time": 1.7740759593434632, + "std_time": 0.0421009936608918, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Posterize(bits=4, p=1.0)": { + "Contrast(contrast_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 23, "throughputs": [ - 316.92832647972847, - 422.8873469237624, - 321.859524111871, - 330.1453580938855, - 360.36192959093046, - 467.97728888030366, - 516.5509377494433, - 494.84136119472635, - 480.3828938917678, - 357.85004768445265, - 304.8435254336901, - 320.86708987965034, - 308.3416791639733, - 390.93815136580406, - 367.6184906717541, - 424.84283339012535, - 361.5881747644005, - 363.52513593192396, - 450.04377221404616, - 300.21645607038965 - ], - "median_throughput": 362.5566553481622, - "std_throughput": 69.00066918314737, + 1130.5680566134567, + 1115.0046714196817, + 1109.4622497718065, + 1107.4111275053583, + 1025.851895092168 + ], + "median_throughput": 1109.4622497718065, + "std_throughput": 41.15385563251513, "times": [ - 3.1552875412162393, - 2.3646959580946714, - 3.106945499777794, - 3.0289688329212368, - 2.774987915996462, - 2.1368558341637254, - 1.9359174999408424, - 2.0208496670238674, - 2.081672792090103, - 2.794466583058238, - 3.280371458036825, - 3.116555207874626, - 3.2431554589420557, - 2.5579493751283735, - 2.720211375039071, - 2.3538116249255836, - 2.765577167039737, - 2.7508414168842137, - 2.2220060841646045, - 3.3309299999382347 - ], - "mean_time": 2.7581896105029506, - "std_time": 0.524930175880918, + 1.769022208172828, + 1.7937144581228495, + 1.8026751251891255, + 1.8060139999724925, + 1.949599166866392 + ], + "mean_time": 1.8026751251891255, + "std_time": 0.0668675584677335, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "JpegCompression(quality=50, p=1.0)": { + "CoarseDropout(hole_height_range=(0.1, 0.1), hole_width_range=(0.1, 0.1), num_holes_range=(4, 4))": { + "supported": false + }, + "Blur(radius=5, border_mode=constant)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 72.56265862024938, - 72.1008795153458, - 73.61166671239323, - 74.4140186706742, - 74.75610330944087, - 72.63124761598417, - 68.12174312548557, - 67.2937641685049, - 68.46623587672624, - 67.92832972722658, - 68.95043255106317, - 68.22302333490141, - 68.77369987855884, - 65.67299036160122, - 68.98189984819342, - 68.20605109421132, - 68.70311792123401, - 67.01695292241504, - 64.84786928997879, - 68.9653289763083 - ], - "median_throughput": 68.73840889989643, - "std_throughput": 2.8350265028076684, + 241.72128277291674, + 266.09905226970204, + 264.72037335767277, + 265.7963460556983, + 265.2817925659599 + ], + "median_throughput": 265.2817925659599, + "std_throughput": 10.635643095808058, "times": [ - 13.78119295812212, - 13.869456332875416, - 13.584803125122562, - 13.438328125048429, - 13.376834207912907, - 13.76817874982953, - 14.679600875126198, - 14.86021791701205, - 14.605739415856078, - 14.721398332854733, - 14.503172249998897, - 14.65780833386816, - 14.540442084195092, - 15.22696004086174, - 14.496556374942884, - 14.661455749999732, - 14.555380166973919, - 14.921597542008385, - 15.420707124983892, - 14.500039582839236 - ], - "mean_time": 14.54790729090482, - "std_time": 0.600009563651192, + 8.273992165923119, + 7.515998207964003, + 7.555141958408058, + 7.5245579169131815, + 7.539152916055173 + ], + "mean_time": 7.539152916055173, + "std_time": 0.30225873733850933, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianNoise(mean=127, var=0.01, per_channel=True, p=1.0)": { + "HSV(hue=0.015, saturation=0.7, value=0.4)": { + "supported": false + }, + "ChannelDropout()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 66.21296805151412, - 63.96581496510221, - 65.89027334042555, - 60.983862720805206, - 62.08836352886776, - 60.994971009865694, - 64.1995589365746, - 64.944776603649, - 64.58746310628081, - 61.77727855633207, - 64.79410637468867, - 65.13447335100965, - 66.58600401318775, - 63.51691910657001, - 64.66821163077475, - 64.80675369846716, - 66.26629308855497, - 61.24323303441513, - 65.2655274696606, - 66.32029181050905 - ], - "median_throughput": 64.73115900273172, - "std_throughput": 1.8528246492734373, + 2273.357721366702, + 2282.646299477472, + 2272.4923848848484, + 2315.4127628487768, + 2322.535767731443 + ], + "median_throughput": 2282.646299477472, + "std_throughput": 23.91577119780579, "times": [ - 15.102781666908413, - 15.633350416086614, - 15.176746874814853, - 16.39778058300726, - 16.106077583041042, - 16.394794250139967, - 15.576430999906734, - 15.397697125095874, - 15.482880916912109, - 16.187181167071685, - 15.433502458035946, - 15.352853083051741, - 15.018171082949266, - 15.743836666923016, - 15.463548083091155, - 15.430490541970357, - 15.090628332924098, - 16.3283345841337, - 15.322024333057925, - 15.078341374872252 - ], - "mean_time": 15.44851066173246, - "std_time": 0.4421886119390117, + 0.8797559579834342, + 0.8761760420165956, + 0.8800909579731524, + 0.8637768747285008, + 0.8611277500167489 + ], + "mean_time": 0.8761760420165956, + "std_time": 0.009179882908124977, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True, p=1.0)": { + "LinearIllumination(gain=(0.01, 0.2))": { "supported": true, - "warmup_iterations": 6, - "throughputs": [], - "median_throughput": 0.8851101201585867, - "std_throughput": 0.09937228493468055, - "times": [], - "mean_time": 1.243876808299683, - "std_time": 0.0, - "variance_stable": false, - "early_stopped": true, - "early_stop_reason": "Transform timeout: 67.6 sec > 60 sec limit" + "warmup_iterations": 16, + "throughputs": [ + 700.8586597965933, + 711.2326105479975, + 707.011585706658, + 707.9659174950601, + 716.3778786787182 + ], + "median_throughput": 707.9659174950601, + "std_throughput": 5.706128375078557, + "times": [ + 2.8536424171179533, + 2.812019542325288, + 2.8288079579360783, + 2.82499474985525, + 2.791822667233646 + ], + "mean_time": 2.82499474985525, + "std_time": 0.022769150750409493, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), p=1.0)": { + "CornerIllumination(gain=(0.01, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 496.55546722869354, - 641.9671067976543, - 650.8251309074825, - 623.4720388168803, - 565.3237878425962, - 662.7131044508908, - 611.135281952472, - 621.2348157850546, - 635.7907935132064, - 665.2612835785991, - 637.316353961522, - 647.5719638599545, - 649.8685924454994, - 651.8744758375163, - 667.5579121214897, - 631.9519652828825, - 651.1625759888558, - 628.0584976863887, - 672.0164024296229, - 657.2885464366939 - ], - "median_throughput": 644.7695353288044, - "std_throughput": 40.23854176062675, + 453.07489186606017, + 452.35147279040467, + 448.48823455487576, + 447.77300657601774, + 452.9455957222388 + ], + "median_throughput": 452.35147279040467, + "std_throughput": 2.579367250735797, "times": [ - 2.0138737079687417, - 1.5577122089453042, - 1.5365110419224948, - 1.6039211668539792, - 1.7688977918587625, - 1.5089485831558704, - 1.6362989170011133, - 1.6096972909290344, - 1.5728444170672446, - 1.5031687919981778, - 1.5690794591791928, - 1.5442299169953912, - 1.538772625150159, - 1.5340376668609679, - 1.4979973749723285, - 1.582398750120774, - 1.5357147920876741, - 1.5922083749901503, - 1.4880589169915766, - 1.5214018339756876 - ], - "mean_time": 1.5509417632302425, - "std_time": 0.09679060732330509, + 4.414281249977648, + 4.421340750064701, + 4.4594257907010615, + 4.466548833064735, + 4.415541334077716 + ], + "mean_time": 4.421340750064701, + "std_time": 0.02521106312467928, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Clahe(clip_limit=(1, 4), tile_grid_size=(8, 8), p=1.0)": { + "GaussianIllumination(gain=(0.01, 0.2))": { "supported": true, - "warmup_iterations": 25, + "warmup_iterations": 16, "throughputs": [ - 91.02588436029748, - 91.73606127092317, - 88.89900428397651, - 90.51012876983913, - 91.23536134230247, - 89.83067468111234, - 91.00753693178338, - 91.31625035272053, - 90.63598545274071, - 87.1785215255696, - 87.28021909474455, - 89.34139278271657, - 92.16757880161144, - 84.26757487462517, - 88.62099811190022, - 89.56616634459603, - 90.03586106095823, - 90.20203643405759, - 91.2301661474408, - 87.74048263871373 - ], - "median_throughput": 90.11894874750791, - "std_throughput": 1.9254859998330414, + 409.49690896102993, + 429.1091368150827, + 444.48073955422365, + 435.6672934649094, + 436.4112409095093 + ], + "median_throughput": 435.6672934649094, + "std_throughput": 13.216923971659376, "times": [ - 10.985886124894023, - 10.900838624918833, - 11.248719915980473, - 11.048487209016457, - 10.960662459023297, - 11.132054874906316, - 10.988100916845724, - 10.950953375082463, - 11.033145334105939, - 11.470715292030945, - 11.457349790958688, - 11.193020042032003, - 10.849802208133042, - 11.86696070805192, - 11.284007417038083, - 11.164930250030011, - 11.106685583014041, - 11.086224208818749, - 10.961286625126377, - 11.397247540997341 - ], - "mean_time": 11.096445463448145, - "std_time": 0.23708721289728876, + 4.8840417503379285, + 4.6608189581893384, + 4.499632542021573, + 4.590659041889012, + 4.582833374850452 + ], + "mean_time": 4.590659041889012, + "std_time": 0.13926772205897697, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Brightness(brightness_limit=(0.2, 0.2), p=1.0)": { + "Hue(hue=20)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 479.2330067418688, - 529.8639958179434, - 529.5042875804415, - 518.0699227325057, - 529.8919909278736, - 519.4437873981459, - 517.6506467572088, - 534.6613011341312, - 519.2761135363303, - 531.9554860495615, - 502.4127533239107, - 489.0406797901851, - 517.0769063742533, - 506.007991018683, - 538.455698243726, - 516.7920709957541, - 509.30564021908936, - 526.971464522076, - 527.5568670246097, - 512.362276968853 - ], - "median_throughput": 518.673018134418, - "std_throughput": 15.07517165214673, + 148.80517028330456, + 150.74496465677052, + 149.73366452054177, + 149.72595564012403, + 149.94375516120786 + ], + "median_throughput": 149.73366452054177, + "std_throughput": 0.6915129460203965, "times": [ - 2.0866676250007004, - 1.8872767500579357, - 1.8885588340926915, - 1.930241374997422, - 1.8871770419646055, - 1.9251361249480397, - 1.9318047920241952, - 1.870342958951369, - 1.9257577499374747, - 1.8798565410543233, - 1.990395334083587, - 2.044819667004049, - 1.933948292164132, - 1.9762533749453723, - 1.8571630001533777, - 1.935014208080247, - 1.9634575410746038, - 1.8976359581574798, - 1.8955302499234676, - 1.9517440001945943 - ], - "mean_time": 1.9279969557638381, - "std_time": 0.05603700990172544, + 13.440393208060414, + 13.267441499978304, + 13.357049708254635, + 13.357737417332828, + 13.338334749918431 + ], + "mean_time": 13.357049708254637, + "std_time": 0.061686680970990906, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Contrast(contrast_limit=(0.2, 0.2), p=1.0)": { + "PlasmaBrightness(roughness=0.5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 477.4741141810744, - 541.7430269893845, - 550.9931285712553, - 548.8495667611328, - 544.0863539899138, - 474.8487363747287, - 499.02820494220254, - 502.56440800965703, - 539.3163893820614, - 524.3385158427994, - 526.5916378582679, - 439.5067810756889, - 430.6567299876105, - 270.4362444457606, - 242.71583727805202, - 278.8516082146546, - 249.0818169296971, - 358.9701863976941, - 261.4208392581883, - 344.4674840461732 - ], - "median_throughput": 476.16142527790157, - "std_throughput": 116.01370523262199, + 84.2196260239644, + 84.91691707623457, + 86.42964567994477, + 87.32417613347337, + 85.09096507059654 + ], + "median_throughput": 85.09096507059654, + "std_throughput": 1.2542105817406997, "times": [ - 2.094354375032708, - 1.8458936251699924, - 1.8149046660400927, - 1.8219928748439997, - 1.8379435408860445, - 2.1059337919577956, - 2.0038947500288486, - 1.9897947090212256, - 1.8541991671081632, - 1.9071648749522865, - 1.8990047089755535, - 2.2752777501009405, - 2.3220349999610335, - 3.6977292080409825, - 4.120044292183593, - 3.586136749945581, - 4.014745083870366, - 2.785746666137129, - 3.825249749934301, - 2.9030316250864416 - ], - "mean_time": 2.100128122340803, - "std_time": 0.5116828705596812, + 23.74743387522176, + 23.552432999946177, + 23.140208249911666, + 22.903164834249765, + 23.504258041270077 + ], + "mean_time": 23.504258041270077, + "std_time": 0.34644440954297656, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "CoarseDropout(hole_height_range=(16, 16), hole_width_range=(16, 16), num_holes_range=(1, 1), p=1.0)": { + "PlasmaContrast(roughness=0.5)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 471.12566041204576, - 394.1223419016081, - 452.51906040099294, - 412.91072743971984, - 575.533854411002, - 620.5708369467844, - 478.870182439389, - 620.0337555876204, - 623.3296067599854, - 514.6511864379969, - 537.0137751171288, - 482.1185735682654, - 506.03202829588076, - 498.19640444977927, - 602.6873227734793, - 546.1060871232511, - 538.8409101916436, - 611.2469437875508, - 560.4221735621464, - 294.70838933478655 - ], - "median_throughput": 525.8324807775629, - "std_throughput": 86.04446030200741, + 84.63812331141787, + 84.3605958242927, + 84.12256510528512, + 84.43920442290639, + 84.74265757619034 + ], + "median_throughput": 84.43920442290639, + "std_throughput": 0.2427947662269866, "times": [ - 2.122575958026573, - 2.5372832079883665, - 2.209851667052135, - 2.4218310001306236, - 1.7375172500032932, - 1.6114195841364563, - 2.088248624932021, - 1.6128154168836772, - 1.604287666035816, - 1.9430636251345277, - 1.8621496250852942, - 2.074178542010486, - 1.9761594999581575, - 2.007240500068292, - 1.6592351659201086, - 1.8311460420954973, - 1.8558353330008686, - 1.6359999999403954, - 1.784369083121419, - 3.393184707965702 - ], - "mean_time": 1.9017463480408678, - "std_time": 0.3111917656865146, + 23.630013541784137, + 23.70775099983439, + 23.774833749979734, + 23.685680291149765, + 23.60086474986747 + ], + "mean_time": 23.685680291149765, + "std_time": 0.06810532203044779, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Blur(radius=5, p=1.0)": { - "supported": false + "PlasmaShadow(roughness=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 213.4922958894896, + 210.4111765864658, + 215.94059237471848, + 222.11339179595527, + 222.09789676223238 + ], + "median_throughput": 215.94059237471848, + "std_throughput": 5.215260833338648, + "times": [ + 9.368019542191178, + 9.505198499653488, + 9.261806583032012, + 9.004409791901708, + 9.00503799971193 + ], + "mean_time": 9.261806583032012, + "std_time": 0.2236853043110389, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "HSV(hue=0.015, saturation=0.7, value=0.4, p=1.0)": { - "supported": false + "Rain(drop_width=5, drop_height=20)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1493.984936918357, + 1488.247172173443, + 1493.4863927241302, + 1472.8426236658363, + 1494.9729200092206 + ], + "median_throughput": 1493.4863927241302, + "std_throughput": 9.244604431875498, + "times": [ + 1.3387015829794109, + 1.3438627920113504, + 1.3391484580934048, + 1.3579183327965438, + 1.3378168749623 + ], + "mean_time": 1.3391484580934048, + "std_time": 0.008289260505446256, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "SaltAndPepper(amount=(0.01, 0.06), salt_vs_pepper=(0.4, 0.6))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 487.52171417817425, + 480.4027649063624, + 473.242872548205, + 458.45818679178217, + 484.4535770104638 + ], + "median_throughput": 480.4027649063624, + "std_throughput": 11.571369047860498, + "times": [ + 4.102381374686956, + 4.163173374719918, + 4.226159792393446, + 4.362447999883443, + 4.1283625406213105 + ], + "mean_time": 4.163173374719918, + "std_time": 0.10027755676739443, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Saturation(saturation_factor=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 154.99202578251348, + 158.303893029792, + 155.12258700692817, + 154.2079276146753, + 152.51130355756285 + ], + "median_throughput": 154.99202578251348, + "std_throughput": 2.1064184452020434, + "times": [ + 12.903889667242765, + 12.633928084280342, + 12.893028917256743, + 12.969501833897084, + 13.113782082684338 + ], + "mean_time": 12.903889667242765, + "std_time": 0.1753702558096304, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Snow(snow_point_range=(0.5, 0.5))": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 142.26622906643635, + 142.94255401558289, + 143.12076321830992, + 143.83064818001367, + 140.4940377380074 + ], + "median_throughput": 142.94255401558289, + "std_throughput": 1.2674385132394965, + "times": [ + 14.058150083292276, + 13.991634707897902, + 13.974212790839374, + 13.90524220885709, + 14.235479542054236 + ], + "mean_time": 13.991634707897902, + "std_time": 0.12406058373656197, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "OpticalDistortion(distort_limit=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 173.502225411185, + 173.75696690645094, + 174.1096454379515, + 174.55428953594077, + 174.64818896450126 + ], + "median_throughput": 174.1096454379515, + "std_throughput": 0.49522018294074843, + "times": [ + 11.5272296667099, + 11.51032983371988, + 11.48701437516138, + 11.457753374706954, + 11.451593124773353 + ], + "mean_time": 11.48701437516138, + "std_time": 0.03267252280022422, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "Shear(shear=10)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 260.8422703434185, + 261.2299731292205, + 261.1844784799706, + 259.77275099645027, + 260.1784774363579 + ], + "median_throughput": 260.8422703434185, + "std_throughput": 0.6423685992798618, + "times": [ + 7.6674689166247845, + 7.656089291907847, + 7.657422874588519, + 7.699036917183548, + 7.687030917033553 + ], + "mean_time": 7.6674689166247845, + "std_time": 0.01888245053805719, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "ThinPlateSpline(num_control_points=4, distortion_scale=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 58.1177869627831, + 57.76735644580254, + 57.68996646380944, + 58.20403152199959, + 58.58105710411862 + ], + "median_throughput": 58.1177869627831, + "std_throughput": 0.35966137338615356, + "times": [ + 34.412872625049204, + 34.62162929121405, + 34.668073541950434, + 34.361880916170776, + 34.140729083213955 + ], + "mean_time": 34.412872625049204, + "std_time": 0.21296373584241626, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null } } } diff --git a/output/torchvision_results.json b/output/torchvision_results.json index 8f1c574..a5715f6 100644 --- a/output/torchvision_results.json +++ b/output/torchvision_results.json @@ -1,16 +1,16 @@ { "metadata": { "system_info": { - "python_version": "3.12.7 | packaged by Anaconda, Inc. | (main, Oct 4 2024, 08:22:19) [Clang 14.0.6 ]", - "platform": "macOS-15.0.1-arm64-arm-64bit", + "python_version": "3.12.8 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 10:37:40) [Clang 14.0.6 ]", + "platform": "macOS-15.1-arm64-arm-64bit", "processor": "arm", - "cpu_count": "10", - "timestamp": "2024-11-02T16:52:32.623562+00:00" + "cpu_count": "16", + "timestamp": "2025-01-24T00:05:11.345897+00:00" }, "library_versions": { "torchvision": "0.20.1", - "numpy": "2.1.2", - "pillow": "11.0.0", + "numpy": "2.2.2", + "pillow": "11.1.0", "opencv-python-headless": "not installed", "torch": "2.5.1", "opencv-python": "not installed" @@ -22,8 +22,8 @@ "pillow": "{'threads': 'unknown', 'simd': False}" }, "benchmark_params": { - "num_images": 1000, - "num_runs": 20, + "num_images": 2000, + "num_runs": 5, "max_warmup_iterations": 1000, "warmup_window": 5, "warmup_threshold": 0.05, @@ -31,982 +31,692 @@ } }, "results": { - "HorizontalFlip(p=1.0)": { + "Resize(target_size=512, interpolation=bilinear)": { "supported": true, - "warmup_iterations": 18, + "warmup_iterations": 16, "throughputs": [ - 740.576236805059, - 842.7414885970853, - 865.6059171521704, - 860.5955043756717, - 864.9025772229157, - 826.4404468545376, - 850.2162668728312, - 864.2481807865875, - 861.7330939783725, - 861.2765236017855, - 870.4988591610094, - 889.2600391097886, - 851.4973383153286, - 881.1615912188056, - 896.7829367208769, - 764.0412879151374, - 847.760899246678, - 861.6637911339378, - 879.5099580895816, - 858.1289080551969 - ], - "median_throughput": 861.4701573678617, - "std_throughput": 37.7963910543144, + 268.73661644504085, + 260.1697072894327, + 249.85758249322987, + 261.5253086483284, + 245.5909793468516 + ], + "median_throughput": 260.1697072894327, + "std_throughput": 9.344765379241814, "times": [ - 1.3502998750191182, - 1.1866035000421107, - 1.1552601249422878, - 1.1619860839564353, - 1.1561995840165764, - 1.2100085418205708, - 1.1761713330633938, - 1.1570750419050455, - 1.160452124895528, - 1.1610672909300774, - 1.148766583064571, - 1.124530459055677, - 1.1744017919991165, - 1.1348656250629574, - 1.1150970419403166, - 1.3088297920767218, - 1.1795778749510646, - 1.1605454590171576, - 1.1369967909995466, - 1.165326084010303 - ], - "mean_time": 1.160806316327199, - "std_time": 0.05092955234140045, + 7.4422310828231275, + 7.687290041707456, + 8.004559957887977, + 7.647443416994065, + 8.14362158300355 + ], + "mean_time": 7.687290041707456, + "std_time": 0.27611178330620334, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "VerticalFlip(p=1.0)": { + "RandomCrop128(height=128, width=128)": { "supported": true, - "warmup_iterations": 16, + "warmup_iterations": 38, "throughputs": [ - 3238.857219612126, - 3332.6501408011954, - 3275.340697680685, - 3354.685434219066, - 3302.012370447355, - 2725.740424053197, - 3252.4115239983357, - 3189.9457183934005, - 2918.9328448960296, - 3315.388791363397, - 2975.855762982257, - 1857.2489069556154, - 3094.4591392345847, - 3084.432874280384, - 3131.7499768354464, - 3165.987588977626, - 2130.3481965418123, - 2640.4194328677686, - 3258.8642130583494, - 3145.014657542121 - ], - "median_throughput": 3155.5011232598736, - "std_throughput": 402.29761940212, + 31538.942993539622, + 31586.303727296057, + 31449.58982283231, + 30988.81431651121, + 31221.075641195275 + ], + "median_throughput": 31449.58982283231, + "std_throughput": 249.14475783388775, "times": [ - 0.30875087482854724, - 0.30006149993278086, - 0.30531174992211163, - 0.29809054220095277, - 0.3028456249739975, - 0.3668727921321988, - 0.3074641670100391, - 0.3134849581401795, - 0.3425909581128508, - 0.30162375001236796, - 0.33603779203258455, - 0.5384307920467108, - 0.323158249957487, - 0.3242087089456618, - 0.3193102921359241, - 0.3158572078682482, - 0.4694068329408765, - 0.3787277080118656, - 0.3068553749471903, - 0.3179635419510305 - ], - "mean_time": 0.3169068749900883, - "std_time": 0.04040273680808262, + 0.06341366609558463, + 0.06331858318299055, + 0.0635938341729343, + 0.064539416693151, + 0.06405929196625948 + ], + "mean_time": 0.0635938341729343, + "std_time": 0.0005037925932897663, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Rotate(angle=45, p=1.0, interpolation=nearest, mode=reflect)": { + "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear)": { + "supported": true, + "warmup_iterations": 17, + "throughputs": [ + 755.2792843061796, + 837.3193074204585, + 836.064055022779, + 844.6286728665476, + 836.951462954496 + ], + "median_throughput": 836.951462954496, + "std_throughput": 37.48240926663955, + "times": [ + 2.6480270829051733, + 2.388575042132288, + 2.392161208204925, + 2.367904458194971, + 2.3896248331293464 + ], + "mean_time": 2.3896248331293464, + "std_time": 0.10701802906574183, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "HorizontalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 171.0968134956512, - 177.1314801210756, - 146.130061349045, - 135.94722307333797, - 155.44209476534843, - 169.06039633698182, - 171.99762557340054, - 165.6772204672737, - 149.2807374114002, - 142.5652515238185, - 159.66332115232905, - 157.0276323168701, - 160.71674416930443, - 158.54821207717282, - 162.835465927297, - 162.55966117274448, - 162.33010800413538, - 149.04307636906907, - 159.68941471424816, - 175.60931363790255 - ], - "median_throughput": 160.2030794417763, - "std_throughput": 10.94944797333919, + 2655.9953210195476, + 2485.9186977380955, + 2573.0080283488, + 2465.934401860682, + 2374.7442400330624 + ], + "median_throughput": 2485.9186977380955, + "std_throughput": 107.3477742139858, "times": [ - 5.844644207973033, - 5.645523874787614, - 6.843218915862963, - 7.355795708019286, - 6.43326379195787, - 5.915045875124633, - 5.814033749978989, - 6.035832790890709, - 6.698787916917354, - 7.014331958955154, - 6.263179249828681, - 6.368305916897953, - 6.222127042012289, - 6.307229749858379, - 6.141168290982023, - 6.1515876250341535, - 6.160286667058244, - 6.709469667170197, - 6.262155834119767, - 5.694458791986108 - ], - "mean_time": 6.2420772652091046, - "std_time": 0.426629129097424, + 0.7530133747495711, + 0.8045315407216549, + 0.7773003340698779, + 0.8110515829175711, + 0.8421959578990936 + ], + "mean_time": 0.8045315407216549, + "std_time": 0.034741550582487034, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Affine(angle=25.0, shift=(50, 50), scale=2.0, shear=[10.0, 15.0], p=1.0, interpolation=bilinear, mode=reflect)": { + "VerticalFlip()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 139.5771958998461, - 141.36849723714093, - 141.2315018520024, - 140.37586902306896, - 137.63158611925903, - 126.5323742755722, - 113.67282290439931, - 105.64906287168273, - 128.8072276854029, - 129.83119666444952, - 128.76730132980646, - 134.62407304459148, - 133.88283011239923, - 116.7659418884608, - 116.28578606838396, - 113.03208192248142, - 74.33832640076504, - 122.51362490893713, - 123.62785889223723, - 135.3929771932397 - ], - "median_throughput": 128.78726450760468, - "std_throughput": 15.956213522182654, + 4912.384042334619, + 4767.422768248097, + 4599.632638733682, + 4490.860391171013, + 4696.317978956326 + ], + "median_throughput": 4696.317978956326, + "std_throughput": 160.66772979394685, "times": [ - 7.164494124939665, - 7.073711750097573, - 7.080573291983455, - 7.123731500003487, - 7.265773999970406, - 7.903115749824792, - 8.797177499858662, - 9.465299292001873, - 7.7635394998360425, - 7.702309041982517, - 7.765946709085256, - 7.428092000074685, - 7.469217667123303, - 8.564141082810238, - 8.599503291072324, - 8.84704575012438, - 13.452011208981276, - 8.162357458146289, - 8.088791708927602, - 7.3859074579086155 - ], - "mean_time": 7.764742917891168, - "std_time": 0.962019780577071, + 0.40713429218158126, + 0.4195138751529157, + 0.4348173337057233, + 0.44534895895048976, + 0.425865541677922 + ], + "mean_time": 0.425865541677922, + "std_time": 0.014569466992110904, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Equalize(p=1.0)": { + "Pad(padding=10, fill=0, border_mode=constant)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 442.4232990576504, - 457.6773284698, - 386.3556008419462, - 416.78787516438, - 411.0181428075939, - 411.7845461642146, - 370.44807871815306, - 454.7303782868059, - 475.90545235317467, - 470.5679177935556, - 415.6057536750405, - 420.77582028925355, - 442.8504862061268, - 376.9864238821554, - 385.0743513086952, - 464.67122128669365, - 462.83365713244734, - 338.76559009627846, - 364.5016962183766, - 332.3677542677632 - ], - "median_throughput": 416.1968144197102, - "std_throughput": 44.056659238903435, + 5033.180715467926, + 4889.1855950850795, + 4948.230681842232, + 4858.148143868722, + 4550.653749670613 + ], + "median_throughput": 4889.1855950850795, + "std_throughput": 183.19502120188304, "times": [ - 2.2602787921205163, - 2.184945457847789, - 2.588289124891162, - 2.3993020420894027, - 2.432982624974102, - 2.4284544170368463, - 2.699433624977246, - 2.199105333071202, - 2.1012577079236507, - 2.125091750174761, - 2.4061264579650015, - 2.3765624158550054, - 2.258098457939923, - 2.652615417027846, - 2.596901083132252, - 2.1520592500455678, - 2.1606034578289837, - 2.951893666991964, - 2.7434714580886066, - 3.0087154579814523 - ], - "mean_time": 2.4027094041896206, - "std_time": 0.25433964365652706, + 0.3973630419932306, + 0.40906608290970325, + 0.4041848750784993, + 0.41167950024828315, + 0.43949729204177856 + ], + "mean_time": 0.40906608290970325, + "std_time": 0.015327474949396002, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomCrop80(height=80, width=80, p=1.0)": { + "Rotate(angle=45, interpolation=nearest, mode=constant, fill=0)": { "supported": true, - "warmup_iterations": 34, + "warmup_iterations": 24, "throughputs": [ - 27335.007682659467, - 28785.020769673218, - 27961.143050856972, - 28406.736907041806, - 28590.795972888824, - 27781.37861396605, - 29236.524425910095, - 28749.469969865575, - 28808.86223425408, - 29682.728854182584, - 28680.962800875273, - 28861.555674290907, - 26414.49625800602, - 28919.286297014012, - 29446.804727227885, - 27917.364699265487, - 30221.599656437957, - 29038.042484879465, - 28249.285856562095, - 29314.48117320955 - ], - "median_throughput": 28767.245369769396, - "std_throughput": 857.6858967017987, + 261.26766188956384, + 262.4047556929937, + 254.89858119985962, + 252.22680672178197, + 258.3533802150072 + ], + "median_throughput": 258.3533802150072, + "std_throughput": 4.272260133134954, "times": [ - 0.036583124892786145, - 0.03474029107019305, - 0.03576391702517867, - 0.035202916944399476, - 0.03497629100456834, - 0.035995333921164274, - 0.0342037919908762, - 0.0347832499537617, - 0.03471154090948403, - 0.033689624862745404, - 0.0348663330078125, - 0.034648166969418526, - 0.03785800002515316, - 0.03457899997010827, - 0.03395954193547368, - 0.03581999987363815, - 0.033088916912674904, - 0.03443758306093514, - 0.0353991249576211, - 0.034112832974642515 - ], - "mean_time": 0.034761757239741446, - "std_time": 0.001036410283496563, + 7.654984874650836, + 7.621813083067536, + 7.84625787474215, + 7.9293712908402085, + 7.741334749851376 + ], + "mean_time": 7.741334749851376, + "std_time": 0.12801456594652733, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomResizedCrop(height=512, width=512, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=bilinear, p=1.0)": { + "Affine(angle=25.0, shift=(20, 20), scale=2.0, shear=(10.0, 15.0), interpolation=bilinear, mode=constant, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 474.4091358551224, - 401.1030198131269, - 376.05982471648406, - 440.89116382477596, - 483.34882419215626, - 494.3739216747146, - 486.65388230968966, - 451.20969897885016, - 507.4333809743065, - 465.49396983725154, - 463.8635060947598, - 485.27980552236255, - 530.6351010768208, - 406.7945469484409, - 431.81891496764564, - 459.66346776757257, - 393.1041666991987, - 352.0049365161348, - 409.19801431454016, - 474.04537369457177 - ], - "median_throughput": 461.7634869311662, - "std_throughput": 46.90773500023627, + 187.7311050578477, + 187.6569765401613, + 186.3393171599938, + 190.48305846120888, + 187.79510093810765 + ], + "median_throughput": 187.7311050578477, + "std_throughput": 1.512894068311513, "times": [ - 2.107885207980871, - 2.4931250840891153, - 2.659151375060901, - 2.2681334579829127, - 2.068899208912626, - 2.022760417079553, - 2.0548484998289496, - 2.216264415998012, - 1.9707020418718457, - 2.1482555409893394, - 2.1558065828867257, - 2.0606668330729008, - 1.8845342081040144, - 2.458243374945596, - 2.3157855418976396, - 2.1755046248435974, - 2.5438550000544637, - 2.8408692500088364, - 2.443804625188932, - 2.109502709005028 - ], - "mean_time": 2.1656108122491444, - "std_time": 0.21999118806414444, + 10.653535541612655, + 10.65774391591549, + 10.7331079156138, + 10.499621415976435, + 10.649905082769692 + ], + "mean_time": 10.653535541612655, + "std_time": 0.08585508897145815, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ShiftRGB(pixel_shift=100, p=1.0, per_channel=True)": { - "supported": false - }, - "Resize(target_size=512, interpolation=bilinear, p=1.0)": { + "Perspective(scale=(0.05, 0.1), interpolation=bilinear, fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 173.99483996220025, - 156.4621672023894, - 173.99092965041245, - 192.32829051271517, - 180.8174204227238, - 168.96681781406377, - 160.2639386791262, - 178.73775972970375, - 173.02538563937998, - 184.6800638335957, - 177.03670214037174, - 186.12647962619187, - 172.94186709924386, - 177.86835096251238, - 191.22521355526618, - 195.83947522408306, - 182.97796967630518, - 196.23313650048016, - 191.48575044299838, - 193.36455353595844 - ], - "median_throughput": 179.77759007621378, - "std_throughput": 11.283959010147868, + 153.7607368001166, + 150.84376486643023, + 143.2207389652988, + 146.7236005619246, + 141.77389158979886 + ], + "median_throughput": 146.7236005619246, + "std_throughput": 5.044888149366217, "times": [ - 5.747296875109896, - 6.391321415780112, - 5.747426041169092, - 5.199443084187806, - 5.530440582893789, - 5.918321792036295, - 6.239706875057891, - 5.594788708956912, - 5.7794987498782575, - 5.414769625058398, - 5.648546250071377, - 5.372690667165443, - 5.782289833994582, - 5.622135667130351, - 5.229435916990042, - 5.106222833041102, - 5.465138791128993, - 5.095979291945696, - 5.222320708911866, - 5.171578666893765 - ], - "mean_time": 5.56242855172364, - "std_time": 0.3491325907078685, + 13.007221749983728, + 13.258751541841775, + 13.9644580418244, + 13.631072249729186, + 14.106969750020653 + ], + "mean_time": 13.631072249729186, + "std_time": 0.46868557336684435, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "RandomGamma(gamma=120, p=1.0)": { - "supported": false + "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True)": { + "supported": true, + "warmup_iterations": 11, + "throughputs": [], + "median_throughput": 3.172784237184834, + "std_throughput": 0.1126560907051603, + "times": [], + "mean_time": 0.30012217089533805, + "std_time": 0.0, + "variance_stable": false, + "early_stopped": true, + "early_stop_reason": "Transform too slow: 0.300 sec/image > 0.1 sec/image threshold" + }, + "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 86.44467701457258, + 87.66466755606078, + 88.04164264031746, + 87.49313137912166, + 87.32129871109245 + ], + "median_throughput": 87.49313137912166, + "std_throughput": 0.5935116581904234, + "times": [ + 23.136184541042894, + 22.814208457712084, + 22.71652300003916, + 22.858937249984592, + 22.903919542208314 + ], + "mean_time": 22.858937249984592, + "std_time": 0.15506412375299525, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "Grayscale(p=1.0, num_output_channels=3)": { + "ChannelShuffle()": { "supported": true, - "warmup_iterations": 43, + "warmup_iterations": 16, "throughputs": [ - 1066.676670009329, - 1204.9884110205817, - 1513.6813130728185, - 1645.904156132091, - 1058.1422723896978, - 1058.0162322312972, - 812.3606080127813, - 965.2734824372677, - 1203.9086698667497, - 1480.9339026495772, - 1614.5832385729595, - 989.8692652352288, - 1350.6126210247628, - 1564.9144109218003, - 1659.6408540603297, - 1766.603812206798, - 1805.8709758995512, - 1759.0621380878715, - 1667.0811193856864, - 1664.3408663506484 - ], - "median_throughput": 1497.307607861198, - "std_throughput": 317.4845967774298, + 4559.365793779506, + 4186.832148274046, + 4314.807258719196, + 4417.262726301525, + 4793.26976320739 + ], + "median_throughput": 4417.262726301525, + "std_throughput": 233.6173994628964, "times": [ - 0.937491208082065, - 0.8298835000023246, - 0.6606410420499742, - 0.6075687920674682, - 0.9450525001157075, - 0.9451650830451399, - 1.2309804169926792, - 1.0359758329577744, - 0.8306277918163687, - 0.6752495828550309, - 0.6193548750597984, - 1.0102344169281423, - 0.7404047499876469, - 0.639012583065778, - 0.6025399998761714, - 0.5660578750539571, - 0.5537494169548154, - 0.568484750110656, - 0.599850834114477, - 0.6008384581655264 - ], - "mean_time": 0.6678654371017535, - "std_time": 0.14161217634011256, + 0.4386574998497963, + 0.4776881253346801, + 0.4635201250202954, + 0.4527690843679011, + 0.4172517089173198 + ], + "mean_time": 0.45276908436790114, + "std_time": 0.023945765194679426, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "ColorJitter(brightness=0.5, contrast=1.5, saturation=1.5, hue=0.5, p=1.0)": { + "Grayscale(num_output_channels=1)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 45.02743963647953, - 46.27878418591268, - 46.66670607271724, - 45.564187299756526, - 46.98668367592637, - 47.499145638333474, - 43.87197937937806, - 49.398775732899004, - 48.671428488528996, - 45.07075000865419, - 42.44659604628005, - 43.163889971159286, - 43.53695459979305, - 46.40989238679391, - 45.67064389046156, - 48.7756212468615, - 49.2883679729386, - 48.82677469421654, - 48.67876867090862, - 49.366751695328716 - ], - "median_throughput": 46.53829922975558, - "std_throughput": 2.2327611251616415, + 2600.2035878652373, + 2612.548448718872, + 2618.0290663797523, + 2559.607935115105, + 2585.9588904823436 + ], + "median_throughput": 2600.2035878652373, + "std_throughput": 23.448559728044817, "times": [ - 22.20868004206568, - 21.608173541957512, - 21.42855333397165, - 21.947061042068526, - 21.282625666819513, - 21.0530102502089, - 22.79359204089269, - 20.243416666984558, - 20.54593487503007, - 22.187338790856302, - 23.559015166014433, - 23.167513416148722, - 22.96899287495762, - 21.54713033302687, - 21.895903250202537, - 20.502045375062153, - 20.288762666052207, - 20.48056637495756, - 20.542836791137233, - 20.256548499921337 - ], - "mean_time": 21.487678246750832, - "std_time": 1.0309111732353844, + 0.7691705408506095, + 0.7655360423959792, + 0.7639334588311613, + 0.7813696670345962, + 0.7734074997715652 + ], + "mean_time": 0.7691705408506095, + "std_time": 0.006936357388459544, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "PlankianJitter(mode=blackbody, p=1.0)": { + "RGBShift(pixel_shift=100)": { "supported": false }, - "RandomPerspective(scale=(0.05, 0.1), p=1.0, interpolation=bilinear)": { + "GaussianBlur(sigma=2.0, kernel_size=(5, 5))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 103.86700450635344, - 108.40335832008856, - 108.7767445528949, - 107.3229388010385, - 108.79904132544291, - 105.05757773274019, - 109.1600694440395, - 99.70592485298525, - 95.57706803760142, - 99.83451057034833, - 97.85702971990094, - 100.99068751057007, - 106.67271382121257, - 106.01066887030669, - 106.85874550633703, - 106.92024490091676, - 108.26224183384619, - 108.94801733623224, - 106.05094384592391, - 105.32847171453457 - ], - "median_throughput": 106.36182883356824, - "std_throughput": 4.060472658802428, + 124.38468193004252, + 127.17084406014074, + 129.93251329441767, + 129.38125076628285, + 119.99002493061397 + ], + "median_throughput": 127.17084406014074, + "std_throughput": 4.08808517899011, "times": [ - 9.627696540905163, - 9.224806458922103, - 9.193141457857564, - 9.31767254206352, - 9.191257457947358, - 9.518589915940538, - 9.160858957795426, - 10.029494249960408, - 10.462760791182518, - 10.0165763751138, - 10.218989916844293, - 9.901903082849458, - 9.374468541936949, - 9.433012834051624, - 9.358148416038603, - 9.352765707997605, - 9.23683070903644, - 9.178689291002229, - 9.429430457996204, - 9.494109082967043 - ], - "mean_time": 9.40186917587483, - "std_time": 0.3589260653839806, + 16.079150334000587, + 15.72687525022775, + 15.392606125213206, + 15.458190334029496, + 16.668052208144218 + ], + "mean_time": 15.72687525022775, + "std_time": 0.5055624667543885, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianBlur(sigma=2.0, kernel_size=(5, 5), p=1.0)": { + "GaussianNoise(mean=0, std=0.44, per_channel=True)": { + "supported": false + }, + "Invert()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 82.4255903216825, - 82.4810664943329, - 81.64415461541059, - 80.61061167961732, - 82.71688802721557, - 81.08437978704491, - 84.2094315941303, - 84.00979949080391, - 82.58668801563819, - 79.89257298772446, - 81.15388132022656, - 82.44935033509486, - 82.25640336903783, - 82.34600388959628, - 78.73890561247556, - 83.46641415935721, - 83.27610183120282, - 74.69657736752349, - 73.76912072603429, - 74.659519460862 - ], - "median_throughput": 82.30120362931706, - "std_throughput": 3.1190876996841506, + 4243.802950916812, + 4225.237928279612, + 4220.185362387556, + 4296.311216519017, + 4254.944576735482 + ], + "median_throughput": 4243.802950916812, + "std_throughput": 30.37900389902373, "times": [ - 12.132154542021453, - 12.12399454205297, - 12.248274291167036, - 12.405314625008032, - 12.089429666055366, - 12.332831583917141, - 11.875154374865815, - 11.903373250039294, - 12.108488959027454, - 12.516808041138574, - 12.322269541909918, - 12.12865833309479, - 12.157108249841258, - 12.143880124902353, - 12.700201916974038, - 11.980866916012019, - 12.008247000165284, - 13.387494249967858, - 13.555807499913499, - 13.394139250041917 - ], - "mean_time": 12.150490587039037, - "std_time": 0.46048470816848974, + 0.4712754157371819, + 0.47334612486884, + 0.47391283279284835, + 0.4655156247317791, + 0.47004137514159083 + ], + "mean_time": 0.47127541573718196, + "std_time": 0.0033735962432235285, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "MedianBlur(blur_limit=5, p=1.0)": { - "supported": false + "Posterize(bits=4)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 4264.947418681492, + 4207.749572009094, + 4275.8789939609815, + 4238.086508731166, + 4247.14339533553 + ], + "median_throughput": 4247.14339533553, + "std_throughput": 26.343348000338242, + "times": [ + 0.46893895836547017, + 0.4753134581260383, + 0.4677400840446353, + 0.47191108437255025, + 0.4709047502838075 + ], + "mean_time": 0.4709047502838075, + "std_time": 0.0029208356198575426, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "MotionBlur(kernel_size=5, angle=45, direction=0.0, p=1.0)": { - "supported": false + "Solarize(threshold=0.5)": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 1042.6397063947732, + 1045.0616424193536, + 1032.1547160685984, + 1029.1857349587094, + 1008.6010773224657 + ], + "median_throughput": 1032.1547160685984, + "std_throughput": 14.47542966977909, + "times": [ + 1.9182081669569016, + 1.9137627091258764, + 1.9376939996145666, + 1.9432838330976665, + 1.9829445406794548 + ], + "mean_time": 1.9376939996145668, + "std_time": 0.027175144168124343, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "Posterize(bits=4, p=1.0)": { + "Sharpen(alpha=(0.2, 0.5), lightness=(0.5, 1))": { "supported": true, - "warmup_iterations": 26, + "warmup_iterations": 16, "throughputs": [ - 2693.5002137178562, - 3115.8148409819746, - 3131.4124673322567, - 3047.975906321366, - 3156.360164537436, - 1474.5554402766, - 2685.386496966321, - 2984.992580120688, - 2973.553589708808, - 3051.2456705131694, - 3187.6819490943576, - 3107.548764372008, - 3175.827713517366, - 2977.948660991694, - 3052.0077449361524, - 3109.4035904642806, - 3176.2421349267493, - 3036.2240446994397, - 3242.774793590188, - 2998.1010720870145 - ], - "median_throughput": 3051.626707724661, - "std_throughput": 380.14970353526587, + 216.13016135598033, + 219.42484797478502, + 222.6179699901719, + 222.55017052839503, + 220.4086316241496 + ], + "median_throughput": 220.4086316241496, + "std_throughput": 2.672750527064949, "times": [ - 0.37126412498764694, - 0.3209433329757303, - 0.3193447079975158, - 0.3280865829437971, - 0.31682062498293817, - 0.6781704998575151, - 0.3723858748562634, - 0.3350092079490423, - 0.33629795792512596, - 0.32773500005714595, - 0.3137075831182301, - 0.32179704192094505, - 0.31487854197621346, - 0.33580162515863776, - 0.3276531659066677, - 0.3216050830669701, - 0.31483745807781816, - 0.32935645896941423, - 0.3083778750151396, - 0.3335444589611143 - ], - "mean_time": 0.327694077872852, - "std_time": 0.040821770971623976, + 9.253683000337332, + 9.114738000091165, + 8.98400070797652, + 8.986737665720284, + 9.074054792057723 + ], + "mean_time": 9.074054792057723, + "std_time": 0.11003509503858833, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "JpegCompression(quality=50, p=1.0)": { + "AutoContrast()": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 625.5691048663607, - 521.6015864099544, - 580.1749717295266, - 560.9877346730968, - 522.7912136557957, - 496.4400182241779, - 599.496602568609, - 546.0734947515396, - 551.6768078949613, - 557.7096315054724, - 632.6489564286444, - 618.5974357955314, - 634.5064601296474, - 629.5236685541037, - 623.1343291929877, - 606.8389999350735, - 606.1636079477146, - 606.5423322863477, - 617.3269158047102, - 618.7987182986049 - ], - "median_throughput": 606.3529701170312, - "std_throughput": 42.464409216348216, + 341.2565399588579, + 342.8451579802102, + 343.9269620917758, + 345.0110294708772, + 343.9899657233198 + ], + "median_throughput": 343.9269620917758, + "std_throughput": 1.4250666024188743, "times": [ - 1.598544416949153, - 1.9171720831654966, - 1.7236179579049349, - 1.7825701672118157, - 1.9128095000050962, - 2.014342041919008, - 1.6680661670397967, - 1.8312553339637816, - 1.8126554999034852, - 1.7930477501358837, - 1.5806554169394076, - 1.616560208844021, - 1.576028082985431, - 1.588502625003457, - 1.6047904170118272, - 1.6478835409507155, - 1.649719625012949, - 1.648689541965723, - 1.6198872500099242, - 1.616034375037998 - ], - "mean_time": 1.6492044226434508, - "std_time": 0.11549789468504777, + 5.860693542286754, + 5.833537249825895, + 5.815188166219741, + 5.796916124876589, + 5.814123082906008 + ], + "mean_time": 5.81518816621974, + "std_time": 0.024095320681051583, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "GaussianNoise(mean=127, var=0.01, per_channel=True, p=1.0)": { - "supported": false + "Equalize()": { + "supported": true, + "warmup_iterations": 16, + "throughputs": [ + 791.6451224811805, + 794.664161381646, + 792.4667451243379, + 799.3963224203335, + 796.6052005994766 + ], + "median_throughput": 794.664161381646, + "std_throughput": 3.1495949809098964, + "times": [ + 2.5263845417648554, + 2.5167864579707384, + 2.5237652081996202, + 2.5018879170529544, + 2.5106539581902325 + ], + "mean_time": 2.5167864579707384, + "std_time": 0.009975104429353617, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "Elastic(alpha=50.0, sigma=5.0, interpolation=bilinear, approximate=False, same_dxdy=True, p=1.0)": { + "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))": { "supported": true, - "warmup_iterations": 11, - "throughputs": [], - "median_throughput": 2.5179910199953315, - "std_throughput": 0.20205401736282502, - "times": [], - "mean_time": 0.46989290418568996, - "std_time": 0.0, - "variance_stable": false, - "early_stopped": true, - "early_stop_reason": "Transform too slow: 0.470 sec/image > 0.1 sec/image threshold" + "warmup_iterations": 16, + "throughputs": [ + 1026.8049354695293, + 1010.7673252804539, + 1017.8857800211667, + 1009.9340904539935, + 1017.5690719785213 + ], + "median_throughput": 1017.5690719785213, + "std_throughput": 6.804174860351097, + "times": [ + 1.947789624799043, + 1.978694749996066, + 1.964856999926269, + 1.980327249970287, + 1.9654685417190194 + ], + "mean_time": 1.9654685417190194, + "std_time": 0.01314249028262306, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null }, - "Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), p=1.0)": { + "Erasing(scale=(0.02, 0.33), ratio=(0.3, 3.3), fill=0)": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 480.27491890874484, - 544.0098531369014, - 538.5265844517252, - 516.3112846694526, - 507.4430261139117, - 532.7314295060406, - 539.3047432746873, - 532.0677335191737, - 536.6384060318086, - 511.603704863746, - 515.7920038166872, - 478.08139234475937, - 518.7826893727541, - 562.3443274615851, - 528.2691572804803, - 535.708856967954, - 526.8084246842421, - 533.3359169422904, - 525.5688018674806, - 518.9928123793733 - ], - "median_throughput": 527.5387909823612, - "std_throughput": 19.863309659936547, + 3610.415152081074, + 3577.1394823439477, + 3479.8267922024675, + 3577.28664714661, + 3548.374963955114 + ], + "median_throughput": 3577.1394823439477, + "std_throughput": 49.21250458656708, "times": [ - 2.0821407919283956, - 1.8382019998971373, - 1.8569185419473797, - 1.9368160830345005, - 1.9706645840778947, - 1.8771184589713812, - 1.854239207925275, - 1.87945995782502, - 1.8634521658532321, - 1.9546379169914871, - 1.9387659998610616, - 2.0916940420866013, - 1.9275893750600517, - 1.7782699160743505, - 1.8929744169581681, - 1.8666855830233544, - 1.8982232499402016, - 1.8749909170437604, - 1.9027004579547793, - 1.9268089579418302 - ], - "mean_time": 1.8955952000000622, - "std_time": 0.07137445642125215, + 0.5539529155939817, + 0.559105958789587, + 0.5747412499040365, + 0.5590829579159617, + 0.5636382908560336 + ], + "mean_time": 0.559105958789587, + "std_time": 0.007691901503175414, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Clahe(clip_limit=(1, 4), tile_grid_size=(8, 8), p=1.0)": { + "JpegCompression(quality=50)": { + "supported": true, + "warmup_iterations": 17, + "throughputs": [ + 892.0013790118184, + 892.3077823909521, + 888.7909736596862, + 881.1726558391205, + 875.5952130581404 + ], + "median_throughput": 888.7909736596862, + "std_throughput": 7.334056876420792, + "times": [ + 2.242149000056088, + 2.2413790840655565, + 2.250247875228524, + 2.2697027497924864, + 2.2841605003923178 + ], + "mean_time": 2.250247875228524, + "std_time": 0.01856842203855473, + "variance_stable": true, + "early_stopped": false, + "early_stop_reason": null + }, + "RandomGamma(gamma=120)": { + "supported": false + }, + "PlankianJitter(mode=blackbody)": { + "supported": false + }, + "MedianBlur(blur_limit=5)": { "supported": false }, - "Brightness(brightness_limit=(0.2, 0.2), p=1.0)": { + "MotionBlur(kernel_size=5, angle_range=(0, 360), direction_range=(-1, 1))": { + "supported": false + }, + "CLAHE(clip_limit=(1, 4), tile_grid_size=(8, 8))": { + "supported": false + }, + "Brightness(brightness_limit=(0.2, 0.2))": { "supported": true, - "warmup_iterations": 17, + "warmup_iterations": 16, "throughputs": [ - 419.04826497644615, - 428.62407280473485, - 441.2410182047314, - 448.1216811721902, - 432.1706614917835, - 437.66155765725796, - 446.2466860689512, - 447.19125893655945, - 450.802953400887, - 442.7275388089713, - 450.4587019601217, - 450.9975474398613, - 449.65169420367556, - 455.8342569275217, - 451.00379350317274, - 457.39732691754847, - 453.70225572069876, - 457.0165465544545, - 453.86626265804324, - 401.5687887096356 - ], - "median_throughput": 448.88668768793286, - "std_throughput": 14.101675659084481, + 856.0870725245223, + 825.9392839832443, + 848.079027621902, + 854.3951528461477, + 857.1719855313169 + ], + "median_throughput": 854.3951528461477, + "std_throughput": 13.005249043739529, "times": [ - 2.3863599579781294, - 2.3330467499326915, - 2.266335083870217, - 2.2315367499832064, - 2.313900708919391, - 2.2848705409560353, - 2.2409129999578, - 2.236179665895179, - 2.2182640829123557, - 2.258725541876629, - 2.2199593340046704, - 2.2173069580458105, - 2.223943583201617, - 2.1937798329163343, - 2.217276250012219, - 2.1862829998135567, - 2.2040886669419706, - 2.188104582950473, - 2.203292208025232, - 2.4902333749923855 - ], - "mean_time": 2.227733696338089, - "std_time": 0.06998375960396659, + 2.3362109581939876, + 2.421485499944538, + 2.358270791824907, + 2.3408372499980032, + 2.333254042081535 + ], + "mean_time": 2.3408372499980032, + "std_time": 0.03563125481889099, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "Contrast(contrast_limit=(0.2, 0.2), p=1.0)": { + "Contrast(contrast_limit=(0.2, 0.2))": { "supported": true, "warmup_iterations": 16, "throughputs": [ - 344.15708808690744, - 359.04679356881064, - 359.3640800912368, - 361.29190758488494, - 358.09464815753535, - 350.072175500547, - 358.28329630005567, - 356.79780385652526, - 355.0119035393361, - 355.33365893401475, - 356.47678142390413, - 358.4978242600958, - 355.4823577863792, - 357.607619325319, - 358.43233347460034, - 355.334132295845, - 356.3526821027158, - 360.04946356117455, - 360.85998890082845, - 358.6305869477121 - ], - "median_throughput": 357.85113374142713, - "std_throughput": 3.885729592320152, + 614.422115190534, + 611.409746570309, + 596.1138592475392, + 601.5947827644763, + 581.1799474769623 + ], + "median_throughput": 601.5947827644763, + "std_throughput": 13.281217850323712, "times": [ - 2.905649875057861, - 2.785152291879058, - 2.782693250104785, - 2.767845000140369, - 2.792557792039588, - 2.8565537908580154, - 2.791087416931987, - 2.802707833936438, - 2.8168069578241557, - 2.814256333047524, - 2.8052317909896374, - 2.7894172079395503, - 2.813079125015065, - 2.7963610000442713, - 2.7899268749170005, - 2.8142525840085, - 2.8062087090220302, - 2.777396166929975, - 2.7711578749585897, - 2.78838458401151 - ], - "mean_time": 2.7944581020178383, - "std_time": 0.030343647169651176, + 3.2550911670550704, + 3.2711287499405444, + 3.3550637499429286, + 3.3244969160296023, + 3.44127495912835 + ], + "mean_time": 3.324496916029602, + "std_time": 0.07339386751597624, "variance_stable": true, "early_stopped": false, "early_stop_reason": null }, - "CoarseDropout(hole_height_range=(16, 16), hole_width_range=(16, 16), num_holes_range=(1, 1), p=1.0)": { + "CoarseDropout(hole_height_range=(0.1, 0.1), hole_width_range=(0.1, 0.1), num_holes_range=(4, 4))": { + "supported": false + }, + "Blur(radius=5, border_mode=constant)": { + "supported": false + }, + "HSV(hue=0.015, saturation=0.7, value=0.4)": { + "supported": false + }, + "ChannelDropout()": { + "supported": false + }, + "LinearIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "CornerIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "GaussianIllumination(gain=(0.01, 0.2))": { + "supported": false + }, + "Hue(hue=20)": { + "supported": false + }, + "PlasmaBrightness(roughness=0.5)": { + "supported": false + }, + "PlasmaContrast(roughness=0.5)": { + "supported": false + }, + "PlasmaShadow(roughness=0.5)": { + "supported": false + }, + "Rain(drop_width=5, drop_height=20)": { + "supported": false + }, + "SaltAndPepper(amount=(0.01, 0.06), salt_vs_pepper=(0.4, 0.6))": { + "supported": false + }, + "Saturation(saturation_factor=0.5)": { + "supported": false + }, + "Snow(snow_point_range=(0.5, 0.5))": { + "supported": false + }, + "OpticalDistortion(distort_limit=0.5)": { "supported": false }, - "Blur(radius=5, p=1.0)": { + "Shear(shear=10)": { "supported": false }, - "HSV(hue=0.015, saturation=0.7, value=0.4, p=1.0)": { + "ThinPlateSpline(num_control_points=4, distortion_scale=0.5)": { "supported": false } } diff --git a/requirements/albumentations.txt b/requirements/albumentations.txt index 49f00f6..ac4b394 100644 --- a/requirements/albumentations.txt +++ b/requirements/albumentations.txt @@ -1 +1,2 @@ -git+https://github.com/albumentations-team/albumentations.git +# git+https://github.com/albumentations-team/albumentations.git +../albumentations diff --git a/run_all.sh b/run_all.sh index 3eb19ed..071c575 100755 --- a/run_all.sh +++ b/run_all.sh @@ -71,6 +71,7 @@ mkdir -p "$OUTPUT_DIR" # Libraries to benchmark LIBRARIES=("albumentations" "imgaug" "torchvision" "kornia" "augly") + # Run benchmarks for each library for library in "${LIBRARIES[@]}"; do echo "Running benchmark for ${library}..." diff --git a/run_single.sh b/run_single.sh index c24b1d0..180b871 100755 --- a/run_single.sh +++ b/run_single.sh @@ -93,7 +93,7 @@ echo "Installing requirements..." pip install -U uv uv pip install setuptools uv pip install -U -r "${SCRIPT_DIR}/requirements/requirements.txt" -uv pip install -U -r "${SCRIPT_DIR}/requirements/${LIBRARY}.txt" +uv pip install -U --force-reinstall -r "${SCRIPT_DIR}/requirements/${LIBRARY}.txt" # Run benchmark echo "Running benchmark..." From 5bd86b71bcd2f0bcb3c0a73583606496967744a1 Mon Sep 17 00:00:00 2001 From: Vladimir Iglovikov Date: Thu, 30 Jan 2025 12:39:07 -0800 Subject: [PATCH 4/5] Updated pre-commit hook --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b56131c..d3bdacf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: - id: requirements-txt-fixer - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.2 + rev: v0.9.4 hooks: # Run the linter. - id: ruff @@ -54,7 +54,7 @@ repos: - id: python-use-type-annotations - id: text-unicode-replacement-char - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 + rev: v2.4.1 hooks: - id: codespell additional_dependencies: ["tomli"] From fc95368ccf4c4bc66f72eb803f614f5f390e5598 Mon Sep 17 00:00:00 2001 From: Vladimir Iglovikov Date: Thu, 30 Jan 2025 17:31:57 -0800 Subject: [PATCH 5/5] Updated benchmark --- .gitignore | 2 + README.md | 106 ++++++++++------ output/comparison.csv | 52 ++++++++ run_all.sh | 4 +- speedup_analysis.png | Bin 0 -> 215515 bytes tools/__init__.py | 0 {benchmark => tools}/compare_results.py | 2 + tools/generate_tables.py | 158 ++++++++++++++++++++++++ 8 files changed, 283 insertions(+), 41 deletions(-) create mode 100644 output/comparison.csv create mode 100644 speedup_analysis.png create mode 100644 tools/__init__.py rename {benchmark => tools}/compare_results.py (98%) create mode 100644 tools/generate_tables.py diff --git a/.gitignore b/.gitignore index c56ae5a..5e66281 100644 --- a/.gitignore +++ b/.gitignore @@ -168,3 +168,5 @@ conda_build/ data/ .venv_* + +notebooks/ diff --git a/README.md b/README.md index b434dc6..d92d9f2 100644 --- a/README.md +++ b/README.md @@ -40,62 +40,90 @@ This benchmark suite measures the throughput and performance characteristics of - Thread control settings for consistent single-threaded performance - Support for multiple image formats and loading methods -## Benchmark Results + +![Albumentations vs TorchVision vs Kornia](speedup_analysis.png) + +# Benchmark Results ### System Information -- Platform: macOS-15.0.1-arm64-arm-64bit +- Platform: macOS-15.1-arm64-arm-64bit - Processor: arm -- CPU Count: 10 -- Python Version: 3.12.7 +- CPU Count: 16 +- Python Version: 3.12.8 ### Benchmark Parameters -- Number of images: 1000 -- Runs per transform: 20 +- Number of images: 2000 +- Runs per transform: 5 - Max warmup iterations: 1000 ### Library Versions -- albumentations: 1.4.21 +- albumentations: 2.0.2 - augly: 1.0.0 - imgaug: 0.4.0 -- kornia: 0.7.3 +- kornia: 0.8.0 - torchvision: 0.20.1 ## Performance Comparison -| Transform | albumentations
1.4.21 | augly
1.0.0 | imgaug
0.4.0 | kornia
0.7.3 | torchvision
0.20.1 | -|:------------------|:---------------------------|:-----------------|:------------------|:------------------|:------------------------| -| HorizontalFlip | **8622 ± 891** | 4121 ± 1001 | 6162 ± 393 | 571 ± 84 | 861 ± 38 | -| VerticalFlip | **23951 ± 5013** | 7775 ± 1376 | 11663 ± 2258 | 1590 ± 100 | 3156 ± 402 | -| Rotate | 1163 ± 84 | 1095 ± 82 | **1224 ± 75** | 167 ± 11 | 160 ± 11 | -| Affine | **907 ± 49** | - | 890 ± 34 | 181 ± 6 | 129 ± 16 | -| Equalize | **852 ± 90** | - | 610 ± 35 | 184 ± 9 | 416 ± 44 | -| RandomCrop80 | **107764 ± 3630** | 25192 ± 5964 | 12343 ± 2013 | 1492 ± 22 | 28767 ± 858 | -| ShiftRGB | **2351 ± 276** | - | 1674 ± 63 | - | - | -| Resize | **2372 ± 156** | 632 ± 38 | 2025 ± 74 | 332 ± 18 | 180 ± 11 | -| RandomGamma | **9014 ± 371** | - | 2592 ± 143 | 128 ± 10 | - | -| Grayscale | **11373 ± 923** | 3359 ± 65 | 1849 ± 75 | 628 ± 75 | 1497 ± 317 | -| RandomPerspective | 401 ± 24 | - | **596 ± 38** | 98 ± 7 | 106 ± 4 | -| GaussianBlur | **1664 ± 144** | 235 ± 18 | 1043 ± 142 | 165 ± 12 | 82 ± 3 | -| MedianBlur | 847 ± 36 | - | **849 ± 32** | 4 ± 0 | - | -| MotionBlur | **3928 ± 742** | - | 663 ± 36 | 75 ± 6 | - | -| Posterize | **9034 ± 331** | - | 2400 ± 142 | 363 ± 69 | 3052 ± 380 | -| JpegCompression | **906 ± 40** | 754 ± 14 | 443 ± 79 | 69 ± 3 | 606 ± 42 | -| GaussianNoise | 183 ± 5 | 70 ± 1 | **204 ± 18** | 65 ± 2 | - | -| Elastic | 229 ± 17 | - | **251 ± 22** | 1 ± 0 | 3 ± 0 | -| Clahe | **471 ± 18** | - | 422 ± 12 | 90 ± 2 | - | -| Brightness | **9251 ± 709** | 1297 ± 42 | 742 ± 39 | 519 ± 15 | 449 ± 14 | -| Contrast | **9146 ± 1034** | 880 ± 9 | 510 ± 9 | 476 ± 116 | 358 ± 4 | -| CoarseDropout | **14488 ± 2108** | - | 653 ± 85 | 526 ± 86 | - | -| Blur | **5804 ± 305** | 243 ± 9 | 3857 ± 385 | - | - | -| ColorJitter | **700 ± 31** | 252 ± 15 | - | 50 ± 4 | 47 ± 2 | -| RandomResizedCrop | **2879 ± 158** | - | - | 321 ± 10 | 462 ± 47 | -| Normalize | **1349 ± 65** | - | - | 645 ± 40 | 528 ± 20 | -| PlankianJitter | **2155 ± 340** | - | - | 1023 ± 114 | - | -| HSV | **1243 ± 44** | - | - | - | - | -## Requirements +Number shows how many uint8 images per second can be processed on one CPU thread. Larger is better. + +| Transform | albumentations
2.0.2 | augly
1.0.0 | imgaug
0.4.0 | kornia
0.8.0 | torchvision
0.20.1 | +|:---------------------|:--------------------------|:-----------------|:------------------|:------------------|:------------------------| +| Resize | **3662 ± 54** | 1083 ± 21 | 2995 ± 70 | 645 ± 13 | 260 ± 9 | +| RandomCrop128 | **116784 ± 2222** | 45395 ± 934 | 21408 ± 622 | 2946 ± 42 | 31450 ± 249 | +| HorizontalFlip | **12649 ± 238** | 8808 ± 1012 | 9599 ± 495 | 1297 ± 13 | 2486 ± 107 | +| VerticalFlip | **24989 ± 904** | 16830 ± 1653 | 19935 ± 1708 | 2872 ± 37 | 4696 ± 161 | +| Rotate | **3066 ± 83** | 1739 ± 105 | 2574 ± 10 | 256 ± 2 | 258 ± 4 | +| Affine | **1503 ± 29** | - | 1328 ± 16 | 248 ± 6 | 188 ± 2 | +| Perspective | **1222 ± 16** | - | 908 ± 8 | 154 ± 3 | 147 ± 5 | +| Elastic | 359 ± 7 | - | **395 ± 14** | 1 ± 0 | 3 ± 0 | +| ChannelShuffle | **8162 ± 180** | - | 1252 ± 26 | 1328 ± 44 | 4417 ± 234 | +| Grayscale | **37212 ± 1856** | 6088 ± 107 | 3100 ± 24 | 1201 ± 52 | 2600 ± 23 | +| GaussianBlur | 943 ± 11 | 387 ± 4 | **1460 ± 23** | 254 ± 5 | 127 ± 4 | +| GaussianNoise | 234 ± 7 | - | **263 ± 9** | 125 ± 1 | - | +| Invert | **35494 ± 17186** | - | 3682 ± 79 | 2881 ± 43 | 4244 ± 30 | +| Posterize | **14146 ± 1381** | - | 3111 ± 95 | 836 ± 30 | 4247 ± 26 | +| Solarize | **12920 ± 1097** | - | 3843 ± 80 | 263 ± 6 | 1032 ± 14 | +| Sharpen | **2375 ± 38** | - | 1101 ± 30 | 201 ± 2 | 220 ± 3 | +| Equalize | **1303 ± 64** | - | 814 ± 11 | 306 ± 1 | 795 ± 3 | +| JpegCompression | **1354 ± 23** | 1202 ± 19 | 687 ± 26 | 120 ± 1 | 889 ± 7 | +| RandomGamma | **12631 ± 1159** | - | 3504 ± 72 | 230 ± 3 | - | +| MedianBlur | **1259 ± 8** | - | 1152 ± 14 | 6 ± 0 | - | +| MotionBlur | **3608 ± 18** | - | 928 ± 37 | 159 ± 1 | - | +| CLAHE | **649 ± 13** | - | 555 ± 14 | 165 ± 3 | - | +| Brightness | **11254 ± 418** | 2108 ± 32 | 1076 ± 32 | 1127 ± 27 | 854 ± 13 | +| Contrast | **11255 ± 242** | 1379 ± 25 | 717 ± 5 | 1109 ± 41 | 602 ± 13 | +| CoarseDropout | **15760 ± 594** | - | 1190 ± 22 | - | - | +| Blur | **7403 ± 114** | 386 ± 4 | 5381 ± 125 | 265 ± 11 | - | +| Saturation | **1581 ± 127** | - | 495 ± 3 | 155 ± 2 | - | +| Shear | **1336 ± 18** | - | 1244 ± 14 | 261 ± 1 | - | +| ColorJitter | **968 ± 52** | 418 ± 5 | - | 104 ± 4 | 87 ± 1 | +| RandomResizedCrop | **4521 ± 17** | - | - | 661 ± 16 | 837 ± 37 | +| Pad | **31866 ± 530** | - | - | - | 4889 ± 183 | +| AutoContrast | **1534 ± 115** | - | - | 541 ± 8 | 344 ± 1 | +| Normalize | **1797 ± 190** | - | - | 1251 ± 14 | 1018 ± 7 | +| Erasing | **25411 ± 5727** | - | - | 1210 ± 27 | 3577 ± 49 | +| CenterCrop128 | **119630 ± 3484** | - | - | - | - | +| RGBShift | **3526 ± 128** | - | - | 896 ± 9 | - | +| PlankianJitter | **3351 ± 42** | - | - | 2150 ± 52 | - | +| HSV | **1277 ± 91** | - | - | - | - | +| ChannelDropout | **10988 ± 243** | - | - | 2283 ± 24 | - | +| LinearIllumination | 462 ± 52 | - | - | **708 ± 6** | - | +| CornerIllumination | **464 ± 45** | - | - | 452 ± 3 | - | +| GaussianIllumination | **670 ± 91** | - | - | 436 ± 13 | - | +| Hue | **1846 ± 193** | - | - | 150 ± 1 | - | +| PlasmaBrightness | **163 ± 1** | - | - | 85 ± 1 | - | +| PlasmaContrast | **138 ± 4** | - | - | 84 ± 0 | - | +| PlasmaShadow | 190 ± 3 | - | - | **216 ± 5** | - | +| Rain | **2121 ± 64** | - | - | 1493 ± 9 | - | +| SaltAndPepper | **2233 ± 35** | - | - | 480 ± 12 | - | +| Snow | **588 ± 32** | - | - | 143 ± 1 | - | +| OpticalDistortion | **687 ± 38** | - | - | 174 ± 0 | - | +| ThinPlateSpline | **75 ± 5** | - | - | 58 ± 0 | - | + The benchmark automatically creates isolated virtual environments for each library and installs the necessary dependencies. Base requirements: diff --git a/output/comparison.csv b/output/comparison.csv new file mode 100644 index 0000000..2916178 --- /dev/null +++ b/output/comparison.csv @@ -0,0 +1,52 @@ +Transform,albumentations
2.0.2,augly
1.0.0,imgaug
0.4.0,kornia
0.8.0,torchvision
0.20.1 +Resize,**3662 ± 54**,1083 ± 21,2995 ± 70,645 ± 13,260 ± 9 +RandomCrop128,**116784 ± 2222**,45395 ± 934,21408 ± 622,2946 ± 42,31450 ± 249 +HorizontalFlip,**12649 ± 238**,8808 ± 1012,9599 ± 495,1297 ± 13,2486 ± 107 +VerticalFlip,**24989 ± 904**,16830 ± 1653,19935 ± 1708,2872 ± 37,4696 ± 161 +Rotate,**3066 ± 83**,1739 ± 105,2574 ± 10,256 ± 2,258 ± 4 +Affine,**1503 ± 29**,-,1328 ± 16,248 ± 6,188 ± 2 +Perspective,**1222 ± 16**,-,908 ± 8,154 ± 3,147 ± 5 +Elastic,359 ± 7,-,**395 ± 14**,1 ± 0,3 ± 0 +ChannelShuffle,**8162 ± 180**,-,1252 ± 26,1328 ± 44,4417 ± 234 +Grayscale,**37212 ± 1856**,6088 ± 107,3100 ± 24,1201 ± 52,2600 ± 23 +GaussianBlur,943 ± 11,387 ± 4,**1460 ± 23**,254 ± 5,127 ± 4 +GaussianNoise,234 ± 7,-,**263 ± 9**,125 ± 1,- +Invert,**35494 ± 17186**,-,3682 ± 79,2881 ± 43,4244 ± 30 +Posterize,**14146 ± 1381**,-,3111 ± 95,836 ± 30,4247 ± 26 +Solarize,**12920 ± 1097**,-,3843 ± 80,263 ± 6,1032 ± 14 +Sharpen,**2375 ± 38**,-,1101 ± 30,201 ± 2,220 ± 3 +Equalize,**1303 ± 64**,-,814 ± 11,306 ± 1,795 ± 3 +JpegCompression,**1354 ± 23**,1202 ± 19,687 ± 26,120 ± 1,889 ± 7 +RandomGamma,**12631 ± 1159**,-,3504 ± 72,230 ± 3,- +MedianBlur,**1259 ± 8**,-,1152 ± 14,6 ± 0,- +MotionBlur,**3608 ± 18**,-,928 ± 37,159 ± 1,- +CLAHE,**649 ± 13**,-,555 ± 14,165 ± 3,- +Brightness,**11254 ± 418**,2108 ± 32,1076 ± 32,1127 ± 27,854 ± 13 +Contrast,**11255 ± 242**,1379 ± 25,717 ± 5,1109 ± 41,602 ± 13 +CoarseDropout,**15760 ± 594**,-,1190 ± 22,-,- +Blur,**7403 ± 114**,386 ± 4,5381 ± 125,265 ± 11,- +Saturation,**1581 ± 127**,-,495 ± 3,155 ± 2,- +Shear,**1336 ± 18**,-,1244 ± 14,261 ± 1,- +ColorJitter,**968 ± 52**,418 ± 5,-,104 ± 4,87 ± 1 +RandomResizedCrop,**4521 ± 17**,-,-,661 ± 16,837 ± 37 +Pad,**31866 ± 530**,-,-,-,4889 ± 183 +AutoContrast,**1534 ± 115**,-,-,541 ± 8,344 ± 1 +Normalize,**1797 ± 190**,-,-,1251 ± 14,1018 ± 7 +Erasing,**25411 ± 5727**,-,-,1210 ± 27,3577 ± 49 +CenterCrop128,**119630 ± 3484**,-,-,-,- +RGBShift,**3526 ± 128**,-,-,896 ± 9,- +PlankianJitter,**3351 ± 42**,-,-,2150 ± 52,- +HSV,**1277 ± 91**,-,-,-,- +ChannelDropout,**10988 ± 243**,-,-,2283 ± 24,- +LinearIllumination,462 ± 52,-,-,**708 ± 6**,- +CornerIllumination,**464 ± 45**,-,-,452 ± 3,- +GaussianIllumination,**670 ± 91**,-,-,436 ± 13,- +Hue,**1846 ± 193**,-,-,150 ± 1,- +PlasmaBrightness,**163 ± 1**,-,-,85 ± 1,- +PlasmaContrast,**138 ± 4**,-,-,84 ± 0,- +PlasmaShadow,190 ± 3,-,-,**216 ± 5**,- +Rain,**2121 ± 64**,-,-,1493 ± 9,- +SaltAndPepper,**2233 ± 35**,-,-,480 ± 12,- +Snow,**588 ± 32**,-,-,143 ± 1,- +OpticalDistortion,**687 ± 38**,-,-,174 ± 0,- +ThinPlateSpline,**75 ± 5**,-,-,58 ± 0,- diff --git a/run_all.sh b/run_all.sh index 071c575..aa7d859 100755 --- a/run_all.sh +++ b/run_all.sh @@ -89,8 +89,8 @@ done # Generate comparison table echo "Generating comparison table..." -python -m benchmark.compare_results -r "$OUTPUT_DIR" -o"${OUTPUT_DIR}/comparison.md" +python -m tools.compare_results -r "$OUTPUT_DIR" -o"${OUTPUT_DIR}/comparison.md" echo "All benchmarks complete." echo "Individual results saved in: $OUTPUT_DIR" -echo "Comparison table saved as: ${OUTPUT_DIR}/comparison.csv" +echo "Comparison table saved as: ${OUTPUT_DIR}/comparison.md" diff --git a/speedup_analysis.png b/speedup_analysis.png new file mode 100644 index 0000000000000000000000000000000000000000..f426721ba229842896961b9b9209470f48769418 GIT binary patch literal 215515 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%0D4jI$(^wc}^(HMV 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%0Ar^9LM*U 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⋙~+$DR`Dq;2Xj8?C!sO_Na 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 i&;N5zlHj(m%F?)>Bo?OPc#Q>qoj7Ljk3z!vTmJ None: df = create_comparison_table(args.results_dir) markdown_table = df.to_markdown(index=False) + df.to_csv(args.output.with_suffix(".csv"), index=False) + # Combine summary and table full_report = f"""# Benchmark Results diff --git a/tools/generate_tables.py b/tools/generate_tables.py new file mode 100644 index 0000000..b82e4b7 --- /dev/null +++ b/tools/generate_tables.py @@ -0,0 +1,158 @@ +import csv +from pathlib import Path +from typing import Any, Tuple + +def parse_throughput(value: str) -> Tuple[float, float]: + """Parse throughput string like '3662 ± 54' or '-' into (value, std)""" + if value == '-': + return (0, 0) + # Remove bold markers if present + value = value.replace('**', '') + parts = value.split('±') + return (float(parts[0].strip()), float(parts[1].strip())) + +def load_results_from_csv(csv_path: Path) -> dict[str, list[Tuple[float, float]]]: + """Load results from CSV file into a dictionary mapping transform names to lists of (value, std) tuples""" + import pandas as pd + + df = pd.read_csv(csv_path) + results = {} + + # Select only the columns we want, using partial matches + albumentations_col = [col for col in df.columns if col.startswith('albumentations')][0] + torchvision_col = [col for col in df.columns if col.startswith('torchvision')][0] + kornia_col = [col for col in df.columns if col.startswith('kornia')][0] + + columns = ['Transform', albumentations_col, torchvision_col, kornia_col] + df = df[columns] + + for _, row in df.iterrows(): + transform = row['Transform'] + # Get throughput values for each library (skip the Transform column) + throughputs = [parse_throughput(val) for val in row.iloc[1:]] + results[transform] = throughputs + + return results + +def format_throughput(value: float, std: float) -> str: + if value == 0: + return "-" + return f"{int(value)} ± {int(std)}" + + +def calculate_speedup(values: list[float]) -> float: + """Calculate speedup ratio between Albumentations and the best of other libraries. + Returns > 1 if Albumentations is faster, < 1 if another library is faster.""" + albumentations_value = values[0] # First value is Albumentations + other_values = [v for v in values[1:] if v > 0] # Rest are other libraries + + if albumentations_value == 0 or not other_values: + return 0 + + best_other = max(other_values) + return albumentations_value / best_other + + +# Sets of transform names to look for in results +SPATIAL_TRANSFORMS: set[str] = { + "Resize", + "RandomCrop128", + "HorizontalFlip", + "VerticalFlip", + "Rotate", + "Affine", + "Perspective", + "Elastic", + "Shear", + "RandomResizedCrop", + "Pad", + "Erasing", + "OpticalDistortion", + "ThinPlateSpline", +} + +PIXEL_TRANSFORMS: set[str] = { + "ChannelShuffle", + "Grayscale", + "GaussianBlur", + "GaussianNoise", + "Invert", + "Posterize", + "Solarize", + "Sharpen", + "Equalize", + "JpegCompression", + "RandomGamma", + "MedianBlur", + "MotionBlur", + "CLAHE", + "Brightness", + "Contrast", + "Blur", + "Saturation", + "ColorJitter", + "AutoContrast", + "Normalize", + "RGBShift", + "PlankianJitter", + "ChannelDropout", + "LinearIllumination", + "CornerIllumination", + "GaussianIllumination", + "Hue", + "PlasmaBrightness", + "PlasmaContrast", + "PlasmaShadow", + "Rain", + "SaltAndPepper", + "Snow", +} + +def generate_comparison_tables(csv_path: Path) -> str: + results = load_results_from_csv(csv_path) + + markdown = "## Performance Comparison (images/second, higher is better)\n\n" + + # Generate tables for both categories + for category, transforms in [("Spatial Transformations", SPATIAL_TRANSFORMS), + ("Pixel-Level Transformations", PIXEL_TRANSFORMS)]: + markdown += f"### {category}\n" + markdown += "| Transform | Albumentations | TorchVision | Kornia | Speedup* |\n" + markdown += "|-----------|---------------|-------------|--------|----------|\n" + + for transform_name in sorted(transforms): + if transform_name not in results: + continue + + throughputs = results[transform_name] + values = [t[0] for t in throughputs] + + # Format strings and bold the highest value + max_val = max(values) + formatted = [] + for val, std in throughputs: + if val == 0: + formatted.append("-") + elif val == max_val: + formatted.append(f"**{format_throughput(val, std)}**") + else: + formatted.append(format_throughput(val, std)) + + # Calculate speedup + speedup = calculate_speedup(values) + speedup_str = f"{speedup:.1f}x" if speedup > 0 else "-" + + markdown += f"| {transform_name} | {' | '.join(formatted)} | {speedup_str} |\n" + + markdown += "\n*Speedup shows how many times the fastest library is faster than the second-best library\n\n" + + return markdown + +if __name__ == "__main__": + import argparse + parser = argparse.ArgumentParser(description='Generate comparison tables from benchmark results') + parser.add_argument("-f", '--file', type=str, help='Path to CSV file containing benchmark results') + args = parser.parse_args() + + markdown = generate_comparison_tables(Path(args.file)) + print(markdown)