From eaf9fbf9692e85281f11a9d9087b47e82513ca62 Mon Sep 17 00:00:00 2001 From: Steve Chien Date: Fri, 4 Jun 2021 11:30:58 -0700 Subject: [PATCH] Changes for API docstrings for TF.org: (1) Hide documentation for superclass methods in DPModel. (2) Make compute_dp_sgd_privacy visible. PiperOrigin-RevId: 377553548 --- g3doc/build_docs.py | 28 +++++++++++++++++++ tensorflow_privacy/__init__.py | 1 + .../analysis/compute_dp_sgd_privacy_lib.py | 13 ++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/g3doc/build_docs.py b/g3doc/build_docs.py index 168a68e..7cc25a7 100644 --- a/g3doc/build_docs.py +++ b/g3doc/build_docs.py @@ -19,6 +19,9 @@ import os from absl import app from absl import flags +import tensorflow as tf + +from tensorflow_docs.api_generator import doc_controls from tensorflow_docs.api_generator import generate_lib from tensorflow_docs.api_generator import public_api @@ -44,10 +47,35 @@ PROJECT_SHORT_NAME = 'tf_privacy' PROJECT_FULL_NAME = 'TensorFlow Privacy' +def _hide_layer_and_module_methods(): + """Hide methods and properties defined in the base classes of keras layers.""" + # __dict__ only sees attributes defined in *this* class, not on parent classes + # Needed to ignore redudant subclass documentation + model_contents = list(tf.keras.Model.__dict__.items()) + layer_contents = list(tf.keras.layers.Layer.__dict__.items()) + module_contents = list(tf.Module.__dict__.items()) + + for name, obj in model_contents + layer_contents + module_contents: + if name == '__init__': + continue + + if isinstance(obj, property): + obj = obj.fget + + if isinstance(obj, (staticmethod, classmethod)): + obj = obj.__func__ + + try: + doc_controls.do_not_doc_in_subclasses(obj) + except AttributeError: + pass + + def gen_api_docs(): """Generates api docs for the tensorflow docs package.""" output_dir = FLAGS.output_dir + _hide_layer_and_module_methods() doc_generator = generate_lib.DocGenerator( root_title=PROJECT_FULL_NAME, py_modules=[(PROJECT_SHORT_NAME, tf_privacy)], diff --git a/tensorflow_privacy/__init__.py b/tensorflow_privacy/__init__.py index 1ef5d2d..e69ec2a 100644 --- a/tensorflow_privacy/__init__.py +++ b/tensorflow_privacy/__init__.py @@ -27,6 +27,7 @@ if hasattr(sys, 'skip_tf_privacy_import'): # Useful for standalone scripts. pass else: # Analysis + from tensorflow_privacy.privacy.analysis.compute_dp_sgd_privacy_lib import compute_dp_sgd_privacy from tensorflow_privacy.privacy.analysis.privacy_ledger import GaussianSumQueryEntry from tensorflow_privacy.privacy.analysis.privacy_ledger import PrivacyLedger from tensorflow_privacy.privacy.analysis.privacy_ledger import QueryWithLedger diff --git a/tensorflow_privacy/privacy/analysis/compute_dp_sgd_privacy_lib.py b/tensorflow_privacy/privacy/analysis/compute_dp_sgd_privacy_lib.py index c8c9821..a69d7db 100644 --- a/tensorflow_privacy/privacy/analysis/compute_dp_sgd_privacy_lib.py +++ b/tensorflow_privacy/privacy/analysis/compute_dp_sgd_privacy_lib.py @@ -55,7 +55,18 @@ def apply_dp_sgd_analysis(q, sigma, steps, orders, delta): def compute_dp_sgd_privacy(n, batch_size, noise_multiplier, epochs, delta): - """Compute epsilon based on the given hyperparameters.""" + """Compute epsilon based on the given hyperparameters. + + Args: + n: Number of examples in the training data. + batch_size: Batch size used in training. + noise_multiplier: Noise multiplier used in training. + epochs: Number of epochs in training. + delta: Value of delta for which to compute epsilon. + + Returns: + Value of epsilon corresponding to input hyperparameters. + """ q = batch_size / n # q - the sampling ratio. if q > 1: raise app.UsageError('n must be larger than the batch size.')