code: def logistic_dpsgd(
      train_dataset: datasets.RegressionDataset,
      test_dataset: datasets.RegressionDataset,
      epsilon: float,
      delta: float,
      epochs: int,
      num_classes: int,
      batch_size: int,
      num_microbatches: int,
      clipping_norm: float,
  ) -> List[float]:
      """Trains and validates private logistic regression model via DP-SGD.
  
        The training is based on the differentially private stochasstic gradient
        descent algorithm implemented in TensorFlow Privacy.
  
      Args:
        train_dataset: consists of num_train many labeled examples, where the labels
          are in {0,1,...,num_classes-1}.
        test_dataset: consists of num_test many labeled examples, where the labels
          are in {0,1,...,num_classes-1}.
        epsilon: epsilon parameter in (epsilon, delta)-DP.
        delta: delta parameter in (epsilon, delta)-DP.
        epochs: number of training epochs.
        num_classes: number of classes.
        batch_size: the number of examples in each batch of gradient descent.
        num_microbatches: the number of microbatches in gradient descent.
        clipping_norm: the gradients will be normalized by DPKerasAdamOptimizer to
          have l2-norm at most clipping_norm.
  
      Returns:
        List of test accuracies (one for each epoch) on test_dataset of model
        trained on train_dataset.
      """
      num_train = train_dataset.points.shape[0]
      remainder = num_train % batch_size
      if remainder != 0:
          train_dataset.points = train_dataset.points[:-remainder, :]
          train_dataset.labels = train_dataset.labels[:-remainder]
          num_train -= remainder
      noise_multiplier = compute_dpsgd_noise_multiplier(
          num_train, epsilon, delta, epochs, batch_size
      )
      optimizer = dp_optimizer_keras.DPKerasAdamOptimizer(
          l2_norm_clip=clipping_norm,
          noise_multiplier=noise_multiplier,
          num_microbatches=num_microbatches,
      )
      loss = tf.keras.losses.CategoricalCrossentropy(
          reduction=tf.losses.Reduction.NONE
      )
      return single_layer_softmax.single_layer_softmax_classifier(
          train_dataset,
          test_dataset,
          epochs,
          num_classes,
          optimizer,
          loss,
          batch_size,
      )
  
file_path: privacy/tensorflow_privacy/privacy/logistic_regression/multinomial_logistic.py
imports: import math
  from typing import List, Optional, Tuple
  import dp_accounting
  import numpy
  import tensorflow
  from tensorflow_privacy.privacy.logistic_regression import datasets
  from tensorflow_privacy.privacy.logistic_regression import single_layer_softmax
  from tensorflow_privacy.privacy.optimizers import dp_optimizer_keras
label_desc: Use image node_id 3 for calling a global function with example usage: logistic_dpsgd(train_dataset, test_dataset, epsilon, delta, epochs, num_classes, batch_size, num_microbatches, clipping_norm) and returns: single_layer_softmax