I got this solved in the end by upgrading tensorflow-privacy to version 0.9.0 and reworking the calculate_epsilon function as shown here. This was based on the updated code in
def compute_epsilon(
epochs: int, num_train_examples: int, batch_size: int, noise_multiplier: float
) -> float:
"""Computes epsilon value for given hyperparameters.
Based on
github.com/tensorflow/privacy/blob/master/tutorials/mnist_dpsgd_tutorial_keras.py
"""
if noise_multiplier == 0.0:
return float("inf")
steps = epochs * num_train_examples // batch_size
orders = [1 + x / 10.0 for x in range(1, 100)] + list(range(12, 64))
accountant = dp_accounting.rdp.RdpAccountant(orders)
sampling_probability = batch_size / num_train_examples
event = dp_accounting.SelfComposedDpEvent(
dp_accounting.PoissonSampledDpEvent(
sampling_probability, dp_accounting.GaussianDpEvent(noise_multiplier)
),
steps,
)
accountant.compose(event)
# Delta is set to approximate 1 / (number of training points).
return accountant.get_epsilon(target_delta=1e-4)