code: def affine_transform(
      image,
      transform,
      interpolation="bilinear",
      fill_mode="constant",
      fill_value=0,
      data_format="channels_last",
  ):
      if interpolation not in AFFINE_TRANSFORM_INTERPOLATIONS.keys():
          raise ValueError(
              "Invalid value for argument `interpolation`. Expected of one "
              f"{set(AFFINE_TRANSFORM_INTERPOLATIONS.keys())}. Received: "
              f"interpolation={interpolation}"
          )
      if fill_mode not in AFFINE_TRANSFORM_FILL_MODES:
          raise ValueError(
              "Invalid value for argument `fill_mode`. Expected of one "
              f"{AFFINE_TRANSFORM_FILL_MODES}. Received: fill_mode={fill_mode}"
          )
  
      image = convert_to_tensor(image)
      transform = convert_to_tensor(transform)
  
      if image.ndim not in (3, 4):
          raise ValueError(
              "Invalid image rank: expected rank 3 (single image) "
              "or rank 4 (batch of images). Received input with shape: "
              f"image.shape={image.shape}"
          )
      if transform.ndim not in (1, 2):
          raise ValueError(
              "Invalid transform rank: expected rank 1 (single transform) "
              "or rank 2 (batch of transforms). Received input with shape: "
              f"transform.shape={transform.shape}"
          )
  
      # unbatched case
      need_squeeze = False
      if image.ndim == 3:
          image = image.unsqueeze(dim=0)
          need_squeeze = True
      if transform.ndim == 1:
          transform = transform.unsqueeze(dim=0)
  
      if data_format == "channels_first":
          image = image.permute((0, 2, 3, 1))
  
      batch_size = image.shape[0]
  
      # get indices
      meshgrid = torch.meshgrid(
          *[
              torch.arange(
                  size, dtype=transform.dtype, device=transform.device
              )
              for size in image.shape[1:]
          ],
          indexing="ij",
      )
      indices = torch.concatenate(
          [torch.unsqueeze(x, dim=-1) for x in meshgrid], dim=-1
      )
      indices = torch.tile(indices, (batch_size, 1, 1, 1, 1))
  
      # swap the values
      a0 = transform[:, 0].clone()
      a2 = transform[:, 2].clone()
      b1 = transform[:, 4].clone()
      b2 = transform[:, 5].clone()
      transform[:, 0] = b1
      transform[:, 2] = b2
      transform[:, 4] = a0
      transform[:, 5] = a2
  
      # deal with transform
      transform = torch.nn.functional.pad(
          transform, pad=[0, 1, 0, 0], mode="constant", value=1
      )
      transform = torch.reshape(transform, (batch_size, 3, 3))
      offset = transform[:, 0:2, 2].clone()
      offset = torch.nn.functional.pad(offset, pad=[0, 1, 0, 0])
      transform[:, 0:2, 2] = 0
  
      # transform the indices
      coordinates = torch.einsum(
          "Bhwij, Bjk -> Bhwik", indices, transform
      )
      coordinates = torch.moveaxis(
          coordinates, source=-1, destination=1
      )
      coordinates += torch.reshape(
          a=offset, shape=(*offset.shape, 1, 1, 1)
      )
  
      # Note: torch.stack is faster than torch.vmap when the batch size is small.
      affined = torch.stack(
          [
              map_coordinates(
                  image[i],
                  coordinates[i],
                  order=AFFINE_TRANSFORM_INTERPOLATIONS[interpolation],
                  fill_mode=fill_mode,
                  fill_value=fill_value,
              )
              for i in range(len(image))
          ],
      )
  
      if data_format == "channels_first":
          affined = affined.permute((0, 3, 1, 2))
      if need_squeeze:
          affined = affined.squeeze(dim=0)
      return affined
  
file_path: keras/keras/backend/torch/image.py
imports: import functools
  import itertools
  import operator
  import torch
  from keras.backend.torch.core import convert_to_tensor
label_desc: Use image node_id 2 for calling a global function with example usage: affine_transform(image, transform, interpolation, fill_mode, fill_value, data_format) and returns: affined