code: def _transform_affine(theta, input, downsample_factor, border_mode):
      num_batch, num_channels, height, width = input.shape
      theta = T.reshape(theta, (-1, 2, 3))
  
      # grid of (x_t, y_t, 1), eq (1) in ref [1]
      out_height = T.cast(height // downsample_factor[0], "int64")
      out_width = T.cast(width // downsample_factor[1], "int64")
      grid = _meshgrid(out_height, out_width)
  
      # Transform A x (x_t, y_t, 1)^T -> (x_s, y_s)
      T_g = T.dot(theta, grid)
      x_s = T_g[:, 0]
      y_s = T_g[:, 1]
      x_s_flat = x_s.flatten()
      y_s_flat = y_s.flatten()
  
      # dimshuffle input to  (bs, height, width, channels)
      input_dim = input.dimshuffle(0, 2, 3, 1)
      input_transformed = _interpolate(
          input_dim,
          x_s_flat,
          y_s_flat,
          out_height,
          out_width,
          border_mode,
      )
  
      output = T.reshape(
          input_transformed,
          (num_batch, out_height, out_width, num_channels),
      )
      output = output.dimshuffle(
          0, 3, 1, 2
      )  # dimshuffle to conv format
      return output
  
imports: import theano
  import theano.tensor
  import numpy
  from ..None import init
  from ..None import nonlinearities
  from ..utils import as_tuple, floatX, int_types
  from ..random import get_rng
  from .base import Layer, MergeLayer
  from theano.sandbox.rng_mrg import MRG_RandomStreams
label_desc: Use image node_id 2 for calling a global function with example usage: _transform_affine(theta, input, downsample_factor, border_mode) and returns: output