code: def _py_func_with_grads(
      func, inp, Tout, stateful=True, name=None, grad=None
  ):
      """
      To get this to work with automatic differentiation
      we use a hack attributed to Sergey Ioffe
      mentioned here: http://stackoverflow.com/questions/36456436
  
      Define custom _py_func_with_grads which takes also a grad op as argument:
      from https://gist.github.com/harpone/3453185b41d8d985356cbe5e57d67342
  
      :param func:
      :param inp:
      :param Tout:
      :param stateful:
      :param name:
      :param grad:
      :return:
      """
      # Need to generate a unique name to avoid duplicates:
      import uuid
  
      rnd_name = "PyFuncGrad" + str(uuid.uuid4())
      # tf.logging.info('CRFasRNN layer iteration {}'.format(rnd_name))
      tf.RegisterGradient(rnd_name)(
          grad
      )  # see _MySquareGrad for grad example
      with tf.get_default_graph().gradient_override_map(
          {"PyFunc": rnd_name}
      ):
          return tf.py_func(
              func, inp, Tout, stateful=stateful, name=name
          )[0]
  
file_path: NiftyNet/niftynet/layer/crf.py
imports: from __future__ import absolute_import, print_function
  import numpy
  import tensorflow
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.layer_util import infer_spatial_rank, expand_spatial_params
label_desc: Use image node_id 4 for calling a global function with example usage: _py_func_with_grads(func, inp, Tout, stateful, name, grad) and returns: tf