Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make fawkes builds and dependencies reproducible and easy to maintain #190

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.9.0
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion fawkes/differentiator.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def compute_batch(self, source_imgs, target_imgs=None, retry=True):
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)

Expand Down
2 changes: 1 addition & 1 deletion fawkes/protection.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def mode2param(self, mode):
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',
Expand Down
4 changes: 2 additions & 2 deletions fawkes/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from PIL import Image, ExifTags
from keras.layers import Dense, Activation
from keras.models import Model
from keras.preprocessing import image
from keras.utils import image_utils as image

from fawkes.align_face import align
from six.moves.urllib.request import urlopen
Expand Down Expand Up @@ -263,7 +263,7 @@ def load_victim_model(number_classes, teacher_model=None, end2end=False):

def resize(img, sz):
assert np.min(img) >= 0 and np.max(img) <= 255.0
from keras.preprocessing import image
from keras.utils import image_utils as image
im_data = image.array_to_img(img).resize((sz[1], sz[0]))
im_data = image.img_to_array(im_data)
return im_data
Expand Down
1,428 changes: 1,428 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions publish.sh
Original file line number Diff line number Diff line change
@@ -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 changes: 48 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[project]
name = "fawkes"
version = "0.1.0"
description = ""
authors = [
{name = "Shawn Shan", email = "[email protected]"}
]
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 changes: 0 additions & 116 deletions setup.py

This file was deleted.