From 51d894e6bdc88952c325d14f09d1275a4c863612 Mon Sep 17 00:00:00 2001 From: Zinan Lin Date: Thu, 21 Nov 2024 22:58:03 -0800 Subject: [PATCH] release: private evolution for images --- .github/workflows/sphinx.yml | 28 ++ .gitignore | 168 ++++++++ .pre-commit-config.yaml | 6 + CODE_OF_CONDUCT.md | 9 + LICENSE | 21 + README.md | 43 ++ SECURITY.md | 41 ++ SUPPORT.md | 13 + doc/.gitkeep | 0 doc/Makefile | 20 + doc/build_autodoc.sh | 2 + doc/build_doc.sh | 1 + doc/make.bat | 35 ++ doc/requirements.txt | 1 + doc/serve_doc.sh | 1 + doc/source/api/api.rst | 10 + doc/source/api/modules.rst | 7 + .../pe.api.image.improved_diffusion_lib.rst | 26 ++ doc/source/api/pe.api.image.rst | 34 ++ doc/source/api/pe.api.rst | 34 ++ doc/source/api/pe.callback.common.rst | 26 ++ doc/source/api/pe.callback.image.rst | 26 ++ doc/source/api/pe.callback.rst | 27 ++ doc/source/api/pe.constant.rst | 18 + doc/source/api/pe.data.image.rst | 42 ++ doc/source/api/pe.data.rst | 26 ++ doc/source/api/pe.dp.rst | 26 ++ doc/source/api/pe.embedding.image.rst | 18 + doc/source/api/pe.embedding.rst | 26 ++ .../pe.histogram.nearest_neighbor_backend.rst | 26 ++ doc/source/api/pe.histogram.rst | 34 ++ doc/source/api/pe.logger.rst | 50 +++ doc/source/api/pe.logging.rst | 7 + doc/source/api/pe.metric_item.rst | 7 + doc/source/api/pe.population.rst | 26 ++ doc/source/api/pe.rst | 27 ++ doc/source/api/pe.runner.rst | 18 + doc/source/api/pe.util.rst | 18 + doc/source/conf.py | 56 +++ doc/source/getting_started/details/api.rst | 32 ++ .../details/callback_and_logger.rst | 36 ++ doc/source/getting_started/details/data.rst | 49 +++ .../getting_started/details/details.rst | 16 + doc/source/getting_started/details/dp.rst | 16 + .../getting_started/details/embedding.rst | 22 + .../getting_started/details/histogram.rst | 15 + .../getting_started/details/overview.rst | 59 +++ .../getting_started/details/population.rst | 15 + doc/source/getting_started/details/runner.rst | 8 + .../getting_started/details/workflow.jpg | Bin 0 -> 512289 bytes doc/source/getting_started/examples.rst | 30 ++ .../getting_started/getting_started.rst | 13 + doc/source/getting_started/installation.rst | 40 ++ doc/source/getting_started/intro.rst | 40 ++ doc/source/getting_started/pe1.bib | 6 + doc/source/getting_started/pe2.bib | 6 + doc/source/index.rst | 18 + example/image/camelyon17.py | 64 +++ example/image/cat.py | 66 +++ example/image/cifar10.py | 64 +++ pe/__init__.py | 1 + pe/api/__init__.py | 1 + pe/api/api.py | 25 ++ pe/api/image/__init__.py | 3 + pe/api/image/improved_diffusion_api.py | 379 ++++++++++++++++++ .../image/improved_diffusion_lib/__init__.py | 0 .../gaussian_diffusion.py | 309 ++++++++++++++ pe/api/image/improved_diffusion_lib/unet.py | 60 +++ pe/api/image/stable_diffusion_api.py | 206 ++++++++++ pe/api/util.py | 6 + pe/callback/__init__.py | 4 + pe/callback/callback.py | 16 + pe/callback/common/__init__.py | 0 pe/callback/common/compute_fid.py | 52 +++ pe/callback/common/save_checkpoints.py | 46 +++ pe/callback/image/__init__.py | 0 pe/callback/image/sample_images.py | 44 ++ pe/callback/image/save_all_images.py | 70 ++++ pe/constant/__init__.py | 0 pe/constant/data.py | 29 ++ pe/data/__init__.py | 1 + pe/data/data.py | 139 +++++++ pe/data/image/__init__.py | 4 + pe/data/image/camelyon17.py | 50 +++ pe/data/image/cat.py | 73 ++++ pe/data/image/cifar10.py | 45 +++ pe/data/image/image.py | 125 ++++++ pe/dp/__init__.py | 2 + pe/dp/dp.py | 29 ++ pe/dp/gaussian.py | 172 ++++++++ pe/embedding/__init__.py | 1 + pe/embedding/embedding.py | 21 + pe/embedding/image/__init__.py | 1 + pe/embedding/image/inception.py | 79 ++++ pe/histogram/__init__.py | 2 + pe/histogram/histogram.py | 18 + .../nearest_neighbor_backend/__init__.py | 0 .../nearest_neighbor_backend/faiss.py | 40 ++ .../nearest_neighbor_backend/sklearn.py | 30 ++ pe/histogram/nearest_neighbors.py | 199 +++++++++ pe/logger/__init__.py | 4 + pe/logger/csv_print.py | 109 +++++ pe/logger/image_file.py | 107 +++++ pe/logger/log_print.py | 38 ++ pe/logger/logger.py | 20 + pe/logger/matplotlib_pdf.py | 65 +++ pe/logging/__init__.py | 43 ++ pe/metric_item/__init__.py | 100 +++++ pe/population/__init__.py | 2 + pe/population/pe_population.py | 145 +++++++ pe/population/population.py | 27 ++ pe/runner/__init__.py | 1 + pe/runner/pe.py | 222 ++++++++++ pe/util/__init__.py | 1 + pe/util/download.py | 21 + pyproject.toml | 43 ++ 116 files changed, 4849 insertions(+) create mode 100644 .github/workflows/sphinx.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 SUPPORT.md create mode 100644 doc/.gitkeep create mode 100644 doc/Makefile create mode 100644 doc/build_autodoc.sh create mode 100644 doc/build_doc.sh create mode 100644 doc/make.bat create mode 100644 doc/requirements.txt create mode 100644 doc/serve_doc.sh create mode 100644 doc/source/api/api.rst create mode 100644 doc/source/api/modules.rst create mode 100644 doc/source/api/pe.api.image.improved_diffusion_lib.rst create mode 100644 doc/source/api/pe.api.image.rst create mode 100644 doc/source/api/pe.api.rst create mode 100644 doc/source/api/pe.callback.common.rst create mode 100644 doc/source/api/pe.callback.image.rst create mode 100644 doc/source/api/pe.callback.rst create mode 100644 doc/source/api/pe.constant.rst create mode 100644 doc/source/api/pe.data.image.rst create mode 100644 doc/source/api/pe.data.rst create mode 100644 doc/source/api/pe.dp.rst create mode 100644 doc/source/api/pe.embedding.image.rst create mode 100644 doc/source/api/pe.embedding.rst create mode 100644 doc/source/api/pe.histogram.nearest_neighbor_backend.rst create mode 100644 doc/source/api/pe.histogram.rst create mode 100644 doc/source/api/pe.logger.rst create mode 100644 doc/source/api/pe.logging.rst create mode 100644 doc/source/api/pe.metric_item.rst create mode 100644 doc/source/api/pe.population.rst create mode 100644 doc/source/api/pe.rst create mode 100644 doc/source/api/pe.runner.rst create mode 100644 doc/source/api/pe.util.rst create mode 100644 doc/source/conf.py create mode 100644 doc/source/getting_started/details/api.rst create mode 100644 doc/source/getting_started/details/callback_and_logger.rst create mode 100644 doc/source/getting_started/details/data.rst create mode 100644 doc/source/getting_started/details/details.rst create mode 100644 doc/source/getting_started/details/dp.rst create mode 100644 doc/source/getting_started/details/embedding.rst create mode 100644 doc/source/getting_started/details/histogram.rst create mode 100644 doc/source/getting_started/details/overview.rst create mode 100644 doc/source/getting_started/details/population.rst create mode 100644 doc/source/getting_started/details/runner.rst create mode 100644 doc/source/getting_started/details/workflow.jpg create mode 100644 doc/source/getting_started/examples.rst create mode 100644 doc/source/getting_started/getting_started.rst create mode 100644 doc/source/getting_started/installation.rst create mode 100644 doc/source/getting_started/intro.rst create mode 100644 doc/source/getting_started/pe1.bib create mode 100644 doc/source/getting_started/pe2.bib create mode 100644 doc/source/index.rst create mode 100644 example/image/camelyon17.py create mode 100644 example/image/cat.py create mode 100644 example/image/cifar10.py create mode 100644 pe/__init__.py create mode 100644 pe/api/__init__.py create mode 100644 pe/api/api.py create mode 100644 pe/api/image/__init__.py create mode 100644 pe/api/image/improved_diffusion_api.py create mode 100644 pe/api/image/improved_diffusion_lib/__init__.py create mode 100644 pe/api/image/improved_diffusion_lib/gaussian_diffusion.py create mode 100644 pe/api/image/improved_diffusion_lib/unet.py create mode 100644 pe/api/image/stable_diffusion_api.py create mode 100644 pe/api/util.py create mode 100644 pe/callback/__init__.py create mode 100644 pe/callback/callback.py create mode 100644 pe/callback/common/__init__.py create mode 100644 pe/callback/common/compute_fid.py create mode 100644 pe/callback/common/save_checkpoints.py create mode 100644 pe/callback/image/__init__.py create mode 100644 pe/callback/image/sample_images.py create mode 100644 pe/callback/image/save_all_images.py create mode 100644 pe/constant/__init__.py create mode 100644 pe/constant/data.py create mode 100644 pe/data/__init__.py create mode 100644 pe/data/data.py create mode 100644 pe/data/image/__init__.py create mode 100644 pe/data/image/camelyon17.py create mode 100644 pe/data/image/cat.py create mode 100644 pe/data/image/cifar10.py create mode 100644 pe/data/image/image.py create mode 100644 pe/dp/__init__.py create mode 100644 pe/dp/dp.py create mode 100644 pe/dp/gaussian.py create mode 100644 pe/embedding/__init__.py create mode 100644 pe/embedding/embedding.py create mode 100644 pe/embedding/image/__init__.py create mode 100644 pe/embedding/image/inception.py create mode 100644 pe/histogram/__init__.py create mode 100644 pe/histogram/histogram.py create mode 100644 pe/histogram/nearest_neighbor_backend/__init__.py create mode 100644 pe/histogram/nearest_neighbor_backend/faiss.py create mode 100644 pe/histogram/nearest_neighbor_backend/sklearn.py create mode 100644 pe/histogram/nearest_neighbors.py create mode 100644 pe/logger/__init__.py create mode 100644 pe/logger/csv_print.py create mode 100644 pe/logger/image_file.py create mode 100644 pe/logger/log_print.py create mode 100644 pe/logger/logger.py create mode 100644 pe/logger/matplotlib_pdf.py create mode 100644 pe/logging/__init__.py create mode 100644 pe/metric_item/__init__.py create mode 100644 pe/population/__init__.py create mode 100644 pe/population/pe_population.py create mode 100644 pe/population/population.py create mode 100644 pe/runner/__init__.py create mode 100644 pe/runner/pe.py create mode 100644 pe/util/__init__.py create mode 100644 pe/util/download.py create mode 100644 pyproject.toml diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml new file mode 100644 index 0000000..ec071d6 --- /dev/null +++ b/.github/workflows/sphinx.yml @@ -0,0 +1,28 @@ +name: "Sphinx: Render docs" + +on: push + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Build HTML + uses: ammaraskar/sphinx-action@master + with: + docs-folder: "doc/" + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: html-docs + path: doc/build/html/ + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: github.ref == 'refs/heads/main' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: doc/build/html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb04a20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,168 @@ +# PE +results +amlt +_test +_data + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..31fe7d6 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: +- repo: https://github.com/psf/black + rev: 24.8.0 + hooks: + - id: black + args: [--line-length=119] \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f9ba8cf --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,9 @@ +# Microsoft Open Source Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). + +Resources: + +- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) +- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9e841e7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/README.md b/README.md new file mode 100644 index 0000000..3af5417 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Private Evolution: Differentially Private Synthetic Data via Foundation Model APIs + +This repo is a Python library to **generate differentially private (DP) synthetic data without the need of any ML model training**. It is based on the following papers that proposed a new DP synthetic data framework that only utilizes the blackbox inference APIs of foundation models (e.g., Stable Diffusion, GPT models). + +* Differentially Private Synthetic Data via Foundation Model APIs 1: Images + [[paper (ICLR 2024)]](https://openreview.net/forum?id=YEhQs8POIo) [[paper (arxiv)](https://arxiv.org/abs/2305.15560)] + **Authors:** [[Zinan Lin](https://zinanlin.me/)], [[Sivakanth Gopi](https://www.microsoft.com/en-us/research/people/sigopi/)], [[Janardhan Kulkarni](https://www.microsoft.com/en-us/research/people/jakul/)], [[Harsha Nori](https://www.microsoft.com/en-us/research/people/hanori/)], [[Sergey Yekhanin](http://www.yekhanin.org/)] + + +## Documentation +Please refer to the [documentation](https://microsoft.github.io/DPSDA/) for more details, including the installation instructions, usage, and examples. + +## Attention + +The code that was published along with the [paper](https://arxiv.org/abs/2305.15560) has been moved to the [deprecated](https://github.com/microsoft/DPSDA/tree/deprecated) branch on 11/21/2024, which is no longer maintained. The code in the current main branch is a refactored version of the original codebase, which is more modularized and easier to use, with support of more advanced Private Evolution algorithms and APIs. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. + +## Responsible Uses + +This project uses foundation model APIs to create [synthetic data](https://en.wikipedia.org/wiki/Synthetic_data) with [differential privacy](https://en.wikipedia.org/wiki/Differential_privacy) guarantees. Differential privacy (DP) is a formal framework that ensures the output of an algorithm does not reveal too much information about its inputs. Without a formal privacy guarantee, a synthetic data generation algorithm may inadvertently reveal sensitive information about its input datapoints. + +Using synthetic data in downstream applications can carry risk. Synthetic data may not always reflect the true data distribution, and can cause harms in downstream applications. Both the dataset and algorithms behind the foundation model APIs may contain various types of bias, leading to potential allocation, representation, and quality-of-service harms. Additionally, privacy violations can still occur if the ε and δ privacy parameters are set inappropriately, or if multiple copies of a sample exist in the seed dataset. It is important to consider these factors carefully before any potential deployments. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..e138ec5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..1be2295 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,13 @@ +# Support + +## How to file issues and get help + +This project uses GitHub Issues to track bugs and feature requests. Please search the existing +issues before filing new issues to avoid duplicates. For new issues, file your bug or +feature request as a new Issue. + +For help and questions about using this project, please contact zinanlin AT microsoft.com. + +## Microsoft Support Policy + +Support for this project is limited to the resources listed above. diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/build_autodoc.sh b/doc/build_autodoc.sh new file mode 100644 index 0000000..d20cf2f --- /dev/null +++ b/doc/build_autodoc.sh @@ -0,0 +1,2 @@ +sphinx-apidoc -f --module-first -d 3 -o source/api ../pe +make clean html \ No newline at end of file diff --git a/doc/build_doc.sh b/doc/build_doc.sh new file mode 100644 index 0000000..ac9f8ab --- /dev/null +++ b/doc/build_doc.sh @@ -0,0 +1 @@ +make html \ No newline at end of file diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 0000000..747ffb7 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 0000000..5614a3c --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1 @@ +sphinx_rtd_theme==3.0.2 \ No newline at end of file diff --git a/doc/serve_doc.sh b/doc/serve_doc.sh new file mode 100644 index 0000000..b6acc2c --- /dev/null +++ b/doc/serve_doc.sh @@ -0,0 +1 @@ +python3 -m http.server 8000 --directory build/html diff --git a/doc/source/api/api.rst b/doc/source/api/api.rst new file mode 100644 index 0000000..fc98e25 --- /dev/null +++ b/doc/source/api/api.rst @@ -0,0 +1,10 @@ +API Reference +=============================== + + +.. toctree:: + :maxdepth: 3 + :caption: Contents: + + modules + diff --git a/doc/source/api/modules.rst b/doc/source/api/modules.rst new file mode 100644 index 0000000..a446077 --- /dev/null +++ b/doc/source/api/modules.rst @@ -0,0 +1,7 @@ +pe +== + +.. toctree:: + :maxdepth: 3 + + pe diff --git a/doc/source/api/pe.api.image.improved_diffusion_lib.rst b/doc/source/api/pe.api.image.improved_diffusion_lib.rst new file mode 100644 index 0000000..841044c --- /dev/null +++ b/doc/source/api/pe.api.image.improved_diffusion_lib.rst @@ -0,0 +1,26 @@ +pe.api.image.improved\_diffusion\_lib package +============================================= + +.. automodule:: pe.api.image.improved_diffusion_lib + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.api.image.improved\_diffusion\_lib.gaussian\_diffusion module +---------------------------------------------------------------- + +.. automodule:: pe.api.image.improved_diffusion_lib.gaussian_diffusion + :members: + :undoc-members: + :show-inheritance: + +pe.api.image.improved\_diffusion\_lib.unet module +------------------------------------------------- + +.. automodule:: pe.api.image.improved_diffusion_lib.unet + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.api.image.rst b/doc/source/api/pe.api.image.rst new file mode 100644 index 0000000..c53f742 --- /dev/null +++ b/doc/source/api/pe.api.image.rst @@ -0,0 +1,34 @@ +pe.api.image package +==================== + +.. automodule:: pe.api.image + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.api.image.improved_diffusion_lib + +Submodules +---------- + +pe.api.image.improved\_diffusion\_api module +-------------------------------------------- + +.. automodule:: pe.api.image.improved_diffusion_api + :members: + :undoc-members: + :show-inheritance: + +pe.api.image.stable\_diffusion\_api module +------------------------------------------ + +.. automodule:: pe.api.image.stable_diffusion_api + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.api.rst b/doc/source/api/pe.api.rst new file mode 100644 index 0000000..a2f2616 --- /dev/null +++ b/doc/source/api/pe.api.rst @@ -0,0 +1,34 @@ +pe.api package +============== + +.. automodule:: pe.api + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.api.image + +Submodules +---------- + +pe.api.api module +----------------- + +.. automodule:: pe.api.api + :members: + :undoc-members: + :show-inheritance: + +pe.api.util module +------------------ + +.. automodule:: pe.api.util + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.callback.common.rst b/doc/source/api/pe.callback.common.rst new file mode 100644 index 0000000..9c387d0 --- /dev/null +++ b/doc/source/api/pe.callback.common.rst @@ -0,0 +1,26 @@ +pe.callback.common package +========================== + +.. automodule:: pe.callback.common + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.callback.common.compute\_fid module +-------------------------------------- + +.. automodule:: pe.callback.common.compute_fid + :members: + :undoc-members: + :show-inheritance: + +pe.callback.common.save\_checkpoints module +------------------------------------------- + +.. automodule:: pe.callback.common.save_checkpoints + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.callback.image.rst b/doc/source/api/pe.callback.image.rst new file mode 100644 index 0000000..784912c --- /dev/null +++ b/doc/source/api/pe.callback.image.rst @@ -0,0 +1,26 @@ +pe.callback.image package +========================= + +.. automodule:: pe.callback.image + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.callback.image.sample\_images module +--------------------------------------- + +.. automodule:: pe.callback.image.sample_images + :members: + :undoc-members: + :show-inheritance: + +pe.callback.image.save\_all\_images module +------------------------------------------ + +.. automodule:: pe.callback.image.save_all_images + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.callback.rst b/doc/source/api/pe.callback.rst new file mode 100644 index 0000000..ae740bf --- /dev/null +++ b/doc/source/api/pe.callback.rst @@ -0,0 +1,27 @@ +pe.callback package +=================== + +.. automodule:: pe.callback + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.callback.common + pe.callback.image + +Submodules +---------- + +pe.callback.callback module +--------------------------- + +.. automodule:: pe.callback.callback + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.constant.rst b/doc/source/api/pe.constant.rst new file mode 100644 index 0000000..4f56470 --- /dev/null +++ b/doc/source/api/pe.constant.rst @@ -0,0 +1,18 @@ +pe.constant package +=================== + +.. automodule:: pe.constant + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.constant.data module +----------------------- + +.. automodule:: pe.constant.data + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.data.image.rst b/doc/source/api/pe.data.image.rst new file mode 100644 index 0000000..177b224 --- /dev/null +++ b/doc/source/api/pe.data.image.rst @@ -0,0 +1,42 @@ +pe.data.image package +===================== + +.. automodule:: pe.data.image + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.data.image.camelyon17 module +------------------------------- + +.. automodule:: pe.data.image.camelyon17 + :members: + :undoc-members: + :show-inheritance: + +pe.data.image.cat module +------------------------ + +.. automodule:: pe.data.image.cat + :members: + :undoc-members: + :show-inheritance: + +pe.data.image.cifar10 module +---------------------------- + +.. automodule:: pe.data.image.cifar10 + :members: + :undoc-members: + :show-inheritance: + +pe.data.image.image module +-------------------------- + +.. automodule:: pe.data.image.image + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.data.rst b/doc/source/api/pe.data.rst new file mode 100644 index 0000000..27d092f --- /dev/null +++ b/doc/source/api/pe.data.rst @@ -0,0 +1,26 @@ +pe.data package +=============== + +.. automodule:: pe.data + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.data.image + +Submodules +---------- + +pe.data.data module +------------------- + +.. automodule:: pe.data.data + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.dp.rst b/doc/source/api/pe.dp.rst new file mode 100644 index 0000000..6473b69 --- /dev/null +++ b/doc/source/api/pe.dp.rst @@ -0,0 +1,26 @@ +pe.dp package +============= + +.. automodule:: pe.dp + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.dp.dp module +--------------- + +.. automodule:: pe.dp.dp + :members: + :undoc-members: + :show-inheritance: + +pe.dp.gaussian module +--------------------- + +.. automodule:: pe.dp.gaussian + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.embedding.image.rst b/doc/source/api/pe.embedding.image.rst new file mode 100644 index 0000000..1777711 --- /dev/null +++ b/doc/source/api/pe.embedding.image.rst @@ -0,0 +1,18 @@ +pe.embedding.image package +========================== + +.. automodule:: pe.embedding.image + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.embedding.image.inception module +----------------------------------- + +.. automodule:: pe.embedding.image.inception + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.embedding.rst b/doc/source/api/pe.embedding.rst new file mode 100644 index 0000000..fbeee54 --- /dev/null +++ b/doc/source/api/pe.embedding.rst @@ -0,0 +1,26 @@ +pe.embedding package +==================== + +.. automodule:: pe.embedding + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.embedding.image + +Submodules +---------- + +pe.embedding.embedding module +----------------------------- + +.. automodule:: pe.embedding.embedding + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.histogram.nearest_neighbor_backend.rst b/doc/source/api/pe.histogram.nearest_neighbor_backend.rst new file mode 100644 index 0000000..6377013 --- /dev/null +++ b/doc/source/api/pe.histogram.nearest_neighbor_backend.rst @@ -0,0 +1,26 @@ +pe.histogram.nearest\_neighbor\_backend package +=============================================== + +.. automodule:: pe.histogram.nearest_neighbor_backend + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.histogram.nearest\_neighbor\_backend.faiss module +---------------------------------------------------- + +.. automodule:: pe.histogram.nearest_neighbor_backend.faiss + :members: + :undoc-members: + :show-inheritance: + +pe.histogram.nearest\_neighbor\_backend.sklearn module +------------------------------------------------------ + +.. automodule:: pe.histogram.nearest_neighbor_backend.sklearn + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.histogram.rst b/doc/source/api/pe.histogram.rst new file mode 100644 index 0000000..2316f2d --- /dev/null +++ b/doc/source/api/pe.histogram.rst @@ -0,0 +1,34 @@ +pe.histogram package +==================== + +.. automodule:: pe.histogram + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.histogram.nearest_neighbor_backend + +Submodules +---------- + +pe.histogram.histogram module +----------------------------- + +.. automodule:: pe.histogram.histogram + :members: + :undoc-members: + :show-inheritance: + +pe.histogram.nearest\_neighbors module +-------------------------------------- + +.. automodule:: pe.histogram.nearest_neighbors + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.logger.rst b/doc/source/api/pe.logger.rst new file mode 100644 index 0000000..5c3b302 --- /dev/null +++ b/doc/source/api/pe.logger.rst @@ -0,0 +1,50 @@ +pe.logger package +================= + +.. automodule:: pe.logger + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.logger.csv\_print module +--------------------------- + +.. automodule:: pe.logger.csv_print + :members: + :undoc-members: + :show-inheritance: + +pe.logger.image\_file module +---------------------------- + +.. automodule:: pe.logger.image_file + :members: + :undoc-members: + :show-inheritance: + +pe.logger.log\_print module +--------------------------- + +.. automodule:: pe.logger.log_print + :members: + :undoc-members: + :show-inheritance: + +pe.logger.logger module +----------------------- + +.. automodule:: pe.logger.logger + :members: + :undoc-members: + :show-inheritance: + +pe.logger.matplotlib\_pdf module +-------------------------------- + +.. automodule:: pe.logger.matplotlib_pdf + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.logging.rst b/doc/source/api/pe.logging.rst new file mode 100644 index 0000000..638a63b --- /dev/null +++ b/doc/source/api/pe.logging.rst @@ -0,0 +1,7 @@ +pe.logging package +================== + +.. automodule:: pe.logging + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.metric_item.rst b/doc/source/api/pe.metric_item.rst new file mode 100644 index 0000000..91146e4 --- /dev/null +++ b/doc/source/api/pe.metric_item.rst @@ -0,0 +1,7 @@ +pe.metric\_item package +======================= + +.. automodule:: pe.metric_item + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.population.rst b/doc/source/api/pe.population.rst new file mode 100644 index 0000000..c7f26a6 --- /dev/null +++ b/doc/source/api/pe.population.rst @@ -0,0 +1,26 @@ +pe.population package +===================== + +.. automodule:: pe.population + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.population.pe\_population module +----------------------------------- + +.. automodule:: pe.population.pe_population + :members: + :undoc-members: + :show-inheritance: + +pe.population.population module +------------------------------- + +.. automodule:: pe.population.population + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.rst b/doc/source/api/pe.rst new file mode 100644 index 0000000..5d6227f --- /dev/null +++ b/doc/source/api/pe.rst @@ -0,0 +1,27 @@ +pe package +========== + +.. automodule:: pe + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + pe.api + pe.callback + pe.constant + pe.data + pe.dp + pe.embedding + pe.histogram + pe.logger + pe.logging + pe.metric_item + pe.population + pe.runner + pe.util diff --git a/doc/source/api/pe.runner.rst b/doc/source/api/pe.runner.rst new file mode 100644 index 0000000..f7b7b13 --- /dev/null +++ b/doc/source/api/pe.runner.rst @@ -0,0 +1,18 @@ +pe.runner package +================= + +.. automodule:: pe.runner + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.runner.pe module +------------------- + +.. automodule:: pe.runner.pe + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/pe.util.rst b/doc/source/api/pe.util.rst new file mode 100644 index 0000000..de60c5b --- /dev/null +++ b/doc/source/api/pe.util.rst @@ -0,0 +1,18 @@ +pe.util package +=============== + +.. automodule:: pe.util + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pe.util.download module +----------------------- + +.. automodule:: pe.util.download + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..c64d68e --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,56 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "Private Evolution" +copyright = "2024, Zinan Lin" +author = "Zinan Lin" +release = "0.0.1" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ["_templates"] +exclude_patterns = [] + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_rtd_theme" # 'alabaster' +html_static_path = ["_static"] + +html_theme_options = {"navigation_depth": 6} + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.mathjax", + "sphinx.ext.ifconfig", + "sphinx.ext.viewcode", + "sphinx.ext.githubpages", + "sphinx.ext.napoleon", +] + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_init_with_doc = True +napoleon_include_private_with_doc = True +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True + +numfig = True diff --git a/doc/source/getting_started/details/api.rst b/doc/source/getting_started/details/api.rst new file mode 100644 index 0000000..af3ada6 --- /dev/null +++ b/doc/source/getting_started/details/api.rst @@ -0,0 +1,32 @@ +APIs +==== + +API reference: :doc:`/api/pe.api` + +:py:class:`pe.api.api.API` is responsible for implementing the foundation model APIs. It has the following key methods: + +* :py:meth:`pe.api.api.API.random_api`: Randomly generates the synthetic samples for the initial samples of the **Private Evolution** algorithm. +* :py:meth:`pe.api.api.API.variation_api`: Generates the variations of the given synthetic samples for the initial or the next **Private Evolution** iteration. + +Available APIs +-------------- + +Currently, the following APIs are implemented: + +* Images + + * :py:class:`pe.api.image.stable_diffusion_api.StableDiffusion`: The APIs of `Stable Diffusion`_. + * :py:class:`pe.api.image.improved_diffusion_api.ImprovedDiffusion`: The APIs of the `improved diffusion model`_. + +* Text + + * Coming soon! + +Adding Your Own APIs +-------------------- + +To add your own APIs, you need to create a class that inherits from :py:class:`pe.api.api.API` and implements the :py:meth:`pe.api.api.API.random_api` and :py:meth:`pe.api.api.API.variation_api` methods. + + +.. _improved diffusion model: https://github.com/openai/improved-diffusion +.. _Stable Diffusion: https://huggingface.co/CompVis/stable-diffusion-v1-4 diff --git a/doc/source/getting_started/details/callback_and_logger.rst b/doc/source/getting_started/details/callback_and_logger.rst new file mode 100644 index 0000000..cd68f30 --- /dev/null +++ b/doc/source/getting_started/details/callback_and_logger.rst @@ -0,0 +1,36 @@ +Callbacks and Loggers +====================== + +API reference: :doc:`/api/pe.callback` and :doc:`/api/pe.logger`. + +:py:class:`pe.callback.callback.Callback` can be configured to be called after each **Private Evolution** iteration with the synthetic data as the input. It is useful for computing metrics, saving the synthetic samples, monitoring the progress, etc. Each :py:class:`pe.callback.callback.Callback` can return a list of results (float numbers, images, matplotlib plots, etc.) in the form of :py:class:`pe.metric_item.MetricItem` (see :py:mod:`pe.metric_item`). All :py:class:`pe.metric_item.MetricItem` from all :py:class:`pe.callback.callback.Callback` will be passed through each of the :py:class:`pe.logger.logger.Logger` modules, which will then log the results in the desired way. + +Available Callbacks +------------------- + +Currently, the following callbacks are implemented: + +* For any data modality + + * :py:class:`pe.callback.common.compute_fid.ComputeFID`: Computes the FID between the synthetic samples and the private samples. + * :py:class:`pe.callback.common.save_checkpoints.SaveCheckpoints`: Saves the checkpoint of current synthetic samples to files. + +* Images + + * :py:class:`pe.callback.image.sample_images.SampleImages`: Samples some images from each class. + * :py:class:`pe.callback.image.save_all_images.SaveAllImages`: Saves all synthetic images to files. + +* Text + + * Coming soon! + + +Available Loggers +----------------- + +Currently, the following loggers are implemented: + +* :py:class:`pe.logger.csv_print.CSVPrint`: Saves the float results to a CSV file. +* :py:class:`pe.logger.log_print.LogPrint`: Prints the float results to the console and/or files using the logging module. +* :py:class:`pe.logger.image_file.ImageFile`: Saves the images to files. +* :py:class:`pe.logger.matplotlib_pdf.MatplotlibPDF`: Saves the matplotlib plots to PDF files. diff --git a/doc/source/getting_started/details/data.rst b/doc/source/getting_started/details/data.rst new file mode 100644 index 0000000..420a5a9 --- /dev/null +++ b/doc/source/getting_started/details/data.rst @@ -0,0 +1,49 @@ +Data +==== + +API reference: :doc:`/api/pe.data`. + +:py:class:`pe.data.data.Data` is the base class for holding the synthetic samples or the private samples, along with their metadata. Different components are mostly communicated through objects of this class. +:py:class:`pe.data.data.Data` has two key attributes: + +* ``data_frame``: A pandas_ DataFrame that holds the samples. Each row in the DataFrame is a sample, and each column is part of the sample (e.g., the image, the text, the label) and other information of the sample (e.g., its embedding produced by :doc:`embedding`). +* ``metadata``: A OmegaConf_ that holds the metadata of the samples, such as the **Private Evolution** iteration number when the samples are generated, and the label names of the classes. + +Available Datasets +------------------ + +For convenience, some well-known datasets are already packaged as `pe.data.data.Data` classes: + +* Image datasets + + * :py:class:`pe.data.image.cifar10.Cifar10`: The `CIFAR10 dataset`_. + * :py:class:`pe.data.image.camelyon17.Camelyon17`: The `Camelyon17 dataset`_. + * :py:class:`pe.data.image.cat.Cat`: The `Cat dataset`_. + * In addition, you can easily load a custom image dataset from a (nested) directory with the image files using :py:meth:`pe.data.image.image.load_image_folder`. + +* Text datasets + + * Coming soon! + +Using Your Own Datasets +----------------------- +To apply **Private Evolution** to your own private dataset, you need to create a :py:class:`pe.data.data.Data` object that holds your dataset, with two parameters, ``data_frame`` and ``metadata``, passed to the constructor: + +* ``data_frame``: A pandas_ DataFrame that holds the samples. Each row in the DataFrame is a sample. The following columns must be included: + + * :py:attr:`pe.constant.data.LABEL_ID_COLUMN_NAME`: The label (class) ID of the sample. The label IDs must be in {0, 1, ..., K-1} if there are K classes. If you are targeting unconditional generation, the values of this column can just be zeros. + + The ``data_frame`` can have any numbers of additional columns that hold the data of the samples, as long as the modules you are using (e.g., :doc:`api`, :doc:`Callbacks `) can recognize them. + +* ``metadata``: A dictionary that holds the metadata of the samples. The following keys must be included: + + * ``label_names``: A list of strings that holds the names of the classes. The length of the list must be equal to K. + + In addition, you can include any other keys that hold the metadata of the samples if needed. + + +.. _OmegaConf: https://omegaconf.readthedocs.io/en/latest/ +.. _pandas: https://pandas.pydata.org/ +.. _Cat dataset: https://www.kaggle.com/datasets/fjxmlzn/cat-cookie-doudou +.. _CIFAR10 dataset: https://www.cs.toronto.edu/~kriz/cifar.html +.. _Camelyon17 dataset: https://camelyon17.grand-challenge.org/ diff --git a/doc/source/getting_started/details/details.rst b/doc/source/getting_started/details/details.rst new file mode 100644 index 0000000..37efb39 --- /dev/null +++ b/doc/source/getting_started/details/details.rst @@ -0,0 +1,16 @@ +Details of the Library +======================= + +.. toctree:: + :maxdepth: 5 + :caption: Contents: + + overview + data + population + api + histogram + dp + embedding + callback_and_logger + runner diff --git a/doc/source/getting_started/details/dp.rst b/doc/source/getting_started/details/dp.rst new file mode 100644 index 0000000..2a3e57c --- /dev/null +++ b/doc/source/getting_started/details/dp.rst @@ -0,0 +1,16 @@ +DP +=== + +API reference: :doc:`/api/pe.dp`. + +:py:class:`pe.dp.dp.DP` is responsible for implementing the differential privacy mechanism. It has the following key methods: + +* :py:meth:`pe.dp.dp.DP.set_epsilon_and_delta`: Set the privacy budget for the differential privacy mechanism. +* :py:meth:`pe.dp.dp.DP.add_noise`: Add noise to the histogram values to achieve differential privacy. + +Available Differential Privacy Mechanisms +----------------------------------------- + +Currently, the following differential privacy mechanisms are implemented: + +* :py:class:`pe.dp.gaussian.Gaussian`: The Gaussian mechanism, which adds Gaussian noise to the histogram values. \ No newline at end of file diff --git a/doc/source/getting_started/details/embedding.rst b/doc/source/getting_started/details/embedding.rst new file mode 100644 index 0000000..acf93ec --- /dev/null +++ b/doc/source/getting_started/details/embedding.rst @@ -0,0 +1,22 @@ +Embeddings +========== + +API reference: :doc:`/api/pe.embedding`. + +:py:class:`pe.embedding.embedding.Embedding` is responsible for computing the embeddings of the (synthetic or private) samples. It has the following key methods/attributes: + +* :py:meth:`pe.embedding.embedding.Embedding.compute_embedding`: Computes the embeddings of the (synthetic or private) samples. +* :py:attr:`pe.embedding.embedding.Embedding.column_name`: The column name to be used when saving the embeddings in the ``data_frame`` of `pe.data.data.Data`. + +Available Embeddings +-------------------- + +Currently, the following embeddings are implemented: + +* Images + + * :py:class:`pe.embedding.image.inception.Inception`: The embeddings computed using the Inception model. + +* Text + + * Coming soon! diff --git a/doc/source/getting_started/details/histogram.rst b/doc/source/getting_started/details/histogram.rst new file mode 100644 index 0000000..b7ee4ac --- /dev/null +++ b/doc/source/getting_started/details/histogram.rst @@ -0,0 +1,15 @@ +Histograms +========== + +API reference: :doc:`/api/pe.histogram`. + +:py:class:`pe.histogram.histogram.Histogram` is responsible for generating the histograms over the synthetic samples. It has the following key methods: + +* :py:meth:`pe.histogram.histogram.Histogram.compute_histogram`: Generates the histograms over the synthetic samples using private samples. + +Available Histograms +-------------------- + +Currently, the following histograms are implemented: + +* :py:class:`pe.histogram.nearest_neighbors.NearestNeighbors`: This histogram algorithm projects the synthetic samples and the private samples into an embedding space and computes the nearest neighbor(s) of each private sample in the synthetic samples. The histogram value for each synthetic sample is the number of times it is the nearest neighbor(s) of a private sample. \ No newline at end of file diff --git a/doc/source/getting_started/details/overview.rst b/doc/source/getting_started/details/overview.rst new file mode 100644 index 0000000..7bc59bf --- /dev/null +++ b/doc/source/getting_started/details/overview.rst @@ -0,0 +1,59 @@ +Overview +======== + +.. _workflow: +.. figure:: workflow.jpg + :align: center + :figwidth: 90% + + The workflow of **Private Evolution**. + + +The Private Evolution Algorithm +------------------------------- + +The workflow of `Private Evolution `_ is shown in the above :numref:`workflow`. +The workflow consists of the following steps: + +* Using the foundation model API to randomly generate the initial synthetic samples. +* Iteratively refining the synthetic samples by: + + * Building a histogram over the synthetic samples using the private samples. The histogram value for each synthetic sample represents how similar it is to the private samples. + * Adding noise to the histogram to ensure differential privacy. + * Selecting a subset of the synthetic samples based on the noisy histogram. Those selected samples are expected to be more similar to the private samples. + * Using the foundation model API to generate variations of the selected synthetic samples. + +* Outputting the final synthetic samples. + +Core Design Principles of This Library +-------------------------------------- + +The design principles of this library are: + +* Easy to use. +* Supporting different data modalities (e.g., images, text), different foundation model APIs (e.g., Stable Diffusion, GPT models), different **Private Evolution** algorithms (e.g., PE, Aug-PE), and different evaluation metrics (e.g., FID), all in one framework. +* Easy to add new data modalities, foundation model APIs, **Private Evolution** algorithms, evaluation metrics, etc. + +Towards these goals, the library is designed to be highly modular and extensible, as discussed next. + +Core Components of This Library +-------------------------------- + +This library provides a set of core components that can be easily customized or replaced. The core components shown in the :numref:`workflow` include: + +* :doc:`runner`: Running the whole **Private Evolution** algorithm. +* :doc:`population`: Generating the initial synthetic samples and the variations of the synthetic samples. +* :doc:`histogram`: Building the histogram over the synthetic samples. +* :doc:`dp`: Adding noise to the histogram to ensure differential privacy. + +In additional to these components shown in the :numref:`workflow`, the library also has the following core components: + +* :doc:`data`: This class holds the synthetic samples or the private samples. Different components are mostly communicated through objects of this class. +* :doc:`api`: This class implements the foundation model APIs. This class is utilized by :doc:`population` to generate the synthetic samples and the variations of the synthetic samples. It might also be used in some :doc:`histogram` algorithms when building the histogram (e.g., when ``lookahead`` in `PE `_ is used). +* :doc:`embedding`: This class is used to embed the synthetic/private samples into an embedding space. It might be used in some :doc:`histogram` algorithms when building the histogram. It might also be used in some :doc:`metric evaluation callback modules ` (e.g., for computing FID). +* :doc:`callback_and_logger`: The :doc:`runner` can be configured to call a given list of callback modules at the end of each Private Evolution iteration. This is very useful for saving the intermediate results, evaluating the synthetic samples, etc. Since we might want to evaluate multiple metrics (e.g., FID, precision, recall), and for each metric, we might want to log it in different ways (e.g., saving it to a file, printing it to the console, uploading it to WandB), the library abstracts this part into two modules: + + * :doc:`Callbacks `: This module computes the metrics and (optionally) return the results. (The callback can also return nothing if it does not need the loggers to help with logging the results, e.g., if this callback is for saving the immediate synthetic samples.) + * :doc:`Loggers `: All results returned by the callback modules will be passed through each of the logger modules, which will then log the results in the desired way. + +.. _paper: https://arxiv.org/abs/2305.15560 diff --git a/doc/source/getting_started/details/population.rst b/doc/source/getting_started/details/population.rst new file mode 100644 index 0000000..0396076 --- /dev/null +++ b/doc/source/getting_started/details/population.rst @@ -0,0 +1,15 @@ +Population +========== + +API reference: :doc:`/api/pe.population`. + +:py:class:`pe.population.population.Population` is responsible for generating the initial synthetic samples and the new synthetic samples for each **Private Evolution** iteration. It has the following key methods: + +* :py:meth:`pe.population.population.Population.initial`: Generates the initial synthetic samples. +* :py:meth:`pe.population.population.Population.next`: Generates the synthetic samples for the next **Private Evolution** iteration. + +Available Populations +--------------------- + +:py:class:`pe.population.pe_population.PEPopulation` is currently the only implementation of :py:class:`pe.population.population.Population`. It supports the key population algorthms from existing **Private Evolution** papers (https://github.com/fjxmlzn/private-evolution-papers). + diff --git a/doc/source/getting_started/details/runner.rst b/doc/source/getting_started/details/runner.rst new file mode 100644 index 0000000..24054b0 --- /dev/null +++ b/doc/source/getting_started/details/runner.rst @@ -0,0 +1,8 @@ +Runner +====== + +API reference: :doc:`/api/pe.runner`. + +:py:class:`pe.runner.pe.PE` manages the main **Private Evolution** algorithm by calling the other components discussed before. It has the following key methods: + +* :py:meth:`pe.runner.pe.PE.run`: Runs the **Private Evolution** algorithm. diff --git a/doc/source/getting_started/details/workflow.jpg b/doc/source/getting_started/details/workflow.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b68448612b1acbb5d1d600d254e835665af93971 GIT binary patch literal 512289 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 z

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 R-mO=Jrd3N%0}+2V(8 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 M@So!YwBH8)2ZeR1I{*Lx literal 0 HcmV?d00001 diff --git a/doc/source/getting_started/examples.rst b/doc/source/getting_started/examples.rst new file mode 100644 index 0000000..a5d17cd --- /dev/null +++ b/doc/source/getting_started/examples.rst @@ -0,0 +1,30 @@ +Examples +======== + +Here are some examples of how to use the **Private Evolution** library. + +Images +------ + +These examples follow the experimental settings in the paper `Differentially Private Synthetic Data via Foundation Model APIs 1: Images (ICLR 2024) `__. + +* **CIFAR10**: `This example `__ shows how to generate differentially private synthetic images for the `CIFAR10 dataset`_ using the APIs from a pre-trained `ImageNet diffusion model`_. + +* **Camelyon17**: `This example `__ shows how to generate differentially private synthetic images for the `Camelyon17 dataset`_ using the APIs from a pre-trained `ImageNet diffusion model`_. + +* **Cat**: `This example `__ shows how to generate differentially private synthetic images of the `Cat dataset`_ using the APIs from `Stable Diffusion`_. + +Text +---- + +Coming soon! + +.. _ImageNet diffusion model: https://github.com/openai/improved-diffusion +.. _Stable Diffusion: https://huggingface.co/CompVis/stable-diffusion-v1-4 +.. _Cat dataset: https://www.kaggle.com/datasets/fjxmlzn/cat-cookie-doudou +.. _CIFAR10 dataset: https://www.cs.toronto.edu/~kriz/cifar.html +.. _Camelyon17 dataset: https://camelyon17.grand-challenge.org/ +.. _CIFAR10 example: https://github.com/microsoft/DPSDA/blob/main/example/image/cifar10.py +.. _Camelyon17 example: https://github.com/microsoft/DPSDA/blob/main/example/image/camelyon17.py +.. _Cat example: https://github.com/microsoft/DPSDA/blob/main/example/image/cat.py +.. _paper: https://arxiv.org/abs/2305.15560 \ No newline at end of file diff --git a/doc/source/getting_started/getting_started.rst b/doc/source/getting_started/getting_started.rst new file mode 100644 index 0000000..ecd0a76 --- /dev/null +++ b/doc/source/getting_started/getting_started.rst @@ -0,0 +1,13 @@ +Getting Started +=============================== + + +.. toctree:: + :maxdepth: 5 + :caption: Contents: + + intro + installation + examples + details/details + diff --git a/doc/source/getting_started/installation.rst b/doc/source/getting_started/installation.rst new file mode 100644 index 0000000..3bf0ac8 --- /dev/null +++ b/doc/source/getting_started/installation.rst @@ -0,0 +1,40 @@ +Installation +============ + +PIP +--- + +To install the core package of **Private Evolution**, please use the following command: + +.. code-block:: bash + + pip install "private-evolution @ git+https://github.com/microsoft/DPSDA.git" + +If you are using **Private Evolution** to generate images, use the following command instead to install the package with the necessary dependencies for image generation: + +.. code-block:: bash + + pip install "private-evolution[image] @ git+https://github.com/microsoft/DPSDA.git" + +Faiss +----- + +**Private Evolution** requires a nearest neighbor search process. By default, it uses the sklearn_ package for this purpose. However, for faster computation, we recommend using the faiss_ package. +To install `faiss 1.8.0`, please use the following command: + +.. code-block:: bash + + conda install -y -c pytorch -c nvidia faiss-gpu=1.8.0 + +Please check out the faiss_ website for the latest information on how to install the package. + +.. + Docker + ------ + + We provide Docker images for **Private Evolution** with all dependencies (including faiss_) pre-installed. To pull the Docker image, please use the following command: + + TODO + +.. _faiss: https://faiss.ai/ +.. _sklearn: https://scikit-learn.org/dev/modules/generated/sklearn.neighbors.NearestNeighbors.html \ No newline at end of file diff --git a/doc/source/getting_started/intro.rst b/doc/source/getting_started/intro.rst new file mode 100644 index 0000000..48b42fd --- /dev/null +++ b/doc/source/getting_started/intro.rst @@ -0,0 +1,40 @@ +What is Private Evolution? +=============================== + +**Private Evolution** (PE in short) is an algorithm for **generating differentially private synthetic data without the need of any ML model training**. + +Given a dataset, **Private Evolution** can generate a new synthetic dataset that is statistically similar to the original dataset, while ensuring a rigorous privacy guarantee called `differential privacy (DP) `_, which implies that the privacy of individuals in the original dataset is protected. It is particularly useful in situations where the original data is sensitive or confidential, such as medical records, financial data, or personal information. The DP synthetic dataset can replace the original data in various use cases where privacy is a concern, for example: + +* Sharing them with other parties for collaboration and research. +* Using them in downstream algorithms (e.g., training ML models) in the normal non-private pipeline. +* Inspecting the data directly for easier product debugging and development. + +Key Features +------------ + +Compared to other DP synthetic data alternatives, **Private Evolution** has the following key features: + +* ✅ **No training needed!** **Private Evolution** only requires the inference APIs of foundation models. Therefore, it can leverage any state-of-the-art black-box models (e.g., GPT-4) and open-source models (e.g., Stable Diffusion, Llama). +* ✅ **Protects privacy even from the API provider.** Even when using APIs from a third-party provider, you can rest assured that the information of individuals in the original dataset is still protected, as all API queries made from **Private Evolution** are also differentially private. +* ✅ **Works across images, text, etc.** **Private Evolution** can generate synthetic data for various data types, including images and text. More data modalities are coming soon! +* ✅ **Could even match/beat SoTA training-based methods in data quality.** **Private Evolution** can generate synthetic data that is statistically similar to the original data, and in some cases, it can even match or beat the state-of-the-art training-based methods in data quality even though it does not require any training. + +What This Library Provides +-------------------------- + +**This library is the official Python package of Private Evolution**. It allows you to generate differentially private synthetic data (e.g., images, text) using the **Private Evolution** algorithm. This library is designed to be easy to use, flexible, modular, and extensible. It provides several popular foundation model APIs, and you can easily extend it to work with your own foundation models (and/or APIs), data types, or new **Private Evolution** algorithms if needed. + +The source code of this **Private Evolution** library is available at https://github.com/microsoft/DPSDA. + +Citations +--------- + +If you use **Private Evolution** in your research or work, please cite the following papers: + +.. literalinclude:: pe1.bib + :language: bibtex + +.. literalinclude:: pe2.bib + :language: bibtex + +Please see https://github.com/fjxmlzn/private-evolution-papers for the full list of **Private Evolution** papers done by the community. diff --git a/doc/source/getting_started/pe1.bib b/doc/source/getting_started/pe1.bib new file mode 100644 index 0000000..d78c1d0 --- /dev/null +++ b/doc/source/getting_started/pe1.bib @@ -0,0 +1,6 @@ +@article{lin2023differentially, + title={Differentially private synthetic data via foundation model apis 1: Images}, + author={Lin, Zinan and Gopi, Sivakanth and Kulkarni, Janardhan and Nori, Harsha and Yekhanin, Sergey}, + journal={arXiv preprint arXiv:2305.15560}, + year={2023} +} \ No newline at end of file diff --git a/doc/source/getting_started/pe2.bib b/doc/source/getting_started/pe2.bib new file mode 100644 index 0000000..5bde0ab --- /dev/null +++ b/doc/source/getting_started/pe2.bib @@ -0,0 +1,6 @@ +@article{xie2024differentially, + title={Differentially private synthetic data via foundation model apis 2: Text}, + author={Xie, Chulin and Lin, Zinan and Backurs, Arturs and Gopi, Sivakanth and Yu, Da and Inan, Huseyin A and Nori, Harsha and Jiang, Haotian and Zhang, Huishuai and Lee, Yin Tat and others}, + journal={arXiv preprint arXiv:2403.01749}, + year={2024} +} \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..1c98d94 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,18 @@ +.. Private Evolution documentation master file, created by + sphinx-quickstart on Wed Oct 30 22:51:11 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Private Evolution Documentation +=============================== + +The source code of this **Private Evolution** library is available at https://github.com/microsoft/DPSDA. + + +.. toctree:: + :maxdepth: 5 + :caption: Contents: + + getting_started/getting_started + api/api + diff --git a/example/image/camelyon17.py b/example/image/camelyon17.py new file mode 100644 index 0000000..79f6674 --- /dev/null +++ b/example/image/camelyon17.py @@ -0,0 +1,64 @@ +from pe.data.image import Camelyon17 +from pe.logging import setup_logging +from pe.runner import PE +from pe.population import PEPopulation +from pe.api.image import ImprovedDiffusion270M +from pe.embedding.image import Inception +from pe.histogram import NearestNeighbors +from pe.callback import SaveCheckpoints +from pe.callback import SampleImages +from pe.callback import ComputeFID +from pe.logger import ImageFile +from pe.logger import CSVPrint +from pe.logger import LogPrint + +import pandas as pd +import os +import numpy as np + +pd.options.mode.copy_on_write = True + + +if __name__ == "__main__": + exp_folder = "results/image/camelyon17" + + setup_logging(log_file=os.path.join(exp_folder, "log.txt")) + + data = Camelyon17(root_dir="/tmp/data/") + api = ImprovedDiffusion270M( + variation_degrees=[0] * 5 + [1] * 5 + [2] * 5 + [3] * 4 + list(range(20, 31)), + timestep_respacing=["ddim10"] * 19 + ["40"] * 11, + ) + embedding = Inception(res=64, batch_size=100) + histogram = NearestNeighbors( + embedding=embedding, + mode="L2", + lookahead_degree=8, + lookahead_log_folder=os.path.join(exp_folder, "lookahead"), + voting_details_log_folder=os.path.join(exp_folder, "voting_details"), + api=api, + backend="faiss", + ) + population = PEPopulation(api=api, histogram_threshold=4) + + save_checkpoints = SaveCheckpoints(os.path.join(exp_folder, "checkpoint")) + sample_images = SampleImages() + compute_fid = ComputeFID(priv_data=data, embedding=embedding) + + image_file = ImageFile(output_folder=exp_folder) + csv_print = CSVPrint(output_folder=exp_folder) + log_print = LogPrint() + + pe_runner = PE( + priv_data=data, + population=population, + histogram=histogram, + callbacks=[save_checkpoints, sample_images, compute_fid], + loggers=[image_file, csv_print, log_print], + ) + pe_runner.run( + num_samples_schedule=[302436] * 30, + delta=3e-6, + noise_multiplier=2 * np.sqrt(2), + checkpoint_path=os.path.join(exp_folder, "checkpoint"), + ) diff --git a/example/image/cat.py b/example/image/cat.py new file mode 100644 index 0000000..0516419 --- /dev/null +++ b/example/image/cat.py @@ -0,0 +1,66 @@ +from pe.data.image import Cat +from pe.logging import setup_logging +from pe.runner import PE +from pe.population import PEPopulation +from pe.api.image import StableDiffusion +from pe.embedding.image import Inception +from pe.histogram import NearestNeighbors +from pe.callback import SaveCheckpoints +from pe.callback import SampleImages +from pe.callback import SaveAllImages +from pe.callback import ComputeFID +from pe.logger import ImageFile +from pe.logger import CSVPrint +from pe.logger import LogPrint + +import pandas as pd +import os +import numpy as np + +pd.options.mode.copy_on_write = True + + +if __name__ == "__main__": + exp_folder = "results/image/cat" + + setup_logging(log_file=os.path.join(exp_folder, "log.txt")) + + data = Cat(root_dir="/tmp/data/") + api = StableDiffusion( + prompt={"cookie": "A photo of ragdoll cat", "doudou": "A photo of ragdoll cat"}, + variation_degrees=list(np.arange(1.0, 0.9, -0.02)) + list(np.arange(0.88, 0.36, -0.04)), + ) + embedding = Inception(res=512, batch_size=100) + histogram = NearestNeighbors( + embedding=embedding, + mode="L2", + lookahead_degree=8, + lookahead_log_folder=os.path.join(exp_folder, "lookahead"), + voting_details_log_folder=os.path.join(exp_folder, "voting_details"), + api=api, + backend="faiss", + ) + population = PEPopulation(api=api, histogram_threshold=2) + + save_checkpoints = SaveCheckpoints(os.path.join(exp_folder, "checkpoint")) + sample_images = SampleImages() + save_all_images = SaveAllImages(output_folder=os.path.join(exp_folder, "all_images")) + compute_fid = ComputeFID(priv_data=data, embedding=embedding) + + image_file = ImageFile(output_folder=exp_folder) + csv_print = CSVPrint(output_folder=exp_folder) + log_print = LogPrint() + + pe_runner = PE( + priv_data=data, + population=population, + histogram=histogram, + callbacks=[save_checkpoints, sample_images, compute_fid, save_all_images], + loggers=[image_file, csv_print, log_print], + ) + pe_runner.run( + num_samples_schedule=[200] * 18, + delta=1e-3, + noise_multiplier=2, + checkpoint_path=os.path.join(exp_folder, "checkpoint"), + ) diff --git a/example/image/cifar10.py b/example/image/cifar10.py new file mode 100644 index 0000000..fbe38c9 --- /dev/null +++ b/example/image/cifar10.py @@ -0,0 +1,64 @@ +from pe.data.image import Cifar10 +from pe.logging import setup_logging +from pe.runner import PE +from pe.population import PEPopulation +from pe.api.image import ImprovedDiffusion270M +from pe.embedding.image import Inception +from pe.histogram import NearestNeighbors +from pe.callback import SaveCheckpoints +from pe.callback import SampleImages +from pe.callback import ComputeFID +from pe.logger import ImageFile +from pe.logger import CSVPrint +from pe.logger import LogPrint + +import pandas as pd +import os +import numpy as np + +pd.options.mode.copy_on_write = True + + +if __name__ == "__main__": + exp_folder = "results/image/cifar10" + + setup_logging(log_file=os.path.join(exp_folder, "log.txt")) + + data = Cifar10() + api = ImprovedDiffusion270M( + variation_degrees=list(range(0, 42, 2)), + timestep_respacing="100", + ) + embedding = Inception(res=32, batch_size=100) + histogram = NearestNeighbors( + embedding=embedding, + mode="L2", + lookahead_degree=8, + lookahead_log_folder=os.path.join(exp_folder, "lookahead"), + voting_details_log_folder=os.path.join(exp_folder, "voting_details"), + api=api, + backend="faiss", + ) + population = PEPopulation(api=api, histogram_threshold=10) + + save_checkpoints = SaveCheckpoints(os.path.join(exp_folder, "checkpoint")) + sample_images = SampleImages() + compute_fid = ComputeFID(priv_data=data, embedding=embedding) + + image_file = ImageFile(output_folder=exp_folder) + csv_print = CSVPrint(output_folder=exp_folder) + log_print = LogPrint() + + pe_runner = PE( + priv_data=data, + population=population, + histogram=histogram, + callbacks=[save_checkpoints, sample_images, compute_fid], + loggers=[image_file, csv_print, log_print], + ) + pe_runner.run( + num_samples_schedule=[50000] * 21, + delta=1e-5, + noise_multiplier=5 * np.sqrt(2), + checkpoint_path=os.path.join(exp_folder, "checkpoint"), + ) diff --git a/pe/__init__.py b/pe/__init__.py new file mode 100644 index 0000000..0ac84d2 --- /dev/null +++ b/pe/__init__.py @@ -0,0 +1 @@ +from .runner.pe import PE diff --git a/pe/api/__init__.py b/pe/api/__init__.py new file mode 100644 index 0000000..ae40d11 --- /dev/null +++ b/pe/api/__init__.py @@ -0,0 +1 @@ +from .api import API diff --git a/pe/api/api.py b/pe/api/api.py new file mode 100644 index 0000000..31481e6 --- /dev/null +++ b/pe/api/api.py @@ -0,0 +1,25 @@ +from abc import ABC, abstractmethod + + +class API(ABC): + """The abstract class that defines the APIs for the synthetic data generation.""" + + @abstractmethod + def random_api(self, label_name, num_samples): + """The abstract method that generates random synthetic data. + + :param label_name: The name of the label + :type label_name: str + :param num_samples: The number of random samples to generate + :type num_samples: int + """ + ... + + @abstractmethod + def variation_api(self, syn_data): + """The abstract method that generates variations of the synthetic data. + + :param syn_data: The data object of the synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + """ + ... diff --git a/pe/api/image/__init__.py b/pe/api/image/__init__.py new file mode 100644 index 0000000..e26ceab --- /dev/null +++ b/pe/api/image/__init__.py @@ -0,0 +1,3 @@ +from .improved_diffusion_api import ImprovedDiffusion +from .improved_diffusion_api import ImprovedDiffusion270M +from .stable_diffusion_api import StableDiffusion diff --git a/pe/api/image/improved_diffusion_api.py b/pe/api/image/improved_diffusion_api.py new file mode 100644 index 0000000..bc76121 --- /dev/null +++ b/pe/api/image/improved_diffusion_api.py @@ -0,0 +1,379 @@ +import torch +import numpy as np +import pandas as pd +import tempfile +import os + +from pe.api import API +from pe.logging import execution_logger +from pe.data import Data +from pe.constant.data import IMAGE_DATA_COLUMN_NAME +from pe.constant.data import IMAGE_MODEL_LABEL_COLUMN_NAME +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.api.util import ConstantList +from pe.util import download + +from improved_diffusion.script_util import NUM_CLASSES +from .improved_diffusion_lib.unet import create_model +from .improved_diffusion_lib.gaussian_diffusion import create_gaussian_diffusion + + +class ImprovedDiffusion(API): + """The image API that utilizes improved diffusion models from https://arxiv.org/abs/2102.09672.""" + + def __init__( + self, + variation_degrees, + model_path, + model_image_size=64, + num_channels=192, + num_res_blocks=3, + learn_sigma=True, + class_cond=True, + use_checkpoint=False, + attention_resolutions="16,8", + num_heads=4, + num_heads_upsample=-1, + use_scale_shift_norm=True, + dropout=0.0, + diffusion_steps=4000, + sigma_small=False, + noise_schedule="cosine", + use_kl=False, + predict_xstart=False, + rescale_timesteps=False, + rescale_learned_sigmas=False, + timestep_respacing="100", + batch_size=2000, + use_ddim=True, + clip_denoised=True, + use_data_parallel=True, + ): + """Constructor. + See https://github.com/openai/improved-diffusion for the explanation of the parameters not listed here. + + :param variation_degrees: The variation degrees utilized at each PE iteration. If a single int is provided, the + same variation degree will be used for all iterations. + :type variation_degrees: int or list[int] + :param model_path: The path of the model checkpoint + :type model_path: str + :param diffusion_steps: The total number of diffusion steps, defaults to 4000 + :type diffusion_steps: int, optional + :param timestep_respacing: The step configurations for image generation utilized at each PE iteration. If a + single str is provided, the same step configuration will be used for all iterations. Defaults to "100" + :type timestep_respacing: str or list[str], optional + :param batch_size: The batch size for image generation, defaults to 2000 + :type batch_size: int, optional + :param use_data_parallel: Whether to use data parallel during image generation, defaults to True + :type use_data_parallel: bool, optional + """ + super().__init__() + self._model = create_model( + image_size=model_image_size, + num_channels=num_channels, + num_res_blocks=num_res_blocks, + learn_sigma=learn_sigma, + class_cond=class_cond, + use_checkpoint=use_checkpoint, + attention_resolutions=attention_resolutions, + num_heads=num_heads, + num_heads_upsample=num_heads_upsample, + use_scale_shift_norm=use_scale_shift_norm, + dropout=dropout, + ) + self._device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + self._model.load_state_dict(torch.load(model_path, map_location="cpu")) + self._model.to(self._device) + self._model.eval() + all_timestep_respacing = ( + set(timestep_respacing) if isinstance(timestep_respacing, list) else {timestep_respacing} + ) + self._timestep_respacing_to_diffusion = {} + self._timestep_respacing_to_sampler = {} + for sub_timestep_respacing in all_timestep_respacing: + self._timestep_respacing_to_diffusion[sub_timestep_respacing] = create_gaussian_diffusion( + steps=diffusion_steps, + learn_sigma=learn_sigma, + sigma_small=sigma_small, + noise_schedule=noise_schedule, + use_kl=use_kl, + predict_xstart=predict_xstart, + rescale_timesteps=rescale_timesteps, + rescale_learned_sigmas=rescale_learned_sigmas, + timestep_respacing=sub_timestep_respacing, + ) + self._timestep_respacing_to_sampler[sub_timestep_respacing] = Sampler( + model=self._model, diffusion=self._timestep_respacing_to_diffusion[sub_timestep_respacing] + ) + if use_data_parallel: + self._timestep_respacing_to_sampler[sub_timestep_respacing] = torch.nn.DataParallel( + self._timestep_respacing_to_sampler[sub_timestep_respacing] + ) + if isinstance(timestep_respacing, str): + self._timestep_respacing = ConstantList(timestep_respacing) + else: + self._timestep_respacing = timestep_respacing + self._batch_size = batch_size + self._use_ddim = use_ddim + self._image_size = model_image_size + self._clip_denoised = clip_denoised + self._class_cond = class_cond + if isinstance(variation_degrees, int): + self._variation_degrees = ConstantList(variation_degrees) + else: + self._variation_degrees = variation_degrees + + def random_api(self, label_name, num_samples): + """Generating random synthetic data. + + :param label_name: The name of the label, not utilized in this API + :type label_name: str + :param num_samples: The number of random samples to generate + :type num_samples: int + :return: The data object of the generated synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + execution_logger.info(f"RANDOM API: creating {num_samples} samples for label {label_name}") + samples, labels = sample( + sampler=self._timestep_respacing_to_sampler[self._timestep_respacing[0]], + start_t=0, + num_samples=num_samples, + batch_size=self._batch_size, + use_ddim=self._use_ddim, + image_size=self._image_size, + clip_denoised=self._clip_denoised, + class_cond=self._class_cond, + device=self._device, + ) + samples = _round_to_uint8((samples + 1.0) * 127.5) + samples = samples.transpose(0, 2, 3, 1) + torch.cuda.empty_cache() + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: list(samples), + IMAGE_MODEL_LABEL_COLUMN_NAME: list(labels), + } + ) + execution_logger.info(f"RANDOM API: finished creating {num_samples} samples for label {label_name}") + return Data(data_frame=data_frame) + + def variation_api(self, syn_data): + """Generating variations of the synthetic data. + + :param syn_data: The data object of the synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: The data object of the variation of the input synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + execution_logger.info(f"VARIATION API: creating variations for {len(syn_data.data_frame)} samples") + images = np.stack(syn_data.data_frame[IMAGE_DATA_COLUMN_NAME].values) + labels = np.array(syn_data.data_frame[IMAGE_MODEL_LABEL_COLUMN_NAME].values) + iteration = getattr(syn_data.metadata, "iteration", -1) + variation_degree = self._variation_degrees[iteration + 1] + timestep_respacing = self._timestep_respacing[iteration + 1] + + execution_logger.info( + f"VARIATION API parameters: variation_degree={variation_degree}, timestep_respacing={timestep_respacing}, " + f"iteration={iteration}" + ) + + images = images.astype(np.float32) / 127.5 - 1.0 + images = images.transpose(0, 3, 1, 2) + variations, _ = sample( + sampler=self._timestep_respacing_to_sampler[timestep_respacing], + start_t=variation_degree, + start_image=torch.Tensor(images).to(self._device), + labels=(None if not self._class_cond else torch.LongTensor(labels).to(self._device)), + num_samples=images.shape[0], + batch_size=self._batch_size, + use_ddim=self._use_ddim, + image_size=self._image_size, + clip_denoised=self._clip_denoised, + class_cond=self._class_cond, + device=self._device, + ) + variations = _round_to_uint8((variations + 1.0) * 127.5) + variations = variations.transpose(0, 2, 3, 1) + torch.cuda.empty_cache() + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: list(variations), + IMAGE_MODEL_LABEL_COLUMN_NAME: list(labels), + } + ) + if LABEL_ID_COLUMN_NAME in syn_data.data_frame.columns: + data_frame[LABEL_ID_COLUMN_NAME] = syn_data.data_frame[LABEL_ID_COLUMN_NAME].values + execution_logger.info(f"VARIATION API: finished creating variations for {len(syn_data.data_frame)} samples") + return Data(data_frame=data_frame, metadata=syn_data.metadata) + + +def sample( + sampler, + num_samples, + start_t, + batch_size, + use_ddim, + image_size, + clip_denoised, + class_cond, + device, + start_image=None, + labels=None, +): + all_images = [] + all_labels = [] + batch_cnt = 0 + cnt = 0 + while cnt < num_samples: + current_batch_size = ( + batch_size if start_image is None else min(batch_size, start_image.shape[0] - batch_cnt * batch_size) + ) + current_batch_size = min(num_samples - cnt, current_batch_size) + shape = (current_batch_size, 3, image_size, image_size) + model_kwargs = {} + if class_cond: + if labels is None: + classes = torch.randint( + low=0, + high=NUM_CLASSES, + size=(current_batch_size,), + device=device, + ) + else: + classes = labels[batch_cnt * batch_size : (batch_cnt + 1) * batch_size] + model_kwargs["y"] = classes + sample = sampler( + clip_denoised=clip_denoised, + model_kwargs=model_kwargs, + start_t=max(start_t, 0), + start_image=( + None if start_image is None else start_image[batch_cnt * batch_size : (batch_cnt + 1) * batch_size] + ), + use_ddim=use_ddim, + noise=torch.randn(*shape, device=device), + image_size=image_size, + ) + batch_cnt += 1 + + all_images.append(sample.detach().cpu().numpy()) + + if class_cond: + all_labels.append(classes.detach().cpu().numpy()) + + cnt += sample.shape[0] + execution_logger.info(f"Created {cnt} samples") + + all_images = np.concatenate(all_images, axis=0) + all_images = all_images[:num_samples] + + if class_cond: + all_labels = np.concatenate(all_labels, axis=0) + all_labels = all_labels[:num_samples] + else: + all_labels = np.zeros(shape=(num_samples,)) + return all_images, all_labels + + +class Sampler(torch.nn.Module): + """A wrapper around the model and diffusion modules that handles the entire + sampling process, so as to reduce the communiation rounds between GPUs when + using DataParallel. + """ + + def __init__(self, model, diffusion): + super().__init__() + self._model = model + self._diffusion = diffusion + + def forward( + self, + clip_denoised, + model_kwargs, + start_t, + start_image, + use_ddim, + noise, + image_size, + ): + sample_fn = self._diffusion.p_sample_loop if not use_ddim else self._diffusion.ddim_sample_loop + sample = sample_fn( + self._model, + (noise.shape[0], 3, image_size, image_size), + clip_denoised=clip_denoised, + model_kwargs=model_kwargs, + start_t=max(start_t, 0), + start_image=start_image, + noise=noise, + device=noise.device, + ) + return sample + + +def _round_to_uint8(image): + return np.around(np.clip(image, a_min=0, a_max=255)).astype(np.uint8) + + +class ImprovedDiffusion270M(ImprovedDiffusion): + #: The URL of the checkpoint path + CHECKPOINT_URL = "https://openaipublic.blob.core.windows.net/diffusion/march-2021/imagenet64_cond_270M_250K.pt" + + def __init__( + self, + variation_degrees, + model_path=None, + batch_size=2000, + timestep_respacing="100", + use_data_parallel=True, + ): + """The "Class-conditional ImageNet-64 model (270M parameters, trained for 250K iterations)" model from the + Improved Diffusion paper. + + :param variation_degrees: The variation degrees utilized at each PE iteration + :type variation_degrees: list[int] + :param model_path: The path of the model checkpoint. If not provided, the checkpoint will be downloaded from + the `CHECKPOINT_URL` + :type model_path: str + :param batch_size: The batch size for image generation, defaults to 2000 + :type batch_size: int, optional + :param timestep_respacing: The step configuration for image generation, defaults to "100" + :type timestep_respacing: str, optional + :param use_data_parallel: Whether to use data parallel during image generation, defaults to True + :type use_data_parallel: bool, optional + """ + if model_path is None or not os.path.exists(model_path): + model_path = self._download_checkpoint(model_path) + super().__init__( + variation_degrees=variation_degrees, + model_path=model_path, + model_image_size=64, + num_channels=192, + num_res_blocks=3, + learn_sigma=True, + class_cond=True, + use_checkpoint=False, + attention_resolutions="16,8", + num_heads=4, + num_heads_upsample=-1, + use_scale_shift_norm=True, + dropout=0.0, + diffusion_steps=4000, + sigma_small=False, + noise_schedule="cosine", + use_kl=False, + predict_xstart=False, + rescale_timesteps=False, + rescale_learned_sigmas=False, + timestep_respacing=timestep_respacing, + batch_size=batch_size, + use_ddim=True, + clip_denoised=True, + use_data_parallel=use_data_parallel, + ) + + def _download_checkpoint(self, model_path): + execution_logger.info(f"Downloading ImprovedDiffusion checkpoint from {self.CHECKPOINT_URL}") + if model_path is None: + model_path = tempfile.mktemp(suffix=".pt") + download(url=self.CHECKPOINT_URL, fname=model_path) + execution_logger.info(f"Finished downloading ImprovedDiffusion checkpoint to {model_path}") + return model_path diff --git a/pe/api/image/improved_diffusion_lib/__init__.py b/pe/api/image/improved_diffusion_lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pe/api/image/improved_diffusion_lib/gaussian_diffusion.py b/pe/api/image/improved_diffusion_lib/gaussian_diffusion.py new file mode 100644 index 0000000..881c441 --- /dev/null +++ b/pe/api/image/improved_diffusion_lib/gaussian_diffusion.py @@ -0,0 +1,309 @@ +""" +This code contains minor edits from the original code at +https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/gaussian_diffusion.py +and +https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/script_util.py +to support sampling from the middle of the diffusion process with start_t and +start_image arguments. +""" + +import torch as th +from improved_diffusion.respace import SpacedDiffusion +from improved_diffusion.respace import space_timesteps +from improved_diffusion.gaussian_diffusion import _extract_into_tensor +from improved_diffusion import gaussian_diffusion as gd + + +class SkippedSpacedDiffusion(SpacedDiffusion): + def p_sample_loop( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + device=None, + progress=False, + start_t=0, + start_image=None, + ): + """ + Generate samples from the model. + + :param model: the model module. + :param shape: the shape of the samples, (N, C, H, W). + :param noise: if specified, the noise from the encoder to sample. + Should be of the same shape as `shape`. + :param clip_denoised: if True, clip x_start predictions to [-1, 1]. + :param denoised_fn: if not None, a function which applies to the + x_start prediction before it is used to sample. + :param model_kwargs: if not None, a dict of extra keyword arguments to + pass to the model. This can be used for conditioning. + :param device: if specified, the device to create the samples on. + If not specified, use a model parameter's device. + :param progress: if True, show a tqdm progress bar. + :return: a non-differentiable batch of samples. + """ + final = None + for sample in self.p_sample_loop_progressive( + model, + shape, + noise=noise, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + device=device, + progress=progress, + start_t=start_t, + start_image=start_image, + ): + final = sample + return final["sample"] + + def p_sample_loop_progressive( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + device=None, + progress=False, + start_t=0, + start_image=None, + ): + """ + Generate samples from the model and yield intermediate samples from + each timestep of diffusion. + + Arguments are the same as p_sample_loop(). + Returns a generator over dicts, where each dict is the return value of + p_sample(). + """ + if device is None: + device = next(model.parameters()).device + assert isinstance(shape, (tuple, list)) + if noise is not None: + img = noise + else: + img = th.randn(*shape, device=device) + indices = list(range(self.num_timesteps))[::-1] + indices = indices[start_t:] + if start_image is not None: + t_batch = th.tensor([indices[0]] * img.shape[0], device=device) + img = self.q_sample(start_image, t=t_batch, noise=img) + if progress: + # Lazy import so that we don't depend on tqdm. + from tqdm.auto import tqdm + + indices = tqdm(indices) + + for i in indices: + t = th.tensor([i] * shape[0], device=device) + with th.no_grad(): + out = self.p_sample( + model, + img, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + ) + yield out + img = out["sample"] + + def ddim_sample( + self, + model, + x, + t, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + eta=0.0, + ): + """ + Sample x_{t-1} from the model using DDIM. + + Same usage as p_sample(). + """ + out = self.p_mean_variance( + model, + x, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + ) + # Usually our model outputs epsilon, but we re-derive it + # in case we used x_start or x_prev prediction. + eps = self._predict_eps_from_xstart(x, t, out["pred_xstart"]) + alpha_bar = _extract_into_tensor(self.alphas_cumprod, t, x.shape) + alpha_bar_prev = _extract_into_tensor(self.alphas_cumprod_prev, t, x.shape) + sigma = eta * th.sqrt((1 - alpha_bar_prev) / (1 - alpha_bar)) * th.sqrt(1 - alpha_bar / alpha_bar_prev) + # Equation 12. + noise = th.randn_like(x) + mean_pred = out["pred_xstart"] * th.sqrt(alpha_bar_prev) + th.sqrt(1 - alpha_bar_prev - sigma**2) * eps + nonzero_mask = (t != 0).float().view(-1, *([1] * (len(x.shape) - 1))) # no noise when t == 0 + sample = mean_pred + nonzero_mask * sigma * noise + return {"sample": sample, "pred_xstart": out["pred_xstart"]} + + def ddim_reverse_sample( + self, + model, + x, + t, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + eta=0.0, + ): + """ + Sample x_{t+1} from the model using DDIM reverse ODE. + """ + assert eta == 0.0, "Reverse ODE only for deterministic path" + out = self.p_mean_variance( + model, + x, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + ) + # Usually our model outputs epsilon, but we re-derive it + # in case we used x_start or x_prev prediction. + eps = ( + _extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x.shape) * x - out["pred_xstart"] + ) / _extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x.shape) + alpha_bar_next = _extract_into_tensor(self.alphas_cumprod_next, t, x.shape) + + # Equation 12. reversed + mean_pred = out["pred_xstart"] * th.sqrt(alpha_bar_next) + th.sqrt(1 - alpha_bar_next) * eps + + return {"sample": mean_pred, "pred_xstart": out["pred_xstart"]} + + def ddim_sample_loop( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + device=None, + progress=False, + eta=0.0, + start_t=0, + start_image=None, + ): + """ + Generate samples from the model using DDIM. + + Same usage as p_sample_loop(). + """ + final = None + for sample in self.ddim_sample_loop_progressive( + model, + shape, + noise=noise, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + device=device, + progress=progress, + eta=eta, + start_t=start_t, + start_image=start_image, + ): + final = sample + return final["sample"] + + def ddim_sample_loop_progressive( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + device=None, + progress=False, + eta=0.0, + start_t=0, + start_image=None, + ): + """ + Use DDIM to sample from the model and yield intermediate samples from + each timestep of DDIM. + + Same usage as p_sample_loop_progressive(). + """ + if device is None: + device = next(model.parameters()).device + assert isinstance(shape, (tuple, list)) + if noise is not None: + img = noise + else: + img = th.randn(*shape, device=device) + indices = list(range(self.num_timesteps))[::-1] + indices = indices[start_t:] + if start_image is not None: + t_batch = th.tensor([indices[0]] * img.shape[0], device=device) + img = self.q_sample(start_image, t=t_batch, noise=img) + if progress: + # Lazy import so that we don't depend on tqdm. + from tqdm.auto import tqdm + + indices = tqdm(indices) + + for i in indices: + t = th.tensor([i] * shape[0], device=device) + with th.no_grad(): + out = self.ddim_sample( + model, + img, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + eta=eta, + ) + yield out + img = out["sample"] + + +def create_gaussian_diffusion( + *, + steps=1000, + learn_sigma=False, + sigma_small=False, + noise_schedule="linear", + use_kl=False, + predict_xstart=False, + rescale_timesteps=False, + rescale_learned_sigmas=False, + timestep_respacing="", +): + betas = gd.get_named_beta_schedule(noise_schedule, steps) + if use_kl: + loss_type = gd.LossType.RESCALED_KL + elif rescale_learned_sigmas: + loss_type = gd.LossType.RESCALED_MSE + else: + loss_type = gd.LossType.MSE + if not timestep_respacing: + timestep_respacing = [steps] + return SkippedSpacedDiffusion( + use_timesteps=space_timesteps(steps, timestep_respacing), + betas=betas, + model_mean_type=(gd.ModelMeanType.EPSILON if not predict_xstart else gd.ModelMeanType.START_X), + model_var_type=( + (gd.ModelVarType.FIXED_LARGE if not sigma_small else gd.ModelVarType.FIXED_SMALL) + if not learn_sigma + else gd.ModelVarType.LEARNED_RANGE + ), + loss_type=loss_type, + rescale_timesteps=rescale_timesteps, + ) diff --git a/pe/api/image/improved_diffusion_lib/unet.py b/pe/api/image/improved_diffusion_lib/unet.py new file mode 100644 index 0000000..8b5bfec --- /dev/null +++ b/pe/api/image/improved_diffusion_lib/unet.py @@ -0,0 +1,60 @@ +""" +This code contains minor edits from the original code at +https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/unet.py +and +https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/script_util.py +to avoid calling self.input_blocks.parameters() in the original code, which is +not supported by DataParallel. +""" + +import torch +from improved_diffusion.unet import UNetModel +from improved_diffusion.script_util import NUM_CLASSES + + +class FP32UNetModel(UNetModel): + @property + def inner_dtype(self): + return torch.float32 + + +def create_model( + image_size, + num_channels, + num_res_blocks, + learn_sigma, + class_cond, + use_checkpoint, + attention_resolutions, + num_heads, + num_heads_upsample, + use_scale_shift_norm, + dropout, +): + if image_size == 256: + channel_mult = (1, 1, 2, 2, 4, 4) + elif image_size == 64: + channel_mult = (1, 2, 3, 4) + elif image_size == 32: + channel_mult = (1, 2, 2, 2) + else: + raise ValueError(f"unsupported image size: {image_size}") + + attention_ds = [] + for res in attention_resolutions.split(","): + attention_ds.append(image_size // int(res)) + + return FP32UNetModel( + in_channels=3, + model_channels=num_channels, + out_channels=(3 if not learn_sigma else 6), + num_res_blocks=num_res_blocks, + attention_resolutions=tuple(attention_ds), + dropout=dropout, + channel_mult=channel_mult, + num_classes=(NUM_CLASSES if class_cond else None), + use_checkpoint=use_checkpoint, + num_heads=num_heads, + num_heads_upsample=num_heads_upsample, + use_scale_shift_norm=use_scale_shift_norm, + ) diff --git a/pe/api/image/stable_diffusion_api.py b/pe/api/image/stable_diffusion_api.py new file mode 100644 index 0000000..4450383 --- /dev/null +++ b/pe/api/image/stable_diffusion_api.py @@ -0,0 +1,206 @@ +import torch +import numpy as np +import pandas as pd +from diffusers import StableDiffusionPipeline +from diffusers import StableDiffusionImg2ImgPipeline +import json +from tqdm import tqdm + +from pe.api import API +from pe.logging import execution_logger +from pe.data import Data +from pe.constant.data import IMAGE_DATA_COLUMN_NAME +from pe.constant.data import IMAGE_PROMPT_COLUMN_NAME +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.api.util import ConstantList + + +def _to_constant_list_if_needed(value): + if not isinstance(value, list): + value = ConstantList(value) + return value + + +def _round_to_uint8(image): + return np.around(np.clip(image * 255, a_min=0, a_max=255)).astype(np.uint8) + + +class StableDiffusion(API): + """The API that uses the Stable Diffusion model to generate synthetic data.""" + + def __init__( + self, + prompt, + variation_degrees, + width=512, + height=512, + random_api_checkpoint="CompVis/stable-diffusion-v1-4", + random_api_guidance_scale=7.5, + random_api_num_inference_steps=50, + random_api_batch_size=10, + variation_api_checkpoint="CompVis/stable-diffusion-v1-4", + variation_api_guidance_scale=7.5, + variation_api_num_inference_steps=50, + variation_api_batch_size=10, + ): + """Constructor. + + :param prompt: The prompt used for each label name. It can be either a string or a dictionary. If it is a + string, it should be the path to a JSON file that contains the prompt for each label name. If it is a + dictionary, it should be a dictionary that maps each label name to its prompt + :type prompt: str or dict + :param variation_degrees: The variation degrees utilized at each PE iteration. If a single float is provided, + the same variation degree will be used for all iterations. + :type variation_degrees: float or list[float] + :param width: The width of the generated images, defaults to 512 + :type width: int, optional + :param height: The height of the generated images, defaults to 512 + :type height: int, optional + :param random_api_checkpoint: The checkpoint of the random API, defaults to "CompVis/stable-diffusion-v1-4" + :type random_api_checkpoint: str, optional + :param random_api_guidance_scale: The guidance scale of the random API, defaults to 7.5 + :type random_api_guidance_scale: float, optional + :param random_api_num_inference_steps: The number of inference steps of the random API, defaults to 50 + :type random_api_num_inference_steps: int, optional + :param random_api_batch_size: The batch size of the random API, defaults to 10 + :type random_api_batch_size: int, optional + :param variation_api_checkpoint: The checkpoint of the variation API, defaults to + "CompVis/stable-diffusion-v1-4" + :type variation_api_checkpoint: str, optional + :param variation_api_guidance_scale: The guidance scale of the variation API utilized at each PE iteration. If + a single float is provided, the same guidance scale will be used for all iterations. Defaults to 7.5 + :type variation_api_guidance_scale: float or list[float], optional + :param variation_api_num_inference_steps: The number of inference steps of the variation API utilized at each + PE iteration. If a single int is provided, the same number of inference steps will be used for all + iterations. Defaults to 50 + :type variation_api_num_inference_steps: int or list[int], optional + :param variation_api_batch_size: The batch size of the variation API, defaults to 10 + :type variation_api_batch_size: int, optional + :raises ValueError: If the prompt is neither a string nor a dictionary + """ + super().__init__() + self._device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + + if isinstance(prompt, str): + with open(prompt, "r") as f: + self._prompt = json.load(f) + elif isinstance(prompt, dict): + self._prompt = prompt + else: + raise ValueError("Prompt must be either a string or a dictionary") + + self._width = width + self._height = height + + self._random_api_checkpoint = random_api_checkpoint + self._random_api_guidance_scale = random_api_guidance_scale + self._random_api_num_inference_steps = random_api_num_inference_steps + self._random_api_batch_size = random_api_batch_size + + self._variation_api_checkpoint = variation_api_checkpoint + self._variation_api_guidance_scale = _to_constant_list_if_needed(variation_api_guidance_scale) + self._variation_api_num_inference_steps = _to_constant_list_if_needed(variation_api_num_inference_steps) + self._variation_api_batch_size = variation_api_batch_size + + self._variation_degrees = _to_constant_list_if_needed(variation_degrees) + + self._random_api_pipe = StableDiffusionPipeline.from_pretrained( + self._random_api_checkpoint, torch_dtype=torch.float16 + ) + self._random_api_pipe.safety_checker = None + self._random_api_pipe = self._random_api_pipe.to(self._device) + + self._variation_api_pipe = StableDiffusionImg2ImgPipeline.from_pretrained( + self._variation_api_checkpoint, torch_dtype=torch.float16 + ) + self._variation_api_pipe.safety_checker = None + self._variation_api_pipe = self._variation_api_pipe.to(self._device) + + def random_api(self, label_name, num_samples): + """Generating random synthetic data. + + :param label_name: The name of the label, not utilized in this API + :type label_name: str + :param num_samples: The number of random samples to generate + :type num_samples: int + :return: The data object of the generated synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + execution_logger.info(f"RANDOM API: creating {num_samples} samples for label {label_name}") + + prompt = self._prompt[label_name] + max_batch_size = self._random_api_batch_size + images = [] + num_iterations = int(np.ceil(float(num_samples) / max_batch_size)) + for iteration in tqdm(range(num_iterations)): + batch_size = min(max_batch_size, num_samples - iteration * max_batch_size) + images.append( + self._random_api_pipe( + prompt=prompt, + width=self._width, + height=self._height, + num_inference_steps=self._random_api_num_inference_steps, + guidance_scale=self._random_api_guidance_scale, + num_images_per_prompt=batch_size, + output_type="np", + ).images + ) + images = _round_to_uint8(np.concatenate(images, axis=0)) + torch.cuda.empty_cache() + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: list(images), + IMAGE_PROMPT_COLUMN_NAME: prompt, + } + ) + execution_logger.info(f"RANDOM API: finished creating {num_samples} samples for label {label_name}") + return Data(data_frame=data_frame) + + def variation_api(self, syn_data): + """Generating variations of the synthetic data. + + :param syn_data: The data object of the synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: The data object of the variation of the input synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + execution_logger.info(f"VARIATION API: creating variations for {len(syn_data.data_frame)} samples") + images = np.stack(syn_data.data_frame[IMAGE_DATA_COLUMN_NAME].values) + prompts = list(syn_data.data_frame[IMAGE_PROMPT_COLUMN_NAME].values) + iteration = getattr(syn_data.metadata, "iteration", -1) + variation_degree = self._variation_degrees[iteration + 1] + guidance_scale = self._variation_api_guidance_scale[iteration + 1] + num_inference_steps = self._variation_api_num_inference_steps[iteration + 1] + + images = images.astype(np.float32) / 127.5 - 1.0 + images = np.transpose(images, (0, 3, 1, 2)) + images = torch.Tensor(images).to(self._device) + max_batch_size = self._variation_api_batch_size + + variations = [] + num_iterations = int(np.ceil(float(images.shape[0]) / max_batch_size)) + for iteration in tqdm(range(num_iterations)): + variations.append( + self._variation_api_pipe( + prompt=prompts[iteration * max_batch_size : (iteration + 1) * max_batch_size], + image=images[iteration * max_batch_size : (iteration + 1) * max_batch_size], + num_inference_steps=num_inference_steps, + strength=variation_degree, + guidance_scale=guidance_scale, + num_images_per_prompt=1, + output_type="np", + ).images + ) + variations = _round_to_uint8(np.concatenate(variations, axis=0)) + + torch.cuda.empty_cache() + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: list(variations), + IMAGE_PROMPT_COLUMN_NAME: prompts, + } + ) + if LABEL_ID_COLUMN_NAME in syn_data.data_frame.columns: + data_frame[LABEL_ID_COLUMN_NAME] = syn_data.data_frame[LABEL_ID_COLUMN_NAME].values + execution_logger.info(f"VARIATION API: finished creating variations for {len(syn_data.data_frame)} samples") + return Data(data_frame=data_frame, metadata=syn_data.metadata) diff --git a/pe/api/util.py b/pe/api/util.py new file mode 100644 index 0000000..78bfcff --- /dev/null +++ b/pe/api/util.py @@ -0,0 +1,6 @@ +class ConstantList: + def __init__(self, value): + self._value = value + + def __getitem__(self, index): + return self._value diff --git a/pe/callback/__init__.py b/pe/callback/__init__.py new file mode 100644 index 0000000..acdc86e --- /dev/null +++ b/pe/callback/__init__.py @@ -0,0 +1,4 @@ +from .common.save_checkpoints import SaveCheckpoints +from .common.compute_fid import ComputeFID +from .image.sample_images import SampleImages +from .image.save_all_images import SaveAllImages diff --git a/pe/callback/callback.py b/pe/callback/callback.py new file mode 100644 index 0000000..f134fab --- /dev/null +++ b/pe/callback/callback.py @@ -0,0 +1,16 @@ +from abc import ABC, abstractmethod + + +class Callback(ABC): + """The abstract class that defines the callback for the synthetic data generation. These callbacks can be + configured to be called after each PE iteration. + """ + + @abstractmethod + def __call__(self, syn_data): + """This function is called after each PE iteration. + + :param syn_data: The :py:class:`pe.data.data.Data` object of the synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + """ + ... diff --git a/pe/callback/common/__init__.py b/pe/callback/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pe/callback/common/compute_fid.py b/pe/callback/common/compute_fid.py new file mode 100644 index 0000000..8d3dd6d --- /dev/null +++ b/pe/callback/common/compute_fid.py @@ -0,0 +1,52 @@ +import numpy as np +import cleanfid.fid + +from pe.callback.callback import Callback +from pe.metric_item import FloatMetricItem +from pe.logging import execution_logger + + +class ComputeFID(Callback): + """The callback that computes the Frechet Inception Distance (FID) between the private and synthetic data.""" + + def __init__(self, priv_data, embedding): + """Constructor. + + :param priv_data: The private data + :type priv_data: :py:class:`pe.data.data.Data` + :param embedding: The embedding to compute the FID + :type embedding: :py:class:`pe.embedding.embedding.Embedding` + """ + self._priv_data = priv_data + self._embedding = embedding + + self._priv_data = self._embedding.compute_embedding(self._priv_data) + priv_embedding = np.stack(self._priv_data.data_frame[self._embedding.column_name].values, axis=0).astype( + np.float32 + ) + self._real_mu = np.mean(priv_embedding, axis=0) + self._real_sigma = np.cov(priv_embedding, rowvar=False) + + def __call__(self, syn_data): + """This function is called after each PE iteration that computes the FID between the private and synthetic + data. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: The FID between the private and synthetic data + :rtype: list[:py:class:`pe.metric_item.FloatMetricItem`] + """ + execution_logger.info(f"Computing FID ({type(self._embedding).__name__})") + syn_data = self._embedding.compute_embedding(syn_data) + syn_embedding = np.stack(syn_data.data_frame[self._embedding.column_name].values, axis=0).astype(np.float32) + syn_mu = np.mean(syn_embedding, axis=0) + syn_sigma = np.cov(syn_embedding, rowvar=False) + fid = cleanfid.fid.frechet_distance( + mu1=self._real_mu, + sigma1=self._real_sigma, + mu2=syn_mu, + sigma2=syn_sigma, + ) + metric_item = FloatMetricItem(name=f"fid_{type(self._embedding).__name__}", value=fid) + execution_logger.info(f"Finished computing FID ({type(self._embedding).__name__})") + return [metric_item] diff --git a/pe/callback/common/save_checkpoints.py b/pe/callback/common/save_checkpoints.py new file mode 100644 index 0000000..9a0de86 --- /dev/null +++ b/pe/callback/common/save_checkpoints.py @@ -0,0 +1,46 @@ +import os + +from pe.callback.callback import Callback + + +class SaveCheckpoints(Callback): + """The callback that saves checkpoints of the synthetic data.""" + + def __init__( + self, + output_folder, + iteration_format="09d", + ): + """Constructor. + + :param output_folder: The output folder that will be used to save the checkpoints + :type output_folder: str + :param iteration_format: The format of the iteration number, defaults to "09d" + :type iteration_format: str, optional + """ + self._output_folder = output_folder + self._iteration_format = iteration_format + + def __call__(self, syn_data): + """This function is called after each PE iteration that saves checkpoints of the synthetic data. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + """ + syn_data.save_checkpoint(self._get_checkpoint_path(syn_data.metadata.iteration)) + + def _get_checkpoint_path(self, iteration): + """Get the checkpoint path. + + :param iteration: The PE iteration number + :type iteration: int + :return: The checkpoint path + :rtype: str + """ + os.makedirs(self._output_folder, exist_ok=True) + iteration_string = format(iteration, self._iteration_format) + checkpoint_path = os.path.join( + self._output_folder, + iteration_string, + ) + return checkpoint_path diff --git a/pe/callback/image/__init__.py b/pe/callback/image/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pe/callback/image/sample_images.py b/pe/callback/image/sample_images.py new file mode 100644 index 0000000..8d60929 --- /dev/null +++ b/pe/callback/image/sample_images.py @@ -0,0 +1,44 @@ +import numpy as np + +from pe.callback.callback import Callback +from pe.constant.data import IMAGE_DATA_COLUMN_NAME +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.metric_item import ImageListMetricItem + + +class SampleImages(Callback): + """The callback that samples images from the synthetic data.""" + + def __init__(self, num_images_per_class=10): + """Constructor. + + :param num_images_per_class: number of images to sample per class, defaults to 10 + :type num_images_per_class: int, optional + """ + self._num_images_per_class = num_images_per_class + + def __call__(self, syn_data): + """This function is called after each PE iteration that samples images from the synthetic data. + + :param syn_data: The :py:class:`pe.data.data.Data` object of the synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: A metric item with the list of sampled images + :rtype: list[:py:class:`pe.metric_item.ImageListMetricItem`] + """ + all_image_list = [] + num_classes = len(syn_data.metadata.label_names) + for class_id in range(num_classes): + image_list = syn_data.data_frame[syn_data.data_frame[LABEL_ID_COLUMN_NAME] == class_id][ + IMAGE_DATA_COLUMN_NAME + ] + image_list = image_list.sample(min(self._num_images_per_class, len(image_list))) + all_image_list.extend(image_list) + assert len(image_list) > 0 + if len(image_list) < self._num_images_per_class: + all_image_list.extend(np.zeros_like(image_list[0]) * (self._num_images_per_class - len(image_list))) + metric_item = ImageListMetricItem( + name="image_sample", + value=all_image_list, + num_images_per_row=None if num_classes == 1 else self._num_images_per_class, + ) + return [metric_item] diff --git a/pe/callback/image/save_all_images.py b/pe/callback/image/save_all_images.py new file mode 100644 index 0000000..6429339 --- /dev/null +++ b/pe/callback/image/save_all_images.py @@ -0,0 +1,70 @@ +import imageio +import os +from tqdm import tqdm + +from pe.callback.callback import Callback +from pe.constant.data import IMAGE_DATA_COLUMN_NAME +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.logging import execution_logger + + +class SaveAllImages(Callback): + """The callback that saves all images.""" + + def __init__( + self, + output_folder, + path_format="{iteration:09d}/{label_id}_{label_name}/{index}.png", + tqdm_enabled=True, + ): + """Constructor. + + :param output_folder: The output folder that will be used to save the images + :type output_folder: str + :param path_format: The format of the image paths, defaults to + "{iteration:09d}/{label_id}_{label_name}/{index}.png" + :type path_format: str, optional + :param tqdm_enabled: Whether to show tqdm progress bar when saving the images, defaults to True + :type tqdm_enabled: bool, optional + """ + self._output_folder = output_folder + self._path_format = path_format + self._tqdm_enabled = tqdm_enabled + + def _save_image(self, image, label_name, label_id, index, iteration): + """A helper function that saves an image.""" + path = os.path.join( + self._output_folder, + self._path_format.format( + iteration=iteration, + label_id=label_id, + label_name=label_name, + index=index, + ), + ) + os.makedirs(os.path.dirname(path), exist_ok=True) + imageio.imsave(path, image) + + def __call__(self, syn_data): + """This function is called after each PE iteration that saves all images. + + :param syn_data: The :py:class:`pe.data.data.Data` object of the synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + """ + execution_logger.info("Saving all images") + iterator = range(len(syn_data.data_frame)) + if self._tqdm_enabled: + iterator = tqdm(iterator) + for i in iterator: + image = syn_data.data_frame[IMAGE_DATA_COLUMN_NAME][i] + label_id = int(syn_data.data_frame[LABEL_ID_COLUMN_NAME][i]) + label_name = syn_data.metadata.label_names[label_id] + index = syn_data.data_frame.index[i] + self._save_image( + image=image, + label_name=label_name, + label_id=label_id, + index=index, + iteration=syn_data.metadata.iteration, + ) + execution_logger.info("Finished saving all images") diff --git a/pe/constant/__init__.py b/pe/constant/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pe/constant/data.py b/pe/constant/data.py new file mode 100644 index 0000000..0824790 --- /dev/null +++ b/pe/constant/data.py @@ -0,0 +1,29 @@ +#: The column name of the label ID +LABEL_ID_COLUMN_NAME = "PE.LABEL_ID" + +#: The column name of the clean histogram +CLEAN_HISTOGRAM_COLUMN_NAME = "PE.CLEAN_HISTOGRAM" +#: The column name of the DP histogram +DP_HISTOGRAM_COLUMN_NAME = "PE.DP_HISTOGRAM" +#: The column name of the post-processed (e.g., clipped) DP histogram +POST_PROCESSED_DP_HISTOGRAM_COLUMN_NAME = "PE.POST_PROCESSED_DP_HISTOGRAM" + +#: The column name of the embedding +EMBEDDING_COLUMN_NAME = "PE.EMBEDDING" +#: The column name of the lookahead embedding +LOOKAHEAD_EMBEDDING_COLUMN_NAME = "PE.LOOKAHEAD_EMBEDDING" + +#: The column name of the index of synthetic sample from the previous iteration that generates the current sample +PARENT_SYN_DATA_INDEX_COLUMN_NAME = "PE.PARENT_SYN_DATA_INDEX" +#: The column name of the flag that indicates whether the sample is from the last iteration +FROM_LAST_FLAG_COLUMN_NAME = "PE.FROM_LAST_FLAG" + +#: The column name of the image data +IMAGE_DATA_COLUMN_NAME = "PE.IMAGE" +#: The column name of the image label that is used for the model to generate the image +IMAGE_MODEL_LABEL_COLUMN_NAME = "PE.IMAGE_MODEL_LABEL" +#: The column name of the prompt for the image +IMAGE_PROMPT_COLUMN_NAME = "PE.IMAGE_PROMPT" + +#: The column name of the nearest neighbors voting IDs +HISTOGRAM_NEAREST_NEIGHBORS_VOTING_IDS_COLUMN_NAME = "PE.HISTOGRAM.NEAREST_NEIGHBORS.VOTING_IDS" diff --git a/pe/data/__init__.py b/pe/data/__init__.py new file mode 100644 index 0000000..02a0feb --- /dev/null +++ b/pe/data/__init__.py @@ -0,0 +1 @@ +from .data import Data diff --git a/pe/data/data.py b/pe/data/data.py new file mode 100644 index 0000000..1d2e854 --- /dev/null +++ b/pe/data/data.py @@ -0,0 +1,139 @@ +import os +from omegaconf import OmegaConf +import pandas as pd +from pe.constant.data import LABEL_ID_COLUMN_NAME + + +class Data: + """The class that holds the private data or synthetic data from PE.""" + + def __init__(self, data_frame=None, metadata={}): + """Constructor. + + :param data_frame: A pandas dataframe that holds the data, defaults to None + :type data_frame: :py:class:`pandas.DataFrame`, optional + :param metadata: the metadata of the data, defaults to {} + :type metadata: dict, optional + """ + self.data_frame = data_frame + self.metadata = OmegaConf.create(metadata) + self._data_frame_file_name = "data_frame.pkl" + self._metadata_file_name = "metadata.yaml" + + def __str__(self): + return f"Metadata:\n{self.metadata}\nData frame:\n{self.data_frame}" + + def save_checkpoint(self, path): + """Save the data to a checkpoint. + + :param path: The folder to save the checkpoint + :type path: str + :raises ValueError: If the path is None + :raises ValueError: If the data frame is empty + """ + if path is None: + raise ValueError("Path is None") + if self.data_frame is None: + raise ValueError("Data frame is empty") + os.makedirs(path, exist_ok=True) + self.data_frame.to_pickle(os.path.join(path, self._data_frame_file_name)) + with open(os.path.join(path, self._metadata_file_name), "w") as file: + file.write(OmegaConf.to_yaml(self.metadata)) + + def load_checkpoint(self, path): + """Load data from a checkpoint + + :param path: The folder that contains the checkpoint + :type path: str + :return: Whether the checkpoint is loaded successfully + :rtype: bool + """ + data_frame_path = os.path.join(path, self._data_frame_file_name) + metadata_path = os.path.join(path, self._metadata_file_name) + if not os.path.exists(data_frame_path) or not os.path.exists(metadata_path): + return False + self.data_frame = pd.read_pickle(data_frame_path) + with open(metadata_path, "r") as file: + self.metadata = OmegaConf.create(file.read()) + return True + + def filter_label_id(self, label_id): + """Filter the data frame according to a label id + + :param label_id: The label id that is used to filter the data frame + :type label_id: int + :return: :py:class:`pe.data.data.Data` object with the filtered data frame + :rtype: :py:class:`pe.data.data.Data` + """ + return Data( + data_frame=self.data_frame[self.data_frame[LABEL_ID_COLUMN_NAME] == label_id], + metadata=self.metadata, + ) + + def set_label_id(self, label_id): + """Set the label id for the data frame + + :param label_id: The label id to set + :type label_id: int + """ + self.data_frame[LABEL_ID_COLUMN_NAME] = label_id + + def truncate(self, num_samples): + """Truncate the data frame to a certain number of samples + + :param num_samples: The number of samples to truncate + :type num_samples: int + :return: A new :py:class:`pe.data.data.Data` object with the truncated data frame + :rtype: :py:class:`pe.data.data.Data` + """ + return Data(data_frame=self.data_frame[:num_samples], metadata=self.metadata) + + def random_truncate(self, num_samples): + """Randomly truncate the data frame to a certain number of samples + + :param num_samples: The number of samples to randomly truncate + :type num_samples: int + :return: A new :py:class:`pe.data.data.Data` object with the randomly truncated data frame + :rtype: :py:class:`pe.data.data.Data` + """ + data_frame = self.data_frame.sample(n=num_samples) + return Data(data_frame=data_frame, metadata=self.metadata) + + def merge(self, data): + """Merge the data object with another data object + + :param data: The data object to merge + :type data: :py:class:`pe.data.data.Data` + :raises ValueError: If the metadata of `data` is not the same as the metadata of the current object + :return: The merged data object + :rtype: :py:class:`pe.data.data.Data` + """ + if self.metadata != data.metadata: + raise ValueError("Metadata must be the same") + cols_to_use = data.data_frame.columns.difference(self.data_frame.columns) + if len(cols_to_use) == 0: + return self + data_frame = self.data_frame.join(data.data_frame[cols_to_use]) + return Data(data_frame=data_frame, metadata=self.metadata) + + @classmethod + def concat(cls, data_list, metadata=None): + """Concatenate the data frames of a list of data objects + + :param data_list: The list of data objects to concatenate + :type data_list: list[:py:class:`pe.data.data.Data`] + :param metadata: The metadata of the concatenated data. When None, the metadata of the list of data objects + must be the same and will be used. Defaults to None + :type metadata: dict, optional + :raises ValueError: If the metadata of the data objects are not the same + :return: The concatenated data object + :rtype: :py:class:`pe.data.data.Data` + """ + data_frame_list = [data.data_frame for data in data_list] + if metadata is None: + metadata_list = [data.metadata for data in data_list] + # Check that all metadata are the same. + if len(set(metadata_list)) != 1: + raise ValueError("Metadata must be the same") + metadata = metadata_list[0] + return Data(data_frame=pd.concat(data_frame_list), metadata=metadata) diff --git a/pe/data/image/__init__.py b/pe/data/image/__init__.py new file mode 100644 index 0000000..fc1043d --- /dev/null +++ b/pe/data/image/__init__.py @@ -0,0 +1,4 @@ +from .image import load_image_folder +from .cifar10 import Cifar10 +from .camelyon17 import Camelyon17 +from .cat import Cat diff --git a/pe/data/image/camelyon17.py b/pe/data/image/camelyon17.py new file mode 100644 index 0000000..acfc37a --- /dev/null +++ b/pe/data/image/camelyon17.py @@ -0,0 +1,50 @@ +import pandas as pd +from wilds import get_dataset +from tqdm import tqdm +import numpy as np +import torchvision.transforms as T + +from pe.data import Data +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.constant.data import IMAGE_DATA_COLUMN_NAME + +CAMELYON17_LABEL_NAMES = [ + "no_tumor", + "tumor", +] + + +class Camelyon17(Data): + """The Camelyon17 dataset.""" + + def __init__(self, split="train", root_dir="data", res=64): + """Constructor. + + :param split: The split of the dataset. It should be either "train", "val", or "test", defaults to "train" + :type split: str, optional + :param root_dir: The root directory to save the dataset, defaults to "data" + :type root_dir: str, optional + :param res: The resolution of the images, defaults to 64 + :type res: int, optional + :raises ValueError: If the split is invalid + """ + if split not in ["train", "val", "test"]: + raise ValueError(f"Invalid split: {split}") + dataset = get_dataset(dataset="camelyon17", download=True, root_dir=root_dir) + data = dataset.get_subset(split) + transform = T.Resize(res) + + images = [] + labels = [] + for i in tqdm(range(len(data))): + image, label, _ = data[i] + images.append(np.array(transform(image))) + labels.append(label.item()) + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: images, + LABEL_ID_COLUMN_NAME: labels, + } + ) + metadata = {"label_names": CAMELYON17_LABEL_NAMES} + super().__init__(data_frame=data_frame, metadata=metadata) diff --git a/pe/data/image/cat.py b/pe/data/image/cat.py new file mode 100644 index 0000000..1c0730b --- /dev/null +++ b/pe/data/image/cat.py @@ -0,0 +1,73 @@ +import pandas as pd +import os +from tqdm import tqdm +import numpy as np +import zipfile +from PIL import Image +import torchvision.transforms as T +from collections import defaultdict + +from pe.data import Data +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.constant.data import IMAGE_DATA_COLUMN_NAME +from pe.util import download + +CAT_LABEL_NAMES = [ + "cookie", + "doudou", +] + + +class Cat(Data): + """The Cat dataset.""" + + #: The URL of the dataset + URL = "https://www.kaggle.com/api/v1/datasets/download/fjxmlzn/cat-cookie-doudou" + + def __init__(self, root_dir="data", res=512): + """Constructor. + + :param root_dir: The root directory to save the dataset, defaults to "data" + :type root_dir: str, optional + :param res: The resolution of the images, defaults to 512 + :type res: int, optional + """ + self._zip_path = os.path.join(root_dir, "cat-cookie-doudou.zip") + self._download() + data = self._read_data() + transform = T.Resize(res) + + images = [] + labels = [] + for label, sub_images in data.items(): + for image in tqdm(sub_images, desc=f"Processing {label} images"): + image = Image.fromarray(image) + image = transform(image) + image = np.array(image) + images.append(image) + labels.append(CAT_LABEL_NAMES.index(label)) + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: images, + LABEL_ID_COLUMN_NAME: labels, + } + ) + metadata = {"label_names": CAT_LABEL_NAMES} + super().__init__(data_frame=data_frame, metadata=metadata) + + def _download(self): + """Download the dataset if it does not exist.""" + if not os.path.exists(self._zip_path): + os.makedirs(os.path.dirname(self._zip_path), exist_ok=True) + download(url=self.URL, fname=self._zip_path) + + def _read_data(self): + """Read the data from the zip file.""" + data = defaultdict(list) + with zipfile.ZipFile(self._zip_path) as z: + for name in tqdm(z.namelist(), desc="Reading zip file"): + with z.open(name) as f: + image = Image.open(f) + label = name.split("/")[0] + data[label].append(np.array(image)) + return data diff --git a/pe/data/image/cifar10.py b/pe/data/image/cifar10.py new file mode 100644 index 0000000..c54eaef --- /dev/null +++ b/pe/data/image/cifar10.py @@ -0,0 +1,45 @@ +import torchvision +import tempfile +import pandas as pd + +from pe.data import Data +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.constant.data import IMAGE_DATA_COLUMN_NAME + +CIFAR10_LABEL_NAMES = [ + "plane", + "car", + "bird", + "cat", + "deer", + "dog", + "frog", + "horse", + "ship", + "truck", +] + + +class Cifar10(Data): + """The CIFAR10 dataset.""" + + def __init__(self, split="train"): + """Constructor. + + :param split: The split of the dataset. It should be either "train" or "test", defaults to "train" + :type split: str, optional + :raises ValueError: If the split is invalid + """ + if split not in ["train", "test"]: + raise ValueError(f"Invalid split: {split}") + train = split == "train" + with tempfile.TemporaryDirectory() as tmp_dir: + dataset = torchvision.datasets.CIFAR10(root=tmp_dir, train=train, download=True) + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: list(dataset.data), + LABEL_ID_COLUMN_NAME: dataset.targets, + } + ) + metadata = {"label_names": CIFAR10_LABEL_NAMES} + super().__init__(data_frame=data_frame, metadata=metadata) diff --git a/pe/data/image/image.py b/pe/data/image/image.py new file mode 100644 index 0000000..de495a2 --- /dev/null +++ b/pe/data/image/image.py @@ -0,0 +1,125 @@ +import pandas as pd +from PIL import Image as PILImage +import blobfile as bf +from torch.utils.data import Dataset +import torchvision.transforms as T +from torch.utils.data import DataLoader +import torch +import numpy as np + +from pe.data import Data +from pe.logging import execution_logger +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.constant.data import IMAGE_DATA_COLUMN_NAME + + +def _list_image_files_recursively(data_dir): + """List all image files in a directory recursively. Adapted from + https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/image_datasets.py + """ + results = [] + for entry in sorted(bf.listdir(data_dir)): + full_path = bf.join(data_dir, entry) + ext = entry.split(".")[-1] + if "." in entry and ext.lower() in ["jpg", "jpeg", "png", "gif"]: + results.append(full_path) + elif bf.isdir(full_path): + results.extend(_list_image_files_recursively(full_path)) + return results + + +class ImageDataset(Dataset): + def __init__(self, folder, transform): + super().__init__() + self.folder = folder + self.transform = transform + + self.local_images = _list_image_files_recursively(folder) + self.local_class_names = [bf.basename(path).split("_")[0] for path in self.local_images] + self.class_names = list(sorted(set(self.local_class_names))) + self.class_name_to_id = {x: i for i, x in enumerate(self.class_names)} + self.local_classes = [self.class_name_to_id[x] for x in self.local_class_names] + + def __len__(self): + return len(self.local_images) + + def __getitem__(self, idx): + path = self.local_images[idx] + with bf.BlobFile(path, "rb") as f: + pil_image = PILImage.open(f) + pil_image.load() + + arr = self.transform(pil_image) + + label = self.local_classes[idx] + return arr, label + + +def load_image_folder(path, image_size, class_cond=True, num_images=-1, num_workers=10, batch_size=1000): + """Load a image dataset from a folder that contains image files. The folder can be nested arbitrarily. The image + file names must be in the format of "{class_name without '_'}_{suffix in any string}.ext". The "ext" can be "jpg", + "jpeg", "png", or "gif". The class names will be extracted from the file names before the first "_". If class_cond + is False, the class names will be ignored and all images will be treated as the same class with class name "None". + + :param path: The path to the root folder that contains the image files + :type path: str + :param image_size: The size of the images. Images will be resized to this size + :type image_size: int + :param class_cond: Whether to treat the loaded dataset as class conditional, defaults to True + :type class_cond: bool, optional + :param num_images: The number of images to load. If -1, load all images. Defaults to -1 + :type num_images: int, optional + :param num_workers: The number of workers to use for loading the images, defaults to 10 + :type num_workers: int, optional + :param batch_size: The batch size to use for loading the images, defaults to 1000 + :type batch_size: int, optional + :return: The loaded data + :rtype: :py:class:`pe.data.data.Data` + """ + transform = T.Compose([T.Resize(image_size), T.CenterCrop(image_size), T.ToTensor()]) + dataset = ImageDataset(folder=path, transform=transform) + loader = DataLoader( + dataset=dataset, + batch_size=batch_size, + shuffle=False, + num_workers=num_workers, + pin_memory=torch.cuda.is_available(), + drop_last=False, + ) + all_samples = [] + all_labels = [] + cnt = 0 + for batch, cond in loader: + all_samples.append(batch.cpu().numpy()) + + if class_cond: + all_labels.append(cond.cpu().numpy()) + + cnt += batch.shape[0] + + execution_logger.info(f"Loaded {cnt} samples.") + if batch.shape[0] < batch_size: + execution_logger.info("Containing incomplete batch. Please check num_images is desired.") + + if num_images > 0 and cnt >= num_images: + break + + all_samples = np.concatenate(all_samples, axis=0) + if num_images <= 0: + num_images = all_samples.shape[0] + all_samples = all_samples[:num_images] + all_samples = np.around(np.clip(all_samples * 255, a_min=0, a_max=255)).astype(np.uint8) + all_samples = np.transpose(all_samples, (0, 2, 3, 1)) + if class_cond: + all_labels = np.concatenate(all_labels, axis=0) + all_labels = all_labels[:num_images] + else: + all_labels = np.zeros(shape=all_samples.shape[0], dtype=np.int64) + data_frame = pd.DataFrame( + { + IMAGE_DATA_COLUMN_NAME: list(all_samples), + LABEL_ID_COLUMN_NAME: list(all_labels), + } + ) + metadata = {"label_names": dataset.class_names if class_cond else ["None"]} + return Data(data_frame=data_frame, metadata=metadata) diff --git a/pe/dp/__init__.py b/pe/dp/__init__.py new file mode 100644 index 0000000..5cbddc4 --- /dev/null +++ b/pe/dp/__init__.py @@ -0,0 +1,2 @@ +from .dp import DP +from .gaussian import Gaussian diff --git a/pe/dp/dp.py b/pe/dp/dp.py new file mode 100644 index 0000000..284a1ba --- /dev/null +++ b/pe/dp/dp.py @@ -0,0 +1,29 @@ +from abc import ABC, abstractmethod + + +class DP(ABC): + """The abstract class for Differential Privacy (DP) histogram mechanism.""" + + @abstractmethod + def set_epsilon_and_delta(self, num_iterations, epsilon, delta, noise_multiplier): + """Set the epsilon and delta for the DP mechanism. Either epsilon or noise_multiplier should be None. + + :param num_iterations: The number of PE iterations + :type num_iterations: int + :param epsilon: The epsilon value of DP + :type epsilon: float or None + :param delta: The delta value of DP + :type delta: float + :param noise_multiplier: The noise multiplier of the DP mechanism + :type noise_multiplier: float or None + """ + ... + + @abstractmethod + def add_noise(self, syn_data): + """Add noise to the histogram of synthetic data. + + :param syn_data: The synthetic data to add noise + :type syn_data: :py:class:`pe.data.data.Data` + """ + ... diff --git a/pe/dp/gaussian.py b/pe/dp/gaussian.py new file mode 100644 index 0000000..6dd9423 --- /dev/null +++ b/pe/dp/gaussian.py @@ -0,0 +1,172 @@ +import scipy.optimize +from scipy.optimize import root_scalar +import numpy as np + +from pe.dp import DP +from pe.logging import execution_logger +from pe.constant.data import CLEAN_HISTOGRAM_COLUMN_NAME +from pe.constant.data import DP_HISTOGRAM_COLUMN_NAME + + +def delta_Gaussian(eps, mu): + """Compute delta of Gaussian mechanism with shift mu or equivalently noise scale 1/mu. + + :param eps: The epsilon value + :type eps: float + :param mu: The mu value + :type mu: float + :return: The delta value + :rtype: float + """ + if mu == 0: + return 0 + if np.isinf(np.exp(eps)): + return 0 + return scipy.stats.norm.cdf(-eps / mu + mu / 2) - np.exp(eps) * scipy.stats.norm.cdf(-eps / mu - mu / 2) + + +def eps_Gaussian(delta, mu, max_epsilon): + """Compute eps of Gaussian mechanism with shift mu or equivalently noise scale 1/mu. + + :param delta: The delta value + :type delta: float + :param mu: The mu value + :type mu: float + :param max_epsilon: The maximum epsilon value to search for + :type max_epsilon: float + """ + + def f(x): + return delta_Gaussian(x, mu) - delta + + return root_scalar(f, bracket=[0, max_epsilon], method="brentq").root + + +def compute_epsilon(noise_multiplier, num_steps, delta, max_epsilon=1e7): + """Compute epsilon of Gaussian mechanism. + + :param noise_multiplier: The noise multiplier + :type noise_multiplier: float + :param num_steps: The number of steps + :type num_steps: int + :param delta: The delta value + :type delta: float + :param max_epsilon: The maximum epsilon value to search for, defaults to 1e7 + :type max_epsilon: float, optional + :return: The epsilon value. + :rtype: float + """ + return eps_Gaussian(delta=delta, mu=np.sqrt(num_steps) / noise_multiplier, max_epsilon=max_epsilon) + + +def get_noise_multiplier( + epsilon, + num_steps, + delta, + min_noise_multiplier=1e-1, + max_noise_multiplier=500, + max_epsilon=1e7, +): + """Get noise multiplier of Gaussian mechanism. + + :param epsilon: The epsilon value + :type epsilon: float + :param num_steps: The number of steps + :type num_steps: int + :param delta: The delta value + :type delta: float + :param min_noise_multiplier: The minimum noise multiplier to search for, defaults to 1e-1 + :type min_noise_multiplier: float, optional + :param max_noise_multiplier: The maximum noise multiplier to search for, defaults to 500 + :type max_noise_multiplier: float, optional + :param max_epsilon: The maximum epsilon value to search for, defaults to 1e7 + :type max_epsilon: float, optional + """ + + def objective(x): + return ( + compute_epsilon( + noise_multiplier=x, + num_steps=num_steps, + delta=delta, + max_epsilon=max_epsilon, + ) + - epsilon + ) + + output = root_scalar(objective, bracket=[min_noise_multiplier, max_noise_multiplier], method="brentq") + + if not output.converged: + raise ValueError("Failed to converge") + + return output.root + + +class Gaussian(DP): + """The Gaussian mechanism for Differential Privacy (DP) histogram.""" + + def set_epsilon_and_delta(self, num_iterations, epsilon, delta, noise_multiplier): + """Set the epsilon and delta for the Gaussian mechanism. + + :param num_iterations: The number of PE iterations + :type num_iterations: int + :param epsilon: The epsilon value of DP + :type epsilon: float + :param delta: The delta value of DP + :type delta: float + :param noise_multiplier: The noise multiplier of the DP mechanism + :type noise_multiplier: float + :raises ValueError: If delta is None + :raises ValueError: If both epsilon and noise_multiplier are None or not None + """ + if delta is None: + raise ValueError("Delta should not be None") + if (epsilon is None) == (noise_multiplier is None): + raise ValueError("Either epsilon or noise multiplier should be None") + + self._delta = delta + if epsilon is not None: + self._epsilon = epsilon + if num_iterations == 0: + self._noise_multiplier = 0 + execution_logger.warning( + "Since num_iterations is 0, noise_multiplier is set to 0, and epsilon is ignored." + ) + else: + self._noise_multiplier = get_noise_multiplier( + epsilon=epsilon, + num_steps=num_iterations, + delta=delta, + ) + else: + self._noise_multiplier = noise_multiplier + if num_iterations == 0: + self._epsilon = 0 + execution_logger.warning( + "Since num_iterations is 0, epsilon is set to 0, and noise_multiplier is ignored." + ) + else: + self._epsilon = compute_epsilon( + noise_multiplier=noise_multiplier, + num_steps=num_iterations, + delta=delta, + ) + execution_logger.info( + f"DP epsilon={self._epsilon}, delta={self._delta}, noise_multiplier={self._noise_multiplier}, " + f"num_iterations={num_iterations}." + ) + + def add_noise(self, syn_data): + """Add noise to the histogram of synthetic data. + + :param syn_data: The synthetic data to add noise. The synthetic data should have the + :py:const:`pe.constant.data.CLEAN_HISTOGRAM_COLUMN_NAME` column + :type syn_data: :py:class:`pe.data.data.Data` + :return: The synthetic data with noise added to the histogram. The noisy histogram is stored in the + :py:const:`pe.constant.data.DP_HISTOGRAM_COLUMN_NAME` column + :rtype: :py:class:`pe.data.data.Data` + """ + syn_data.data_frame[DP_HISTOGRAM_COLUMN_NAME] = syn_data.data_frame[ + CLEAN_HISTOGRAM_COLUMN_NAME + ] + np.random.normal(scale=self._noise_multiplier, size=len(syn_data.data_frame)) + return syn_data diff --git a/pe/embedding/__init__.py b/pe/embedding/__init__.py new file mode 100644 index 0000000..b42f9d1 --- /dev/null +++ b/pe/embedding/__init__.py @@ -0,0 +1 @@ +from .embedding import Embedding diff --git a/pe/embedding/embedding.py b/pe/embedding/embedding.py new file mode 100644 index 0000000..ae64be6 --- /dev/null +++ b/pe/embedding/embedding.py @@ -0,0 +1,21 @@ +from abc import ABC, abstractmethod + +from pe.constant.data import EMBEDDING_COLUMN_NAME + + +class Embedding(ABC): + """The abstract class that computes the embedding of samples.""" + + @property + def column_name(self): + """The column name to be used in the data frame.""" + return f"{EMBEDDING_COLUMN_NAME}.{type(self).__name__}" + + @abstractmethod + def compute_embedding(self, data): + """Compute the embedding of samples. + + :param data: The data to compute the embedding + :type data: :py:class:`pe.data.data.Data` + """ + pass diff --git a/pe/embedding/image/__init__.py b/pe/embedding/image/__init__.py new file mode 100644 index 0000000..293879f --- /dev/null +++ b/pe/embedding/image/__init__.py @@ -0,0 +1 @@ +from .inception import Inception diff --git a/pe/embedding/image/inception.py b/pe/embedding/image/inception.py new file mode 100644 index 0000000..c6a8e67 --- /dev/null +++ b/pe/embedding/image/inception.py @@ -0,0 +1,79 @@ +import tempfile +import numpy as np +import torch +import pandas as pd +from tqdm import tqdm + +from cleanfid.inception_torchscript import InceptionV3W +from cleanfid.resize import build_resizer +from cleanfid.resize import make_resizer + +from pe.embedding import Embedding +from pe.constant.data import IMAGE_DATA_COLUMN_NAME +from pe.logging import execution_logger + + +def to_uint8(x, min, max): + x = (x - min) / (max - min) + x = np.around(np.clip(x * 255, a_min=0, a_max=255)).astype(np.uint8) + return x + + +class Inception(Embedding): + """Compute the Inception embedding of images.""" + + def __init__(self, res, device="cuda", batch_size=2000): + """Constructor. + + :param res: The resolution of the images. The images will be resized to (res, res) before computing the + embedding + :type res: int + :param device: The device to use for computing the embedding, defaults to "cuda" + :type device: str, optional + :param batch_size: The batch size to use for computing the embedding, defaults to 2000 + :type batch_size: int, optional + """ + super().__init__() + self._temp_folder = tempfile.TemporaryDirectory() + self._device = device + self._inception = InceptionV3W(path=self._temp_folder.name, download=True, resize_inside=False).to(device) + self._resize_pre = make_resizer( + library="PIL", + quantize_after=False, + filter="bicubic", + output_size=(res, res), + ) + self._resizer = build_resizer("clean") + self._batch_size = batch_size + + def compute_embedding(self, data): + """Compute the Inception embedding of images. + + :param data: The data object containing the images + :type data: :py:class:`pe.data.data.Data` + :return: The data object with the computed embedding + :rtype: :py:class:`pe.data.data.Data` + """ + if self.column_name in data.data_frame.columns: + execution_logger.info(f"Embedding: {self.column_name} already computed") + return data + execution_logger.info(f"Embedding: computing {self.column_name} for {len(data.data_frame)} samples") + x = np.stack(data.data_frame[IMAGE_DATA_COLUMN_NAME].values, axis=0) + if x.shape[3] == 1: + x = np.repeat(x, 3, axis=3) + embeddings = [] + for i in tqdm(range(0, len(x), self._batch_size)): + transformed_x = [] + for j in range(i, min(i + self._batch_size, len(x))): + image = x[j] + image = self._resize_pre(image) + image = to_uint8(image, min=0, max=255) + image = self._resizer(image) + transformed_x.append(image) + transformed_x = np.stack(transformed_x, axis=0).transpose((0, 3, 1, 2)) + embeddings.append(self._inception(torch.from_numpy(transformed_x).to(self._device))) + embeddings = torch.cat(embeddings, dim=0) + embeddings = embeddings.cpu().detach().numpy() + data.data_frame[self.column_name] = pd.Series(list(embeddings), index=data.data_frame.index) + execution_logger.info(f"Embedding: finished computing {self.column_name} for {len(data.data_frame)} samples") + return data diff --git a/pe/histogram/__init__.py b/pe/histogram/__init__.py new file mode 100644 index 0000000..7db90c1 --- /dev/null +++ b/pe/histogram/__init__.py @@ -0,0 +1,2 @@ +from .histogram import Histogram +from .nearest_neighbors import NearestNeighbors diff --git a/pe/histogram/histogram.py b/pe/histogram/histogram.py new file mode 100644 index 0000000..1bc7093 --- /dev/null +++ b/pe/histogram/histogram.py @@ -0,0 +1,18 @@ +from abc import ABC, abstractmethod + + +class Histogram(ABC): + """The abstract class for computing the histogram over synthetic samples. The histogram values indicate how good + each synthetic sample is in terms their closeness to the private data. + """ + + @abstractmethod + def compute_histogram(self, priv_data, syn_data): + """Compute the histogram over the synthetic data using the private data. + + :param priv_data: The private data + :type priv_data: :py:class:`pe.data.data.Data` + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + """ + ... diff --git a/pe/histogram/nearest_neighbor_backend/__init__.py b/pe/histogram/nearest_neighbor_backend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pe/histogram/nearest_neighbor_backend/faiss.py b/pe/histogram/nearest_neighbor_backend/faiss.py new file mode 100644 index 0000000..d4a8ba8 --- /dev/null +++ b/pe/histogram/nearest_neighbor_backend/faiss.py @@ -0,0 +1,40 @@ +import faiss +import torch +import numpy as np + + +def search(syn_embedding, priv_embedding, num_nearest_neighbors, mode): + """Compute the nearest neighbors of the private embedding in the synthetic embedding using FAISS. + + :param syn_embedding: The synthetic embedding + :type syn_embedding: np.ndarray + :param priv_embedding: The private embedding + :type priv_embedding: np.ndarray + :param num_nearest_neighbors: The number of nearest neighbors to search + :type num_nearest_neighbors: int + :param mode: The distance metric to use for finding the nearest neighbors. It should be one of the following: + "l2" (l2 distance), "cos_sim" (cosine similarity), "ip" (inner product) + :type mode: str + :raises ValueError: If the mode is unknown + :return: The distances and indices of the nearest neighbors + :rtype: tuple[np.ndarray, np.ndarray] + """ + if mode.lower() == "l2": + index = faiss.IndexFlatL2(syn_embedding.shape[1]) + elif mode.lower() == "ip": + index = faiss.IndexFlatIP(syn_embedding.shape[1]) + elif mode.lower() == "cos_sim": + index = faiss.IndexFlatIP(syn_embedding.shape[1]) + faiss.normalize_L2(syn_embedding) + faiss.normalize_L2(priv_embedding) + else: + raise ValueError(f"Unknown mode: {mode}") + + if torch.cuda.is_available(): + ngpus = faiss.get_num_gpus() + co = faiss.GpuMultipleClonerOptions() + index = faiss.index_cpu_to_all_gpus(index, co, ngpus) + + index.add(syn_embedding) + distances, ids = index.search(priv_embedding, num_nearest_neighbors) + return np.sqrt(distances), ids diff --git a/pe/histogram/nearest_neighbor_backend/sklearn.py b/pe/histogram/nearest_neighbor_backend/sklearn.py new file mode 100644 index 0000000..2b3554f --- /dev/null +++ b/pe/histogram/nearest_neighbor_backend/sklearn.py @@ -0,0 +1,30 @@ +from sklearn.neighbors import NearestNeighbors + + +def search(syn_embedding, priv_embedding, num_nearest_neighbors, mode): + """Compute the nearest neighbors of the private embedding in the synthetic embedding using sklearn. + + :param syn_embedding: The synthetic embedding + :type syn_embedding: np.ndarray + :param priv_embedding: The private embedding + :type priv_embedding: np.ndarray + :param num_nearest_neighbors: The number of nearest neighbors to search + :type num_nearest_neighbors: int + :param mode: The distance metric to use for finding the nearest neighbors. It should be one of the following: + "l2" (l2 distance), "cos_sim" (cosine similarity) + :type mode: str + :raises ValueError: If the mode is unknown + :return: The distances and indices of the nearest neighbors + :rtype: tuple[np.ndarray, np.ndarray] + """ + if mode.lower() == "l2": + metric = "l2" + elif mode.lower() == "cos_sim": + metric = "cosine" + else: + raise ValueError(f"Unknown mode: {mode}") + + nn = NearestNeighbors(n_neighbors=num_nearest_neighbors, metric=metric, algorithm="brute", n_jobs=-1) + nn.fit(syn_embedding) + distances, ids = nn.kneighbors(priv_embedding) + return distances, ids diff --git a/pe/histogram/nearest_neighbors.py b/pe/histogram/nearest_neighbors.py new file mode 100644 index 0000000..d8182c3 --- /dev/null +++ b/pe/histogram/nearest_neighbors.py @@ -0,0 +1,199 @@ +import numpy as np +import os +from collections import Counter +import copy + +from pe.histogram import Histogram +from pe.constant.data import CLEAN_HISTOGRAM_COLUMN_NAME +from pe.constant.data import LOOKAHEAD_EMBEDDING_COLUMN_NAME +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.constant.data import HISTOGRAM_NEAREST_NEIGHBORS_VOTING_IDS_COLUMN_NAME +from pe.logging import execution_logger + + +class NearestNeighbors(Histogram): + """Compute the nearest neighbors histogram. Each private sample will vote for their closest `num_nearest_neighbors` + synthetic samples to construct the histogram. The l2 norm of the votes from each private sample is normalized to 1. + """ + + def __init__( + self, + embedding, + mode, + lookahead_degree, + lookahead_log_folder=None, + voting_details_log_folder=None, + api=None, + num_nearest_neighbors=1, + backend="sklearn", + ): + """Constructor. + + :param embedding: The :py:class:`pe.embedding.embedding.Embedding` object to compute the embedding of samples + :type embedding: :py:class:`pe.embedding.embedding.Embedding` + :param mode: The distance metric to use for finding the nearest neighbors. It should be one of the following: + "l2" (l2 distance), "cos_sim" (cosine similarity), "ip" (inner product). Not all backends support all + modes + :type mode: str + :param lookahead_degree: The degree of lookahead to compute the embedding of synthetic samples. If it is 0, the + original embedding is used. If it is greater than 0, the embedding of the synthetic samples is computed by + averaging the embeddings of the synthetic samples generated by the variation API for `lookahead_degree` + times + :type lookahead_degree: int + :param lookahead_log_folder: The folder to save the logs of the lookahead. If it is None, the logs are not + saved. Defaults to None + :type lookahead_log_folder: str, optional + :param voting_details_log_folder: The folder to save the logs of the voting details. If it is None, the logs + are not saved. Defaults to None + :type voting_details_log_folder: str, optional + :param api: The API to generate synthetic samples. It should be provided when `lookahead_degree` is greater + than 0. Defaults to None + :type api: :py:class:`pe.api.api.API`, optional + :param num_nearest_neighbors: The number of nearest neighbors to consider for each private sample, defaults to + 1 + :type num_nearest_neighbors: int, optional + :param backend: The backend to use for finding the nearest neighbors. It should be one of the following: + "faiss" (FAISS), "sklearn" (scikit-learn). Defaults to "sklearn". FAISS supports GPU and is much faster + when the number of synthetic samples and/or private samples is large. It requires the installation of + `faiss-gpu` or `faiss-cpu` package. See https://faiss.ai/ + :type backend: str, optional + :raises ValueError: If the `api` is not provided when `lookahead_degree` is greater than 0 + :raises ValueError: If the `backend` is unknown + """ + super().__init__() + self._embedding = embedding + self._mode = mode + self._lookahead_degree = lookahead_degree + self._lookahead_log_folder = lookahead_log_folder + self._voting_details_log_folder = voting_details_log_folder + self._api = api + self._num_nearest_neighbors = num_nearest_neighbors + if self._lookahead_degree > 0 and self._api is None: + raise ValueError("API should be provided when lookahead_degree is greater than 0") + if backend.lower() == "faiss": + from pe.histogram.nearest_neighbor_backend.faiss import search + + self._search = search + elif backend.lower() == "sklearn": + from pe.histogram.nearest_neighbor_backend.sklearn import search + + self._search = search + else: + raise ValueError(f"Unknown backend: {backend}") + + def _log_lookahead(self, syn_data, lookahead_id): + """Log the lookahead data. + + :param syn_data: The lookahead data + :type syn_data: :py:class:`pe.data.data.Data` + :param lookahead_id: The ID of the lookahead + :type lookahead_id: int + """ + if self._lookahead_log_folder is None: + return + labels = set(list(syn_data.data_frame[LABEL_ID_COLUMN_NAME].values)) + assert len(labels) == 1 + label = list(labels)[0] + iteration = syn_data.metadata["iteration"] + log_folder = os.path.join( + self._lookahead_log_folder, f"{iteration}", f"label-id{label}_lookahead{lookahead_id}" + ) + syn_data.save_checkpoint(log_folder) + + def _log_voting_details(self, priv_data, syn_data, ids): + """Log the voting details. + + :param priv_data: The private data + :type priv_data: :py:class:`pe.data.data.Data` + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :param ids: The IDs of the nearest neighbors for each private sample + :type ids: np.ndarray + """ + if self._voting_details_log_folder is None: + return + labels = set(list(priv_data.data_frame[LABEL_ID_COLUMN_NAME].values)) + assert len(labels) == 1 + label = list(labels)[0] + iteration = syn_data.metadata["iteration"] + log_folder = os.path.join(self._voting_details_log_folder, f"{iteration}", f"label-id{label}") + priv_data = copy.deepcopy(priv_data) + priv_data.data_frame[HISTOGRAM_NEAREST_NEIGHBORS_VOTING_IDS_COLUMN_NAME] = list(ids) + priv_data.save_checkpoint(log_folder) + + def _compute_lookahead_embedding(self, syn_data): + """Compute the embedding of synthetic samples with lookahead. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: The synthetic data with the computed embedding in the column + :py:const:`pe.constant.data.LOOKAHEAD_EMBEDDING_COLUMN_NAME` + :rtype: :py:class:`pe.data.data.Data` + """ + if self._lookahead_degree == 0: + syn_data = self._embedding.compute_embedding(syn_data) + syn_data.data_frame[LOOKAHEAD_EMBEDDING_COLUMN_NAME] = syn_data.data_frame[self._embedding.column_name] + else: + embedding_list = [] + for lookahead_id in range(self._lookahead_degree): + variation_data = self._api.variation_api(syn_data=syn_data) + variation_data = self._embedding.compute_embedding(variation_data) + self._log_lookahead(syn_data=variation_data, lookahead_id=lookahead_id) + embedding_list.append( + np.stack( + variation_data.data_frame[self._embedding.column_name].values, + axis=0, + ) + ) + embedding = np.mean(embedding_list, axis=0) + syn_data.data_frame[LOOKAHEAD_EMBEDDING_COLUMN_NAME] = list(embedding) + self._log_lookahead(syn_data=syn_data, lookahead_id=-1) + + return syn_data + + def compute_histogram(self, priv_data, syn_data): + """Compute the nearest neighbors histogram. + + :param priv_data: The private data + :type priv_data: :py:class:`pe.data.data.Data` + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: The private data, possibly with the additional embedding column, and the synthetic data, with the + computed histogram in the column :py:const:`pe.constant.data.CLEAN_HISTOGRAM_COLUMN_NAME` and possibly with + the additional embedding column + :rtype: tuple[:py:class:`pe.data.data.Data`, :py:class:`pe.data.data.Data`] + """ + execution_logger.info( + f"Histogram: computing nearest neighbors histogram for {len(priv_data.data_frame)} private " + f"samples and {len(syn_data.data_frame)} synthetic samples" + ) + + priv_data = self._embedding.compute_embedding(priv_data) + syn_data = self._compute_lookahead_embedding(syn_data) + + priv_embedding = np.stack(priv_data.data_frame[self._embedding.column_name].values, axis=0).astype(np.float32) + syn_embedding = np.stack(syn_data.data_frame[LOOKAHEAD_EMBEDDING_COLUMN_NAME].values, axis=0).astype( + np.float32 + ) + + _, ids = self._search( + syn_embedding=syn_embedding, + priv_embedding=priv_embedding, + num_nearest_neighbors=self._num_nearest_neighbors, + mode=self._mode, + ) + self._log_voting_details(priv_data=priv_data, syn_data=syn_data, ids=ids) + + counter = Counter(list(ids.flatten())) + count = np.zeros(shape=syn_embedding.shape[0], dtype=np.float32) + count[list(counter.keys())] = list(counter.values()) + count /= np.sqrt(self._num_nearest_neighbors) + + syn_data.data_frame[CLEAN_HISTOGRAM_COLUMN_NAME] = count + + execution_logger.info( + f"Histogram: finished computing nearest neighbors histogram for {len(priv_data.data_frame)} private " + f"samples and {len(syn_data.data_frame)} synthetic samples" + ) + + return priv_data, syn_data diff --git a/pe/logger/__init__.py b/pe/logger/__init__.py new file mode 100644 index 0000000..0447e54 --- /dev/null +++ b/pe/logger/__init__.py @@ -0,0 +1,4 @@ +from .csv_print import CSVPrint +from .image_file import ImageFile +from .log_print import LogPrint +from .matplotlib_pdf import MatplotlibPDF diff --git a/pe/logger/csv_print.py b/pe/logger/csv_print.py new file mode 100644 index 0000000..7fd3023 --- /dev/null +++ b/pe/logger/csv_print.py @@ -0,0 +1,109 @@ +import os +import csv +import torch +import numpy as np +from collections import defaultdict + +from .logger import Logger +from pe.metric_item import FloatMetricItem +from pe.metric_item import FloatListMetricItem + + +class CSVPrint(Logger): + """The logger that prints the metrics to CSV files.""" + + def __init__( + self, + output_folder, + path_separator="-", + float_format=".8f", + flush_iteration_freq=1, + ): + """Constructor. + + :param output_folder: The output folder that will be used to save the CSV files + :type output_folder: str + :param path_separator: The string that will be used to replace '\' and '/' in log names, defaults to "-" + :type path_separator: str, optional + :param float_format: The format of the floating point numbers, defaults to ".8f" + :type float_format: str, optional + :param flush_iteration_freq: The frequency to flush the logs, defaults to 1 + :type flush_iteration_freq: int, optional + """ + self._output_folder = output_folder + os.makedirs(self._output_folder, exist_ok=True) + self._path_separator = path_separator + self._float_format = float_format + self._flush_iteration_freq = flush_iteration_freq + self._clear_logs() + + def _clear_logs(self): + """Clear the logs.""" + self._logs = defaultdict(list) + + def _get_log_path(self, iteration, item): + """Get the log path. + + :param iteration: The PE iteration number + :type iteration: int + :param item: The metric item + :type item: :py:class:`pe.metric_item.MetricItem` + :return: The log path + :rtype: str + """ + log_path = item.name + log_path = log_path.replace("/", self._path_separator) + log_path = log_path.replace("\\", self._path_separator) + log_path = os.path.join(self._output_folder, log_path + ".csv") + return log_path + + def _flush(self): + """Flush the logs.""" + for path in self._logs: + with open(path, "a") as f: + writer = csv.writer(f) + writer.writerows(self._logs[path]) + + def _log_float(self, log_path, iteration, item): + """Log a float metric item. + + :param log_path: The path of the log file + :type log_path: str + :param iteration: The PE iteration number + :type iteration: int + :param item: The float metric item + :type item: :py:class:`pe.metric_item.FloatMetricItem` or :py:class:`pe.metric_item.FloatListMetricItem` + """ + str_iteration = str(iteration) + str_value = item.value + if isinstance(item.value, torch.Tensor): + str_value = item.value.cpu().detach().numpy() + if isinstance(str_value, np.ndarray): + str_value = str_value.tolist() + if isinstance(str_value, list): + str_value = ",".join([format(v, self._float_format) for v in str_value]) + else: + str_value = format(str_value, self._float_format) + self._logs[log_path].append([str_iteration, str_value]) + + def log(self, iteration, metric_items): + """Log the metrics. + + :param iteration: The PE iteration number + :type iteration: int + :param metric_items: The metrics to log + :type metric_items: list[:py:class:`pe.metric_item.MetricItem`] + """ + for item in metric_items: + if not isinstance(item, (FloatMetricItem, FloatListMetricItem)): + continue + log_path = self._get_log_path(iteration, item) + self._log_float(log_path, iteration, item) + if iteration % self._flush_iteration_freq == 0: + self._flush() + self._clear_logs() + + def clean_up(self): + """Clean up the logger.""" + self._flush() + self._clear_logs() diff --git a/pe/logger/image_file.py b/pe/logger/image_file.py new file mode 100644 index 0000000..7b7a8bc --- /dev/null +++ b/pe/logger/image_file.py @@ -0,0 +1,107 @@ +import os +import imageio +import math +import torch +import numpy as np +from torchvision.utils import make_grid + +from .logger import Logger +from pe.metric_item import ImageMetricItem, ImageListMetricItem + + +class ImageFile(Logger): + """The logger that saves images to files.""" + + def __init__( + self, + output_folder, + path_separator="-", + iteration_format="09d", + ): + """Constructor. + + :param output_folder: The output folder that will be used to save the images + :type output_folder: str + :param path_separator: The string that will be used to replace '\' and '/' in log names, defaults to "-" + :type path_separator: str, optional + :param iteration_format: The format of the iteration number, defaults to "09d" + :type iteration_format: str, optional + """ + self._output_folder = output_folder + self._path_separator = path_separator + self._iteration_format = iteration_format + + def log(self, iteration, metric_items): + """Log the images. + + :param iteration: The PE iteration number + :type iteration: int + :param metric_items: The images to log + :type metric_items: list[:py:class:`pe.metric_item.ImageMetricItem` or + :py:class:`pe.metric_item.ImageListMetricItem`] + """ + for item in metric_items: + if not isinstance(item, (ImageMetricItem, ImageListMetricItem)): + continue + image_path = self._get_image_path(iteration, item) + if isinstance(item, ImageMetricItem): + self._log_image(image_path, item) + elif isinstance(item, ImageListMetricItem): + self._log_image_list(image_path, item) + + def _get_image_path(self, iteration, item): + """Get the image save path. + + :param iteration: The PE iteration number + :type iteration: int + :param item: The image metric item + :type item: :py:class:`pe.metric_item.ImageMetricItem` or :py:class:`pe.metric_item.ImageListMetricItem` + :return: The image save path + :rtype: str + """ + os.makedirs(self._output_folder, exist_ok=True) + image_name = item.name + image_name = image_name.replace("/", self._path_separator) + image_name = image_name.replace("\\", self._path_separator) + image_folder = os.path.join(self._output_folder, image_name) + os.makedirs(image_folder, exist_ok=True) + iteration_string = format(iteration, self._iteration_format) + image_file_name = f"{iteration_string}.png" + image_path = os.path.join( + image_folder, + image_file_name, + ) + return image_path + + def _log_image(self, image_path, item): + """Log a single image. + + :param image_path: The path to save the image + :type image_path: str + :param item: The image metric item + :type item: :py:class:`pe.metric_item.ImageMetricItem` + """ + image = item.value + if isinstance(image, torch.Tensor): + image = image.cpu().detach().numpy() + imageio.imwrite(image_path, image) + + def _log_image_list(self, image_path, item): + """Log a list of images. + + :param image_path: The path to save the image + :type image_path: str + :param item: The image list metric item + :type item: :py:class:`pe.metric_item.ImageListMetricItem` + """ + images = item.value + num_images_per_row = item.num_images_per_row + if num_images_per_row is None: + num_images_per_row = int(math.sqrt(len(images))) + + if isinstance(images[0], np.ndarray): + images = [torch.from_numpy(image.transpose(2, 0, 1)) for image in images] + + image = make_grid(images, nrow=num_images_per_row).cpu().detach().numpy() + image = image.transpose((1, 2, 0)) + imageio.imwrite(image_path, image) diff --git a/pe/logger/log_print.py b/pe/logger/log_print.py new file mode 100644 index 0000000..00dc8d4 --- /dev/null +++ b/pe/logger/log_print.py @@ -0,0 +1,38 @@ +from .logger import Logger +from pe.metric_item import FloatMetricItem, FloatListMetricItem +from pe.logging import execution_logger + + +class LogPrint(Logger): + """The logger that prints the metrics to the console/file using :py:const:`pe.logging.execution_logger`.""" + + def __init__(self, log_iteration_freq=1): + """Constructor. + + :param log_iteration_freq: The frequency to log the metrics, defaults to 1 + :type log_iteration_freq: int, optional + """ + self._log_iteration_freq = log_iteration_freq + + def log(self, iteration, metric_items): + """Log the metrics to the console/file. + + :param iteration: The PE iteration number + :type iteration: int + :param metric_items: The metrics to log + :type metric_items: list[:py:class:`pe.metric_item.FloatMetricItem` or + :py:class:`pe.metric_item.FloatListMetricItem`] + """ + if iteration % self._log_iteration_freq != 0: + return + metric_items = [item for item in metric_items if isinstance(item, (FloatMetricItem, FloatListMetricItem))] + if len(metric_items) == 0: + return + execution_logger.info(f"Iteration: {iteration}") + for item in metric_items: + if isinstance(item, FloatMetricItem): + value = [item.value] + else: + value = item.value + value = ",".join([f"{v:.8f}" for v in value]) + execution_logger.info(f"\t{item.name}: {value}") diff --git a/pe/logger/logger.py b/pe/logger/logger.py new file mode 100644 index 0000000..1f1c646 --- /dev/null +++ b/pe/logger/logger.py @@ -0,0 +1,20 @@ +from abc import ABC, abstractmethod + + +class Logger(ABC): + """The abstract class for logging the metrics""" + + @abstractmethod + def log(self, iteration, metric_items): + """Log the metrics. + + :param iteration: The PE iteration number + :type iteration: int + :param metric_items: The metrics to log + :type metric_items: list[:py:class:`pe.metric_item.MetricItem`] + """ + ... + + def clean_up(self): + """Clean up the logger.""" + ... diff --git a/pe/logger/matplotlib_pdf.py b/pe/logger/matplotlib_pdf.py new file mode 100644 index 0000000..da61eec --- /dev/null +++ b/pe/logger/matplotlib_pdf.py @@ -0,0 +1,65 @@ +import os + +from .logger import Logger +from pe.metric_item import MatplotlibMetricItem + + +class MatplotlibPDF(Logger): + """The logger that saves Matplotlib figures to PDF files.""" + + def __init__( + self, + output_folder, + path_separator="-", + iteration_format="09d", + ): + """Constructor. + + :param output_folder: The output folder that will be used to save the PDF files + :type output_folder: str + :param path_separator: The string that will be used to replace '\' and '/' in log names, defaults to "-" + :type path_separator: str, optional + :param iteration_format: The format of the iteration number, defaults to "09d" + :type iteration_format: str, optional + """ + self._output_folder = output_folder + os.makedirs(self._output_folder, exist_ok=True) + self._path_separator = path_separator + self._iteration_format = iteration_format + + def log(self, iteration, metric_items): + """Log the Matplotlib figures to PDF files. + + :param iteration: The PE iteration number + :type iteration: int + :param metric_items: The Matplotlib figures to log + :type metric_items: list[:py:class:`pe.metric_item.MatplotlibMetricItem`] + """ + for item in metric_items: + if not isinstance(item, (MatplotlibMetricItem,)): + continue + pdf_path = self._get_pdf_path(iteration, item) + item.value.savefig(pdf_path) + + def _get_pdf_path(self, iteration, item): + """Get the PDF save path. + + :param iteration: The PE iteration number + :type iteration: int + :param item: The Matplotlib figure metric item + :type item: :py:class:`pe.metric_item.MatplotlibMetricItem` + :return: The PDF save path + :rtype: str + """ + image_name = item.name + image_name = image_name.replace("/", self._path_separator) + image_name = image_name.replace("\\", self._path_separator) + image_folder = os.path.join(self._output_folder, image_name) + os.makedirs(image_folder, exist_ok=True) + iteration_string = format(iteration, self._iteration_format) + image_file_name = f"{iteration_string}.pdf" + image_path = os.path.join( + image_folder, + image_file_name, + ) + return image_path diff --git a/pe/logging/__init__.py b/pe/logging/__init__.py new file mode 100644 index 0000000..2cd65c7 --- /dev/null +++ b/pe/logging/__init__.py @@ -0,0 +1,43 @@ +import logging +import os + +#: The logger that will be used to log the execution information +execution_logger = logging.getLogger() + + +def setup_logging( + log_file=None, + datefmt="%m/%d/%Y %H:%M:%S %p", + fmt="%(asctime)s [%(name)s] [%(levelname)-5.5s] %(message)s", + level=logging.INFO, + name="logger", +): + """Setup the logging configuration. + + :param log_file: The log file path, defaults to None + :type log_file: str, optional + :param datefmt: The date format, defaults to "%m/%d/%Y %H:%M:%S %p" + :type datefmt: str, optional + :param fmt: The log format, defaults to "%(asctime)s [%(name)s] [%(levelname)-5.5s] %(message)s" + :type fmt: str, optional + :param level: The log level, defaults to logging.INFO + :type level: int, optional + :param name: The logger name, defaults to "logger" + :type name: str, optional + """ + execution_logger.name = name + + execution_logger.handlers.clear() + execution_logger.setLevel(level) + + log_formatter = logging.Formatter(fmt=fmt, datefmt=datefmt) + + console_handler = logging.StreamHandler() + console_handler.setFormatter(log_formatter) + execution_logger.addHandler(console_handler) + + if log_file is not None: + os.makedirs(os.path.dirname(log_file), exist_ok=True) + file_handler = logging.FileHandler(log_file) + file_handler.setFormatter(log_formatter) + execution_logger.addHandler(file_handler) diff --git a/pe/metric_item/__init__.py b/pe/metric_item/__init__.py new file mode 100644 index 0000000..d5a9103 --- /dev/null +++ b/pe/metric_item/__init__.py @@ -0,0 +1,100 @@ +import matplotlib.pyplot as plt + +scopes = [] + + +class metric_scope(object): + """The context manager to manage the metric scope.""" + + def __init__(self, name): + self._name = name + + def __enter__(self): + scopes.append(self._name) + + def __exit__(self, type, value, traceback): + scopes.pop() + + +class MetricItem(object): + """The base class for the metric item.""" + + def __init__(self, name, value): + """Constructor. + + :param name: The name of the metric item + :type name: str + :param value: The value of the metric item + :type value: object + """ + self._name = "/".join(scopes + [name]) + self._value = value + + @property + def name(self): + """Get the name of the metric item. + + :return: The name of the metric item + :rtype: str + """ + return self._name + + @property + def value(self): + """Get the value of the metric item. + + :return: The value of the metric item + :rtype: object + """ + return self._value + + def clean_up(self): + """Clean up the metric item.""" + pass + + +class MatplotlibMetricItem(MetricItem): + """The metric item for Matplotlib figures.""" + + def clean_up(self): + plt.close(self._value) + + +class FloatMetricItem(MetricItem): + """The metric item for a single float value.""" + + pass + + +class FloatListMetricItem(MetricItem): + """The metric item for a list of float values.""" + + pass + + +class ImageMetricItem(MetricItem): + """The metric item for an image.""" + + pass + + +class ImageListMetricItem(MetricItem): + """The metric item for a list of images.""" + + def __init__(self, num_images_per_row=None, *args, **kwargs): + """Constructor. + + :param num_images_per_row: The number of images per row when saving to the file, defaults to None + :type num_images_per_row: int, optional + """ + super().__init__(*args, **kwargs) + self._num_images_per_row = num_images_per_row + + @property + def num_images_per_row(self): + """Get the number of images per row when saving to the file. + + :return: The number of images per row when saving to the file + :rtype: int or None + """ + return self._num_images_per_row diff --git a/pe/population/__init__.py b/pe/population/__init__.py new file mode 100644 index 0000000..1a5cb0c --- /dev/null +++ b/pe/population/__init__.py @@ -0,0 +1,2 @@ +from .population import Population +from .pe_population import PEPopulation diff --git a/pe/population/pe_population.py b/pe/population/pe_population.py new file mode 100644 index 0000000..24180b5 --- /dev/null +++ b/pe/population/pe_population.py @@ -0,0 +1,145 @@ +import numpy as np + +from .population import Population +from pe.data import Data +from pe.constant.data import DP_HISTOGRAM_COLUMN_NAME +from pe.constant.data import POST_PROCESSED_DP_HISTOGRAM_COLUMN_NAME +from pe.constant.data import PARENT_SYN_DATA_INDEX_COLUMN_NAME +from pe.constant.data import FROM_LAST_FLAG_COLUMN_NAME +from pe.logging import execution_logger + + +class PEPopulation(Population): + """The default population algorithm for Private Evolution.""" + + def __init__( + self, + api, + histogram_threshold, + initial_variation_api_fold=0, + next_variation_api_fold=1, + keep_selected=False, + selection_mode="sample", + ): + """Constructor. + + :param api: The API object that contains the random and variation APIs + :type api: :py:class:`pe.api.api.API` + :param histogram_threshold: The threshold for clipping the histogram + :type histogram_threshold: float + :param initial_variation_api_fold: The number of variations to apply to the initial synthetic data, defaults to + 0 + :type initial_variation_api_fold: int, optional + :param next_variation_api_fold: The number of variations to apply to the next synthetic data, defaults to 1 + :type next_variation_api_fold: int, optional + :param keep_selected: Whether to keep the selected data in the next synthetic data, defaults to False + :type keep_selected: bool, optional + :param selection_mode: The selection mode for selecting the data. It should be one of the following: "sample"( + random sampling proportional to the histogram). Defaults to "sample" + :type selection_mode: str, optional + :raises ValueError: If next_variation_api_fold is 0 and keep_selected is False + """ + super().__init__() + self._api = api + self._histogram_threshold = histogram_threshold + self._initial_variation_api_fold = initial_variation_api_fold + self._next_variation_api_fold = next_variation_api_fold + self._keep_selected = keep_selected + self._selection_mode = selection_mode + if self._next_variation_api_fold == 0 and not self._keep_selected: + raise ValueError( + "next_variation_api_fold should be greater than 0 or keep_selected should be True. Otherwise, next " + "synthetic data will be empty." + ) + + def initial(self, label_name, num_samples): + """Generate the initial synthetic data. + + :param label_name: The label name + :type label_name: str + :param num_samples: The number of samples to generate + :type num_samples: int + :return: The initial synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + execution_logger.info( + f"Population: generating {num_samples}*{self._initial_variation_api_fold + 1} initial " + f"synthetic samples for label {label_name}" + ) + random_data = self._api.random_api(label_name=label_name, num_samples=num_samples) + variation_data_list = [] + for _ in range(self._initial_variation_api_fold): + variation_data = self._api.variation_api(syn_data=random_data) + variation_data_list.append(variation_data) + data = Data.concat([random_data] + variation_data_list) + execution_logger.info( + f"Population: finished generating {num_samples}*{self._initial_variation_api_fold + 1} initial " + f"synthetic samples for label {label_name}" + ) + return data + + def _post_process_histogram(self, syn_data): + """Post process the histogram of synthetic data (e.g., clipping). + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :return: The synthetic data with post-processed histogram in the column + :py:const:`pe.constant.data.POST_PROCESSED_DP_HISTOGRAM_COLUMN_NAME` + :rtype: :py:class:`pe.data.data.Data` + """ + count = syn_data.data_frame[DP_HISTOGRAM_COLUMN_NAME].to_numpy() + clipped_count = np.clip(count, a_min=self._histogram_threshold, a_max=None) + clipped_count -= self._histogram_threshold + syn_data.data_frame[POST_PROCESSED_DP_HISTOGRAM_COLUMN_NAME] = clipped_count + return syn_data + + def _select_data(self, syn_data, num_samples): + """Select data from the synthetic data according to `selection_mode`. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :param num_samples: The number of samples to select + :type num_samples: int + :raises ValueError: If the selection mode is not supported + :return: The selected data + :rtype: :py:class:`pe.data.data.Data` + """ + if self._selection_mode == "sample": + count = syn_data.data_frame[POST_PROCESSED_DP_HISTOGRAM_COLUMN_NAME].to_numpy() + prob = count / count.sum() + indices = np.random.choice(len(syn_data.data_frame), size=num_samples, p=prob) + new_data_frame = syn_data.data_frame.iloc[indices] + new_data_frame[PARENT_SYN_DATA_INDEX_COLUMN_NAME] = syn_data.data_frame.index[indices] + return Data(data_frame=new_data_frame, metadata=syn_data.metadata) + else: + raise ValueError(f"Selection mode {self._selection_mode} is not supported") + + def next(self, syn_data, num_samples): + """Generate the next synthetic data. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :param num_samples: The number of samples to generate + :type num_samples: int + :return: The next synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + execution_logger.info( + f"Population: generating {num_samples}*{self._next_variation_api_fold} " "next synthetic samples" + ) + syn_data = self._post_process_histogram(syn_data) + selected_data = self._select_data(syn_data, num_samples) + selected_data.data_frame[FROM_LAST_FLAG_COLUMN_NAME] = 1 + variation_data_list = [] + for _ in range(self._next_variation_api_fold): + variation_data = self._api.variation_api(syn_data=selected_data) + variation_data.data_frame[PARENT_SYN_DATA_INDEX_COLUMN_NAME] = selected_data.data_frame[ + PARENT_SYN_DATA_INDEX_COLUMN_NAME + ].values + variation_data.data_frame[FROM_LAST_FLAG_COLUMN_NAME] = 0 + variation_data_list.append(variation_data) + new_syn_data = Data.concat(variation_data_list + ([selected_data] if self._keep_selected else [])) + execution_logger.info( + f"Population: finished generating {num_samples}*{self._next_variation_api_fold} " "next synthetic samples" + ) + return new_syn_data diff --git a/pe/population/population.py b/pe/population/population.py new file mode 100644 index 0000000..2676b91 --- /dev/null +++ b/pe/population/population.py @@ -0,0 +1,27 @@ +from abc import ABC, abstractmethod + + +class Population(ABC): + """The abstract class that generates synthetic data.""" + + @abstractmethod + def initial(self, label_name, num_samples): + """Generate the initial synthetic data. + + :param label_name: The label name + :type label_name: str + :param num_samples: The number of samples to generate + :type num_samples: int + """ + pass + + @abstractmethod + def next(self, syn_data, num_samples): + """Generate the next synthetic data. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + :param num_samples: The number of samples to generate + :type num_samples: int + """ + pass diff --git a/pe/runner/__init__.py b/pe/runner/__init__.py new file mode 100644 index 0000000..5d3b4ba --- /dev/null +++ b/pe/runner/__init__.py @@ -0,0 +1 @@ +from .pe import PE diff --git a/pe/runner/pe.py b/pe/runner/pe.py new file mode 100644 index 0000000..f212a61 --- /dev/null +++ b/pe/runner/pe.py @@ -0,0 +1,222 @@ +import numpy as np + +from pe.dp import Gaussian +from pe.data import Data +from pe.constant.data import LABEL_ID_COLUMN_NAME +from pe.logging import execution_logger + + +class PE(object): + """The class that runs the PE algorithm.""" + + def __init__(self, priv_data, population, histogram, dp=None, loggers=[], callbacks=[]): + """Constructor. + + :param priv_data: The private data + :type priv_data: :py:class:`pe.data.data.Data` + :param population: The population algorithm + :type population: :py:class:`pe.population.population.Population` + :param histogram: The histogram algorithm + :type histogram: :py:class:`pe.histogram.histogram.Histogram` + :param dp: The DP algorithm, defaults to None, in which case the Gaussian mechanism + :py:class:`pe.dp.gaussian.Gaussian` is used + :type dp: :py:class:`pe.dp.dp.DP`, optional + :param loggers: The list of loggers, defaults to [] + :type loggers: list[:py:class:`pe.logger.logger.Logger`], optional + :param callbacks: The list of callbacks, defaults to [] + :type callbacks: list[Callable or :py:class:`pe.callback.callback.Callback`], optional + """ + super().__init__() + self._priv_data = priv_data + self._population = population + self._histogram = histogram + if dp is None: + dp = Gaussian() + self._dp = dp + self._loggers = loggers + self._callbacks = callbacks + + def load_checkpoint(self, checkpoint_path): + """Load a checkpoint. + + :param checkpoint_path: The path to the checkpoint + :type checkpoint_path: str + :return: The synthetic data + :rtype: :py:class:`pe.data.data.Data` or None + """ + syn_data = Data() + if not syn_data.load_checkpoint(checkpoint_path): + return None + return syn_data + + def _log_metrics(self, syn_data): + """Log metrics. + + :param syn_data: The synthetic data + :type syn_data: :py:class:`pe.data.data.Data` + """ + if not self._callbacks: + return + metric_items = [] + for callback in self._callbacks: + metric_items.extend(callback(syn_data) or []) + for logger in self._loggers: + logger.log(iteration=syn_data.metadata.iteration, metric_items=metric_items) + for metric_item in metric_items: + metric_item.clean_up() + + def _get_num_samples_per_label_id(self, num_samples, fraction_per_label_id): + """Get the number of samples per label id given the total number of samples + + :param num_samples: The total number of samples + :type num_samples: int + :param fraction_per_label_id: The fraction of samples for each label id. The fraction does not have to be + normalized. When it is None, the fraction is assumed to be the same as the fraction of label ids in the + private data. Defaults to None + :type fraction_per_label_id: list[float], optional + :raises ValueError: If the length of fraction_per_label_id is not the same as the number of labels + :raises ValueError: If the number of samples is so small that the number of samples for some label ids is zero + :return: The number of samples per label id + :rtype: np.ndarray + """ + if fraction_per_label_id is None: + execution_logger.warning( + "fraction_per_label_id is not provided. Assuming the fraction of label ids in private data is public " + "information." + ) + fraction_per_label_id = self._priv_data.data_frame[LABEL_ID_COLUMN_NAME].value_counts().to_dict() + fraction_per_label_id = [ + 0 if i not in fraction_per_label_id else fraction_per_label_id[i] + for i in range(len(self._priv_data.metadata.label_names)) + ] + if len(fraction_per_label_id) != len(self._priv_data.metadata.label_names): + raise ValueError("fraction_per_label_id should have the same length as the number of labels.") + fraction_per_label_id = np.array(fraction_per_label_id) + fraction_per_label_id = fraction_per_label_id / np.sum(fraction_per_label_id) + + target_num_samples_per_label_id = fraction_per_label_id * num_samples + num_samples_per_label_id = np.floor(target_num_samples_per_label_id).astype(int) + num_samples_left = num_samples - np.sum(num_samples_per_label_id) + ids = np.argsort(target_num_samples_per_label_id - num_samples_per_label_id)[::-1] + num_samples_per_label_id[ids[:num_samples_left]] += 1 + assert np.sum(num_samples_per_label_id) == num_samples + if np.any(num_samples_per_label_id == 0): + raise ValueError("num_samples is so small that the number of samples for some label ids is zero.") + return num_samples_per_label_id + + def _clean_up_loggers(self): + """Clean up loggers.""" + for logger in self._loggers: + logger.clean_up() + + def run( + self, + num_samples_schedule, + delta, + epsilon=None, + noise_multiplier=None, + checkpoint_path=None, + save_checkpoint=True, + fraction_per_label_id=None, + ): + """Run the PE algorithm. + + :param num_samples_schedule: The schedule of the number of samples for each PE iteration. The first element is + the number of samples for the initial data, and the rest are the number of samples for each PE iteration. + So the length of the list is the number of PE iterations plus one + :type num_samples_schedule: list[int] + :param delta: The delta value of DP + :type delta: float + :param epsilon: The epsilon value of DP, defaults to None + :type epsilon: float, optional + :param noise_multiplier: The noise multiplier of the DP mechanism, defaults to None + :type noise_multiplier: float, optional + :param checkpoint_path: The path to load and save the checkpoint, defaults to None + :type checkpoint_path: str, optional + :param save_checkpoint: Whether to save the checkpoint, defaults to True + :type save_checkpoint: bool, optional + :param fraction_per_label_id: The fraction of samples for each label id. The fraction does not have to be + normalized. When it is None, the fraction is assumed to be the same as the fraction of label ids in the + private data. Defaults to None + :type fraction_per_label_id: list[float], optional + :return: The synthetic data + :rtype: :py:class:`pe.data.data.Data` + """ + try: + # Set privacy budget. + self._dp.set_epsilon_and_delta( + num_iterations=len(num_samples_schedule) - 1, + epsilon=epsilon, + delta=delta, + noise_multiplier=noise_multiplier, + ) + + # Generate or load initial data. + if checkpoint_path is not None and (syn_data := self.load_checkpoint(checkpoint_path)): + execution_logger.info( + f"Loaded checkpoint from {checkpoint_path}, iteration={syn_data.metadata.iteration}" + ) + else: + num_samples_per_label_id = self._get_num_samples_per_label_id( + num_samples=num_samples_schedule[0], + fraction_per_label_id=fraction_per_label_id, + ) + syn_data_list = [] + for label_id, label_name in enumerate(self._priv_data.metadata.label_names): + syn_data = self._population.initial( + label_name=label_name, + num_samples=num_samples_per_label_id[label_id], + ) + syn_data.set_label_id(label_id) + syn_data_list.append(syn_data) + syn_data = Data.concat(syn_data_list, metadata=self._priv_data.metadata) + syn_data.data_frame.reset_index(drop=True, inplace=True) + syn_data.metadata.iteration = 0 + syn_data.metadata.label_names = self._priv_data.metadata.label_names + self._log_metrics(syn_data) + + # Run PE iterations. + for iteration in range(syn_data.metadata.iteration + 1, len(num_samples_schedule)): + execution_logger.info(f"PE iteration {iteration}") + num_samples_per_label_id = self._get_num_samples_per_label_id( + num_samples=num_samples_schedule[iteration], + fraction_per_label_id=fraction_per_label_id, + ) + syn_data_list = [] + priv_data_list = [] + + # Generate synthetic data for each label. + for label_id in range(len(self._priv_data.metadata.label_names)): + execution_logger.info(f"Label {label_id}") + sub_priv_data = self._priv_data.filter_label_id(label_id=label_id) + sub_syn_data = syn_data.filter_label_id(label_id=label_id) + + # DP NN histogram. + sub_priv_data, sub_syn_data = self._histogram.compute_histogram( + priv_data=sub_priv_data, syn_data=sub_syn_data + ) + priv_data_list.append(sub_priv_data) + sub_syn_data = self._dp.add_noise(syn_data=sub_syn_data) + + # Generate next population. + sub_syn_data = self._population.next( + syn_data=sub_syn_data, + num_samples=num_samples_per_label_id[label_id], + ) + sub_syn_data.set_label_id(label_id) + syn_data_list.append(sub_syn_data) + + syn_data = Data.concat(syn_data_list) + syn_data.data_frame.reset_index(drop=True, inplace=True) + syn_data.metadata.iteration = iteration + + new_priv_data = Data.concat(priv_data_list) + self._priv_data = self._priv_data.merge(new_priv_data) + + if save_checkpoint: + syn_data.save_checkpoint(checkpoint_path) + self._log_metrics(syn_data) + finally: + self._clean_up_loggers() + + return syn_data diff --git a/pe/util/__init__.py b/pe/util/__init__.py new file mode 100644 index 0000000..ae25d07 --- /dev/null +++ b/pe/util/__init__.py @@ -0,0 +1 @@ +from .download import download diff --git a/pe/util/download.py b/pe/util/download.py new file mode 100644 index 0000000..aa2ddc9 --- /dev/null +++ b/pe/util/download.py @@ -0,0 +1,21 @@ +import requests +from tqdm import tqdm + + +def download(url: str, fname: str, chunk_size=1024): + """ + From: + https://gist.github.com/yanqd0/c13ed29e29432e3cf3e7c38467f42f51 + """ + resp = requests.get(url, stream=True) + total = int(resp.headers.get("content-length", 0)) + with open(fname, "wb") as file, tqdm( + desc=fname, + total=total, + unit="iB", + unit_scale=True, + unit_divisor=1024, + ) as bar: + for data in resp.iter_content(chunk_size=chunk_size): + size = file.write(data) + bar.update(size) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..643a0ac --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,43 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "private-evolution" +version = "0.0.1" +maintainers = [{ name = "Zinan Lin", email = "zinanlin@microsoft.com" }] +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", +] +readme = "README.md" +description = "Differentially private synthetic data via foundation model inference APIs." +dependencies = [ + "matplotlib", + "clean-fid", + "omegaconf", + "pandas", + "scikit-learn", +] + +[project.optional-dependencies] +dev = ["pre-commit", "black", "sphinx", "sphinx-rtd-theme"] +image = [ + "blobfile", + "torch", + "imageio", + "clip@git+https://github.com/openai/CLIP.git@dcba3cb2e2827b402d2701e7e1c7d9fed8a20ef1", + "diffusers[pytorch]", + "improved-diffusion@git+https://github.com/fjxmlzn/improved-diffusion.git@8f6677c3c47d1c1ad2e22ad2603eaec4cc639805", + "wilds", +] + +[project.urls] +Homepage = "https://github.com/microsoft/DPSDA" +Documentation = "https://github.com/microsoft/DPSDA" +Repository = "https://github.com/microsoft/DPSDA" +"Bug Tracker" = "https://github.com/microsoft/DPSDA/issues" + +[tool.setuptools.packages.find] +exclude = ["doc", "data", "example", "docker*", "amlt", "dist*", "_*"]