Matching Augmentation with Tensorflow

I noticed that Tensorflow’s random_brightness and random_contrast function calculation is different from PyTorch. While tensorflow adds the delta value to the pixels, PyTorch multiplies the value.

I am trying to replicate a paper that has provided the code in Tensorflow. How do I replicate the transformation for random brightness and contrast based on the code provided in tensorflow?

reshaped_image = tf.image.random_brightness(reshaped_image,
                                               max_delta=63)
  # Randomly changing contrast of the image
  reshaped_image = tf.image.random_contrast(reshaped_image,
                                             lower=0.2, upper=1.8)

torchvision.transforms uses either PIL as the backend for PIL.Images or the equivalent tensor manipulations (which should yield the same results as PIL).
Could you explain which delta is wrongly multiplied in which function?

Hello Peter,
Thank you for your reply. The function is not wrongly calculated but just different. Please check this adjust_brightness function in Tensorflow where the value ‘delta’ is added to all the pixels of the image.
Tensorflow Adjust_brightness

In PyTorch, brightness in colorJitter is calculated as a factor value. So a delta value of 52 in tensorflow for random_brightness would make the image completely white in PyTorch.

The main reason I ask this question is how do I replicate a paper’s augmentation that has source code in Tensorflow?

Thank you,
Ayush

@ptrblck, Also, the tensorflow method for per_image_normalization. How do we achieve that in PyTorch?

If TF uses an absolute value for the brightness and PyTorch/PIL a relative one, you could try to map the TF value by dividing it with 255.

However, I’m a bit confused by the TF description, which claims:

The value delta is added to all components of the tensor image. image is
converted to float and scaled appropriately if it is in fixed-point
representation, and delta is converted to the same data type. For regular
images, delta should be in the range [0,1), as it is added to the image in
floating point representation, where pixel values are in the [0,1) range.

Also the example uses a delta value of 0.1, so I’m unsure where the 52 comes from.

This was a bit confusing to us as well. We were using the random_brightness function in TF and the closest thing to that was the ColorJitter in PyTorch. But it seems like they just derive a random uniform distribution from the max_delta value that you provide and generate a sample delta value. This value is then added to each pixel of the image. Here is the implementation that my teammate created that we use as a lambda function in our transforms.

def random_brightness(image, max_delta):
    """
    This function creates a custom random brightness
    transform which is used for data augmentation.
    params:
        - image (torch Tensor): Image Tensor that needs to be standardized.
        - max_delta (int) : Number used to generate random brightness
    
    returns:
        - adjusted_image (torch Tensor): Image Tensor post standardization.
    """

    # check if max delta is greater than 0
    if max_delta < 0:
        raise ValueError('Max Delta should be non-negative!')

    # Generates uniformly distributed random samples from the half-open interval [low, high)
    delta = Uniform(-max_delta, max_delta).sample()

    # Add the delta to each pixel of the image
    adjusted_image = torch.add(image, delta)

    return adjusted_image