question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`A.Compose`, `A.Sequential` components run multiple times inside of `A.OneOf`

See original GitHub issue

🐛 Bug

Hi, I used A.OneOf method on my A.Compose objects, but when I run entire pipeline, all components of A.Compose objects are called altogether.

To Reproduce

Steps to reproduce the behavior:

  1. define augmentation
class Augmentation():

    def __init__(self, 
                 dataset_w:int=None, 
                 dataset_h:int=None, 
                 final_return_w:int=None, 
                 final_return_h:int=None):
        
        self.train_augmentation = self.set_train_augmentation(
            dataset_w=dataset_w,
            dataset_h=dataset_h,
            final_return_w=final_return_w,
            final_return_h=final_return_h,
        )

    def get_train_augmentation(self):
        return lambda image, mask: list(self.train_augmentation(image=image, mask=mask).values())
    
    def set_train_augmentation(self, **kwargs):
        ret = self.augmentation_method(**kwargs)
        return ret

    def _slightly_smaller(self,
        target_h:int,
        target_w:int, 
        original_h:int,
        original_w:int,
        ratio:float=0.5
    )->tuple:
        assert 0. < ratio and ratio < 1, f'0 < ratio {repr(ratio)} < 1'
        dw = int((original_w - target_w) * ratio)
        dh = int((original_h - target_h) * ratio)
        return (target_h + dh, target_w + dw)

    def _get_crop(self,
        target_h:int,
        target_w:int,
    )->list:
        tf = []
        tf += [A.RandomCrop(target_h, target_w, p=1.0)]
        return tf

    def _get_resize(self,
        target_h:int,
        target_w:int
    )->list:
        tf = []
        tf += [A.Resize(target_h, target_w, p=1.0)]
        return tf

    def _get_pad(self,
        target_h:int,
        target_w:int
    )->list:
        longer_side = target_h if target_h > target_w else target_w
        tf = []
        tf += [A.PadIfNeeded(
            min_height=longer_side,
            min_width=longer_side,
            p=1.0,
            border_mode=4)]
        return tf

    def _get_resize_crop(self,
        target_h:int,
        target_w:int,
        original_h:int,
        original_w:int,
    )->list:
        tf = []
        tf += self._get_resize(*self._slightly_smaller(
            target_h, target_w, 
            original_h, original_w)
        )
        tf += self._get_crop(target_h, target_w)
        return tf

    def _get_crop_resize(self,
        target_h:int,
        target_w:int,
        original_h:int,
        original_w:int,
    )->list:
        tf = []
        tf += self._get_crop(*self._slightly_smaller(
            target_h, target_w, 
            original_h, original_w)
        )
        tf += self._get_resize(target_h, target_w)
        return tf

    def _get_pad_resize(self,
        target_h:int,
        target_w:int,
        original_h:int,
        original_w:int,
    )->list:
        tf = []
        tf += self._get_pad(original_h, original_w)
        tf += self._get_reszie(target_h, target_w)
        return tf

    def _get_pad_crop(self,
        target_h:int,
        target_w:int,
        original_h:int,
        original_w:int,
    )->list:
        tf = []
        tf += self._get_pad(original_h, original_w)
        tf += self._get_crop(target_h, target_w)
        return tf

    def _get_pad_resize_crop(self,
        target_h:int,
        target_w:int,
        original_h:int,
        original_w:int,
    )->list:
        tf = []
        tf += self._get_pad(original_h, original_w)
        tf += self._get_resize(*self._slightly_smaller(
            target_h, target_w, 
            original_h, original_w)
        )
        tf += self._get_crop(target_h, target_w)
        return tf

    def _get_pad_crop_resize(self,
        target_h:int,
        target_w:int,
        original_h:int,
        original_w:int,
    )->list:
        tf = []
        tf += self._get_pad(original_h, original_w)
        tf += self._get_crop(*self._slightly_smaller(
            target_h, target_w, 
            original_h, original_w)
        )
        tf += self._get_resize(target_h, target_w)
        return tf

    def augmentation_method(self,
        dataset_w=None, 
        dataset_h=None,
        final_return_w=None,
        final_return_h=None,
        ):
        kwargs = {'target_h':final_return_h,
                  'target_w':final_return_w,
                  'original_h':dataset_h,
                  'original_w':dataset_w}

        print(self._get_resize_crop(**kwargs))
        print(self._get_crop_resize(**kwargs))
        print(self._get_pad_crop_resize(**kwargs))
        print(self._get_pad_resize_crop(**kwargs))
        tf = A.OneOf([
                 #A.Compose(self._get_resize_crop(**kwargs), p=1.0), # <-- this line makes error either.
                 A.Compose(self._get_crop_resize(**kwargs), p=1.0),
                 A.Compose(self._get_pad_crop_resize(**kwargs), p=1.0),
                 A.Compose(self._get_pad_resize_crop(**kwargs), p=1.0),
                ], p=1.0)
        return A.Compose(tf, p=1.0)
  1. new instance
aug = Augmentation(DATASET_WIDTH, 
                   DATASET_HEIGHT,
                   DATASET_TRAINING_TARGET_W,
                   DATASET_TRAINING_TARGET_H)    
aug_fn_for_train = aug.get_train_augmentation()
  1. run pipeline
image_train_debug, mask_train_debug = aug_fn_for_train(image, mask)

Expected behavior

Doing augmentation from randomly selected one of the composed pipeline.

tf = A.OneOf([
         A.Compose(self._get_resize_crop(**kwargs), p=1.0), # 25%
         A.Compose(self._get_crop_resize(**kwargs), p=1.0), # 25%
         A.Compose(self._get_pad_crop_resize(**kwargs), p=1.0), # 25%
         A.Compose(self._get_pad_resize_crop(**kwargs), p=1.0), # 25%
        ], p=1.0)

Environment

  • Albumentations version (e.g., 0.1.8): 0.1.12
  • Python version (e.g., 3.7): python3.8
  • OS (e.g., Linux): Google COLAB COLAB
  • How you installed albumentations (conda, pip, source): colab default installed
  • Any other relevant information:

Additional context

image

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Dipetcommented, Nov 4, 2021

Yes, I am working on this problem.

1reaction
Dipetcommented, Nov 3, 2021

I think problem in augmentation_method. Change A.Compose(tf, p=1.0) to A.Compose([tf], p=1.0)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unit 5 Lab 1: Search Algorithms and Efficiency, Page 8
This section covers two computational models: In sequential computing, operations are performed in order one at a time. In parallel computing, the program...
Read more >
6. SEQUENTIAL AND CONCURRENT STATEMENTS IN THE ...
SEQUENTIAL AND CONCURRENT STATEMENTS IN THE. VHDL LANGUAGE. A VHDL description has two domains: a sequential domain and a concurrent domain. The sequential....
Read more >
1.13. Loops and Sequences — Hands-on Python Tutorial for ...
In this situation, the variable i is not used inside the body of the for-loop. The user could choose the number of times...
Read more >
Sequence Diagram Tutorial - Complete Guide with Examples
This sequence diagram tutorial is to help you understand sequence diagrams better; to explain everything you need to know, from how to draw ......
Read more >
Resolve promises one after another (i.e. in sequence)?
Each function will then be executed sequentially, which then starts the promise inside. We can solve this a few ways, but my favorite...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found