mirror of
https://github.com/Shawn-Shan/fawkes.git
synced 2025-02-22 18:47:06 +05:30
Situation: Fawkes is a brilliant research project. I personally enjoyed reading the research paper. However, numerous issues and pull requests have resulted from how difficult it is to run after initially downloading it due to poorly documented python version requirements and compatibility collapse with numerous dependencies following ~4 years of drift. Example links in the last paragraph for brevity.
Action: I rewrote the setup code to depend on pyenv and poetry allowing us to explicitly require the use of python 3.9.0 rather than having users guess at how best to execute the code. I've used stricter dependency requirements (lots of ~= in pyproject.toml dependencies) as the project is unlikely to be maintained regularly and reviving the code required a lot of dependency incompatibility navigation we should avoid for future users. Result: A new user can build this great research project with ~10 lines! A big win in my opinion. Some relevant pull requests and issues. https://github.com/Shawn-Shan/fawkes/pull/168 https://github.com/Shawn-Shan/fawkes/pull/158 https://github.com/Shawn-Shan/fawkes/issues/186 https://github.com/Shawn-Shan/fawkes/issues/178
This commit is contained in:
parent
272469421b
commit
5e9bef774d
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
||||
3.9.0
|
22
README.md
22
README.md
@ -18,6 +18,25 @@ This code is intended only for personal privacy protection or academic research.
|
||||
Usage
|
||||
-----
|
||||
|
||||
### Local Development (Most reliable and future-proof method of running fawkes)
|
||||
|
||||
```commandline
|
||||
# Install pyenv before running these commands
|
||||
# Instructions to install pyenv vary per OS.
|
||||
pyenv install 3.9.0
|
||||
pyenv global 3.9.0
|
||||
pip install poetry
|
||||
# After this point global python can be anything
|
||||
# the fawkes repos .python-version file tells pyenv to use 3.9.0 when inside the fawkes folder.
|
||||
|
||||
pip install poetry # Install poetry
|
||||
|
||||
pyenv install 3.9.0
|
||||
cd fawkes
|
||||
poetry install
|
||||
poetry run python .\fawkes\protection.py -d ./imgs --mode low
|
||||
```
|
||||
|
||||
`$ fawkes`
|
||||
|
||||
Options:
|
||||
@ -34,9 +53,6 @@ Options:
|
||||
|
||||
`fawkes -d ./imgs --mode low`
|
||||
|
||||
or `python3 protection.py -d ./imgs --mode low`
|
||||
|
||||
|
||||
### Tips
|
||||
|
||||
- The perturbation generation takes ~60 seconds per image on a CPU machine, and it would be much faster on a GPU
|
||||
|
@ -195,7 +195,7 @@ class FawkesMaskGeneration:
|
||||
dtype=tf.float32)
|
||||
|
||||
# make the optimizer
|
||||
optimizer = tf.keras.optimizers.Adadelta(float(self.learning_rate))
|
||||
optimizer = tf.keras.optimizers.legacy.Adadelta(float(self.learning_rate))
|
||||
const_numpy = np.ones(len(source_imgs)) * self.initial_const
|
||||
self.const = tf.Variable(const_numpy, dtype=np.float32)
|
||||
|
||||
|
@ -75,7 +75,7 @@ class Fawkes(object):
|
||||
extractors = ["extractor_0", "extractor_2"]
|
||||
|
||||
else:
|
||||
raise Exception("mode must be one of 'min', 'low', 'mid', 'high'")
|
||||
raise Exception("mode must be one of 'low', 'mid', 'high'")
|
||||
return th, max_step, lr, extractors
|
||||
|
||||
def run_protection(self, image_paths, th=0.04, sd=1e7, lr=10, max_step=500, batch_size=1, format='png',
|
||||
|
1428
poetry.lock
generated
Normal file
1428
poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
publish.sh
Normal file
11
publish.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Publish the package
|
||||
poetry publish --build
|
||||
|
||||
# Get the current version
|
||||
VERSION=$(poetry version -s)
|
||||
|
||||
# Create and push a Git tag
|
||||
git tag v$VERSION
|
||||
git push origin v$VERSION
|
48
pyproject.toml
Normal file
48
pyproject.toml
Normal file
@ -0,0 +1,48 @@
|
||||
[project]
|
||||
name = "fawkes"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [
|
||||
{name = "Shawn Shan", email = "shawnshan@cs.uchicago.edu"}
|
||||
]
|
||||
license = "BSD"
|
||||
homepage = "https://github.com/Shawn-Shan/fawkes"
|
||||
keywords = ["fawkes", "privacy", "ML"]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Topic :: System :: Monitoring",
|
||||
]
|
||||
|
||||
readme = "README.md"
|
||||
requires-python = "~=3.9"
|
||||
dependencies = [
|
||||
"numpy (>=1.22,<2.0)",
|
||||
"tensorflow-io-gcs-filesystem (>=0.23.1,<0.24.0)",
|
||||
"tensorflow (==2.12)",
|
||||
"keras (>=2.12.0,<2.13.0)",
|
||||
"setuptools (>=75.8.0,<76.0.0)",
|
||||
"mtcnn (>=0.1.0,<0.2.0)",
|
||||
"pillow (>=11.1.0,<12.0.0)",
|
||||
"bleach (>=6.2.0,<7.0.0)",
|
||||
"pyqt5 (==5.15.2)",
|
||||
# Despite the name amd runs this implementation fine.
|
||||
# There's no built in poetry env variable that'll tell us if an AMD GPU is present (which would imply tensorflow-rocm could be a more efficient implementation).
|
||||
# A script could probably be built that intelligently runs pip install under the hood but this is hard to track for a newbie.
|
||||
"tensorflow-intel (==2.12.0)"
|
||||
|
||||
]
|
||||
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "~3.9"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
fawkes = "fawkes:main"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
116
setup.py
116
setup.py
@ -1,116 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from setuptools import setup, Command
|
||||
|
||||
__PATH__ = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
|
||||
def read_version():
|
||||
__PATH__ = os.path.abspath(os.path.dirname(__file__))
|
||||
with open(os.path.join(__PATH__, 'fawkes/__init__.py')) as f:
|
||||
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
|
||||
f.read(), re.M)
|
||||
if version_match:
|
||||
return version_match.group(1)
|
||||
raise RuntimeError("Unable to find __version__ string")
|
||||
|
||||
|
||||
__version__ = read_version()
|
||||
|
||||
|
||||
# brought from https://github.com/kennethreitz/setup.py
|
||||
class DeployCommand(Command):
|
||||
description = 'Build and deploy the package to PyPI.'
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def status(s):
|
||||
print(s)
|
||||
|
||||
def run(self):
|
||||
|
||||
assert 'dev' not in __version__, (
|
||||
"Only non-devel versions are allowed. "
|
||||
"__version__ == {}".format(__version__))
|
||||
|
||||
with os.popen("git status --short") as fp:
|
||||
git_status = fp.read().strip()
|
||||
if git_status:
|
||||
print("Error: git repository is not clean.\n")
|
||||
os.system("git status --short")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
from shutil import rmtree
|
||||
self.status('Removing previous builds ...')
|
||||
rmtree(os.path.join(__PATH__, 'dist'))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
self.status('Building Source and Wheel (universal) distribution ...')
|
||||
os.system('{0} setup.py sdist'.format(sys.executable))
|
||||
|
||||
self.status('Uploading the package to PyPI via Twine ...')
|
||||
ret = os.system('twine upload dist/*')
|
||||
if ret != 0:
|
||||
sys.exit(ret)
|
||||
|
||||
self.status('Creating git tags ...')
|
||||
os.system('git tag v{0}'.format(__version__))
|
||||
os.system('git tag --list')
|
||||
sys.exit()
|
||||
|
||||
|
||||
setup_requires = []
|
||||
|
||||
install_requires = [
|
||||
'numpy>=1.19.5',
|
||||
'tensorflow==2.4.1',
|
||||
'keras==2.4.3',
|
||||
'mtcnn',
|
||||
'pillow>=7.0.0',
|
||||
'bleach>=2.1.0'
|
||||
]
|
||||
|
||||
setup(
|
||||
name='fawkes',
|
||||
version=__version__,
|
||||
license='BSD',
|
||||
description='An utility to protect user privacy',
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/markdown',
|
||||
url="https://github.com/Shawn-Shan/fawkes",
|
||||
author='Shawn Shan',
|
||||
author_email='shawnshan@cs.uchicago.edu',
|
||||
keywords='fawkes privacy ML',
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
"Operating System :: OS Independent",
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: System :: Monitoring',
|
||||
],
|
||||
packages=['fawkes'],
|
||||
install_requires=install_requires,
|
||||
setup_requires=setup_requires,
|
||||
entry_points={
|
||||
'console_scripts': ['fawkes=fawkes:main'],
|
||||
},
|
||||
cmdclass={
|
||||
'deploy': DeployCommand,
|
||||
},
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
python_requires='>=3.5',
|
||||
)
|
Loading…
Reference in New Issue
Block a user