code: def cnn_model_fn(
      features, labels, mode, params
  ):  # pylint: disable=unused-argument
      """Model function for a CNN."""
  
      # Define CNN architecture.
      logits = common.get_cnn_model(features)
  
      # Calculate loss as a vector (to support microbatches in DP-SGD).
      vector_loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
          labels=labels, logits=logits
      )
      # Define mean of loss across minibatch (for reporting through tf.Estimator).
      scalar_loss = tf.reduce_mean(input_tensor=vector_loss)
  
      # Configure the training op (for TRAIN mode).
      if mode == tf_estimator.ModeKeys.TRAIN:
          if FLAGS.dpsgd:
              # Use DP version of GradientDescentOptimizer. Other optimizers are
              # available in dp_optimizer. Most optimizers inheriting from
              # tf.compat.v1.train.Optimizer should be wrappable in differentially
              # private counterparts by calling dp_optimizer.optimizer_from_args().
              optimizer = (
                  dp_optimizer.DPGradientDescentGaussianOptimizer(
                      l2_norm_clip=FLAGS.l2_norm_clip,
                      noise_multiplier=FLAGS.noise_multiplier,
                      num_microbatches=FLAGS.microbatches,
                      learning_rate=FLAGS.learning_rate,
                  )
              )
              opt_loss = vector_loss
          else:
              optimizer = tf.compat.v1.train.GradientDescentOptimizer(
                  learning_rate=FLAGS.learning_rate
              )
              opt_loss = scalar_loss
  
          global_step = tf.compat.v1.train.get_global_step()
          train_op = optimizer.minimize(
              loss=opt_loss, global_step=global_step
          )
  
          # In the following, we pass the mean of the loss (scalar_loss) rather than
          # the vector_loss because tf.estimator requires a scalar loss. This is only
          # used for evaluation and debugging by tf.estimator. The actual loss being
          # minimized is opt_loss defined above and passed to optimizer.minimize().
          return tf_estimator.EstimatorSpec(
              mode=mode, loss=scalar_loss, train_op=train_op
          )
  
      # Add evaluation metrics (for EVAL mode).
      elif mode == tf_estimator.ModeKeys.EVAL:
          eval_metric_ops = {
              "accuracy": tf.compat.v1.metrics.accuracy(
                  labels=labels,
                  predictions=tf.argmax(input=logits, axis=1),
              )
          }
          return tf_estimator.EstimatorSpec(
              mode=mode,
              loss=scalar_loss,
              eval_metric_ops=eval_metric_ops,
          )
  
file_path: privacy/tutorials/mnist_dpsgd_tutorial.py
imports: import time
  from absl import app
  from absl import flags
  from absl import logging
  import tensorflow
  from tensorflow import estimator
  from tensorflow_privacy.privacy.analysis import compute_dp_sgd_privacy_lib
  from tensorflow_privacy.privacy.optimizers import dp_optimizer
  import mnist_dpsgd_tutorial_common
label_desc: Use image node_id 1 for calling a global function with example usage: cnn_model_fn(features, labels, mode, params) and returns: tf_estimator, tf_estimator