2
0
mirror of https://github.com/Shawn-Shan/fawkes.git synced 2024-12-22 07:09:33 +05:30
Former-commit-id: 14c0173d9f573e7ccb275b3e366505057ac2c9b1 [formerly e359682d967212b4b3f27923fd659bbade7880e5]
Former-commit-id: a44577686ff64da031231ea323c681185daa8b0d
This commit is contained in:
Shawn-Shan 2020-07-07 11:14:38 -05:00
parent 30fa1635a5
commit e9f1a50653
19 changed files with 112 additions and 348 deletions

View File

@ -6,11 +6,11 @@ We published an academic paper to summary our work "[Fawkes: Protecting Personal
### BEFORE YOU RUN OUR CODE ### BEFORE YOU RUN OUR CODE
If you would like to use Fawkes to protect your images, please check out our binary implementation on the [website](http://sandlab.cs.uchicago.edu/fawkes/#code).
If you are a developer or researcher planning to customize and modify on our existing code. Please refer to [fawkes_dev](https://github.com/Shawn-Shan/fawkes/tree/master/fawkes_dev). If you are a developer or researcher planning to customize and modify on our existing code. Please refer to [fawkes_dev](https://github.com/Shawn-Shan/fawkes/tree/master/fawkes_dev).
### How to protect my image
### Citation ### Citation
``` ```
@inproceedings{shan2020fawkes, @inproceedings{shan2020fawkes,

View File

@ -1,71 +0,0 @@
Metadata-Version: 2.1
Name: fawkes
Version: 0.0.1
Summary: Fawkes protect user privacy
Home-page: https://github.com/Shawn-Shan/fawkes
Author: Shawn Shan
Author-email: shansixiong@cs.uchicago.edu
License: UNKNOWN
Description: # Fawkes
Code implementation of the paper "[Fawkes: Protecting Personal Privacy against Unauthorized Deep Learning Models](https://arxiv.org/pdf/2002.08327.pdf)", at *USENIX Security 2020*.
### BEFORE YOU RUN OUR CODE
We appreciate your interest in our work and for trying out our code. We've noticed several cases where incorrect configuration leads to poor performances of protection. If you also observe low detection performance far away from what we presented in the paper, please feel free to open an issue in this repo or contact any of the authors directly. We are more than happy to help you debug your experiment and find out the correct configuration.
### ABOUT
This repository contains code implementation of the paper "[Fawkes: Protecting Personal Privacy against Unauthorized Deep Learning Models](https://arxiv.org/pdf/2002.08327.pdf)", at *USENIX Security 2020*.
### DEPENDENCIES
Our code is implemented and tested on Keras with TensorFlow backend. Following packages are used by our code.
- `keras==2.3.1`
- `numpy==1.18.4`
- `tensorflow-gpu==1.13.1`
Our code is tested on `Python 3.6.8`
### HOWTO
#### Download and Config Datasets
The first step is to download several datasets for protection and target selection.
1. Download the following dataset to your local machine. After downloading the datasets, restructure it the same way as the FaceScrub dataset downloaded.
- FaceScrub -- used for protection evaluation (link)
- VGGFace1 -- used for target select (link)
- VGGFace2 -- used for target select (link)
- WebFace -- used for target select (link)
2. Config datasets
open `fawkes/config.py` and update the `DATASETS` dictionary with the path to each dataset. Then run `python fawkes/config.py`. Every time the datasets are updated or moved, remember to rerun the command with the updated path.
3. Calculate embeddings using feature extractor.
Run `python3 fawkes/prepare_feature_extractor.py --candidate-datasets scrub vggface1 vggface2 webface`. This will calculate and cache the embeddings using the default feature extractor we provide. To use a customized feature extractor, please look at the Advance section at the end.
#### Generate Cloak for Images
To generate cloak, run
`python3 fawkes/protection.py --gpu 0 --dataset scrub --feature-extractor webface_dense_robust_extract`
For more information about the detailed parameters, please read `fawkes/protection.py`.
The code will output a directory in `results/` with `cloak_data.p` inside. You can check the cloaked images or inspect the changes in `this notebook`.
#### Evaluate Cloak Effectiveness
To evaluate the cloak, run `python3 fawkes/eval_cloak.py --gpu 0 --cloak_data PATH-TO-RESULT-DIRECTORY --transfer_model vggface2_inception_extract`.
The code will print out the tracker model accuracy on uncloaked/original test images of the protected user, which should be close to 0.
### Citation
```
@inproceedings{shan2020fawkes,
title={Fawkes: Protecting Personal Privacy against Unauthorized Deep Learning Models},
author={Shan, Shawn and Wenger, Emily and Zhang, Jiayun and Li, Huiying and Zheng, Haitao and Zhao, Ben Y},
booktitle="Proc. of USENIX Security",
year={2020}
}
```
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.5
Description-Content-Type: text/markdown

View File

@ -1,10 +0,0 @@
README.md
setup.py
fawkes/__init__.py
fawkes/differentiator.py
fawkes/protection.py
fawkes/utils.py
fawkes.egg-info/PKG-INFO
fawkes.egg-info/SOURCES.txt
fawkes.egg-info/dependency_links.txt
fawkes.egg-info/top_level.txt

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@
fawkes

View File

@ -1 +0,0 @@
58d500da850206b845bdd0150fa182a0ff8c50f0

View File

@ -4,21 +4,17 @@
# @Link : https://www.shawnshan.com/ # @Link : https://www.shawnshan.com/
__version__ = '0.0.2' __version__ = '0.0.5'
from .detect_faces import create_mtcnn, run_detect_face
from .differentiator import FawkesMaskGeneration from .differentiator import FawkesMaskGeneration
from .utils import load_extractor, init_gpu, select_target_label, dump_image, reverse_process_cloaked, \
Faces
from .protection import main from .protection import main
import logging from .utils import load_extractor, init_gpu, select_target_label, dump_image, reverse_process_cloaked, Faces, get_file
import sys
import os
logging.getLogger('tensorflow').disabled = True
__all__ = ( __all__ = (
'__version__', '__version__', 'create_mtcnn', 'run_detect_face',
'FawkesMaskGeneration', 'load_extractor', 'FawkesMaskGeneration', 'load_extractor',
'init_gpu', 'init_gpu',
'select_target_label', 'dump_image', 'reverse_process_cloaked', 'Faces', 'main' 'select_target_label', 'dump_image', 'reverse_process_cloaked',
'Faces', 'get_file', 'main',
) )

View File

@ -1,7 +1,6 @@
from .detect_face import detect_face, create_mtcnn
import numpy as np import numpy as np
from fawkes import create_mtcnn, run_detect_face
# modify the default parameters of np.load
np_load_old = np.load np_load_old = np.load
np.load = lambda *a, **k: np_load_old(*a, allow_pickle=True, **k) np.load = lambda *a, **k: np_load_old(*a, allow_pickle=True, **k)
@ -30,7 +29,7 @@ def align(orig_img, aligner, margin=0.8, detect_multiple_faces=True):
orig_img = to_rgb(orig_img) orig_img = to_rgb(orig_img)
orig_img = orig_img[:, :, 0:3] orig_img = orig_img[:, :, 0:3]
bounding_boxes, _ = detect_face(orig_img, minsize, pnet, rnet, onet, threshold, factor) bounding_boxes, _ = run_detect_face(orig_img, minsize, pnet, rnet, onet, threshold, factor)
nrof_faces = bounding_boxes.shape[0] nrof_faces = bounding_boxes.shape[0]
if nrof_faces > 0: if nrof_faces > 0:
det = bounding_boxes[:, 0:4] det = bounding_boxes[:, 0:4]
@ -66,14 +65,6 @@ def align(orig_img, aligner, margin=0.8, detect_multiple_faces=True):
cropped = orig_img[bb[1]:bb[3], bb[0]:bb[2], :] cropped = orig_img[bb[1]:bb[3], bb[0]:bb[2], :]
cropped_arr.append(cropped) cropped_arr.append(cropped)
bounding_boxes_arr.append([bb[0], bb[1], bb[2], bb[3]]) bounding_boxes_arr.append([bb[0], bb[1], bb[2], bb[3]])
# scaled = misc.imresize(cropped, (image_size, image_size), interp='bilinear')
return cropped_arr, bounding_boxes_arr return cropped_arr, bounding_boxes_arr
else: else:
return None return None
#
# if __name__ == '__main__':
# orig_img = misc.imread('orig_img.jpeg')
# cropped_arr, bounding_boxes_arr = align(orig_img)
# misc.imsave('test_output.jpeg', cropped_arr[0])
# print(bounding_boxes_arr)
#

View File

@ -1,38 +1,15 @@
""" Tensorflow implementation of the face detection / alignment algorithm found at """ Tensorflow implementation of the face detection / alignment algorithm found at
https://github.com/kpzhang93/MTCNN_face_detection_alignment https://github.com/kpzhang93/MTCNN_face_detection_alignment
""" """
# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# 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.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import gzip
import os import os
import pickle
import cv2
import numpy as np import numpy as np
import tensorflow as tf import tensorflow as tf
from six import string_types, iteritems from six import string_types, iteritems
from skimage.transform import resize
def layer(op): def layer(op):
@ -78,13 +55,12 @@ class Network(object):
"""Construct the network. """ """Construct the network. """
raise NotImplementedError('Must be implemented by the subclass.') raise NotImplementedError('Must be implemented by the subclass.')
def load(self, data_path, session, ignore_missing=False): def load(self, data_dict, session, ignore_missing=False):
"""Load network weights. """Load network weights.
data_path: The path to the numpy-serialized network weights data_path: The path to the numpy-serialized network weights
session: The current TensorFlow session session: The current TensorFlow session
ignore_missing: If true, serialized weights for missing layers are ignored. ignore_missing: If true, serialized weights for missing layers are ignored.
""" """
data_dict = np.load(data_path, encoding='latin1').item() # pylint: disable=no-member
for op_name in data_dict: for op_name in data_dict:
with tf.variable_scope(op_name, reuse=True): with tf.variable_scope(op_name, reuse=True):
@ -280,21 +256,27 @@ class ONet(Network):
def create_mtcnn(sess, model_path): def create_mtcnn(sess, model_path):
if not model_path: model_dir = os.path.join(os.path.expanduser('~'), '.fawkes')
model_path, _ = os.path.split(os.path.realpath(__file__)) os.makedirs(model_dir, exist_ok=True)
fp = gzip.open(os.path.join(model_dir, "mtcnn.p.gz"), 'rb')
dnet_weights = pickle.load(fp)
fp.close()
with tf.variable_scope('pnet'): with tf.variable_scope('pnet'):
data = tf.placeholder(tf.float32, (None, None, None, 3), 'input') data = tf.placeholder(tf.float32, (None, None, None, 3), 'input')
pnet = PNet({'data': data}) pnet = PNet({'data': data})
pnet.load(os.path.join(model_path, 'weights/det1.npy'), sess)
# data_dict = np.load(data_path, encoding='latin1').item() # pylint: disable=no-member
pnet.load(dnet_weights[0], sess)
with tf.variable_scope('rnet'): with tf.variable_scope('rnet'):
data = tf.placeholder(tf.float32, (None, 24, 24, 3), 'input') data = tf.placeholder(tf.float32, (None, 24, 24, 3), 'input')
rnet = RNet({'data': data}) rnet = RNet({'data': data})
rnet.load(os.path.join(model_path, 'weights/det2.npy'), sess) rnet.load(dnet_weights[1], sess)
with tf.variable_scope('onet'): with tf.variable_scope('onet'):
data = tf.placeholder(tf.float32, (None, 48, 48, 3), 'input') data = tf.placeholder(tf.float32, (None, 48, 48, 3), 'input')
onet = ONet({'data': data}) onet = ONet({'data': data})
onet.load(os.path.join(model_path, 'weights/det3.npy'), sess) onet.load(dnet_weights[2], sess)
pnet_fun = lambda img: sess.run(('pnet/conv4-2/BiasAdd:0', 'pnet/prob1:0'), feed_dict={'pnet/input:0': img}) pnet_fun = lambda img: sess.run(('pnet/conv4-2/BiasAdd:0', 'pnet/prob1:0'), feed_dict={'pnet/input:0': img})
rnet_fun = lambda img: sess.run(('rnet/conv5-2/conv5-2:0', 'rnet/prob1:0'), feed_dict={'rnet/input:0': img}) rnet_fun = lambda img: sess.run(('rnet/conv5-2/conv5-2:0', 'rnet/prob1:0'), feed_dict={'rnet/input:0': img})
@ -303,7 +285,7 @@ def create_mtcnn(sess, model_path):
return pnet_fun, rnet_fun, onet_fun return pnet_fun, rnet_fun, onet_fun
def detect_face(img, minsize, pnet, rnet, onet, threshold, factor): def run_detect_face(img, minsize, pnet, rnet, onet, threshold, factor):
"""Detects faces in an image, and returns bounding boxes and points for them. """Detects faces in an image, and returns bounding boxes and points for them.
img: input image img: input image
minsize: minimum faces' size minsize: minimum faces' size
@ -367,11 +349,15 @@ def detect_face(img, minsize, pnet, rnet, onet, threshold, factor):
tempimg = np.zeros((24, 24, 3, numbox)) tempimg = np.zeros((24, 24, 3, numbox))
for k in range(0, numbox): for k in range(0, numbox):
tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3)) tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
# try:
tmp[dy[k] - 1:edy[k], dx[k] - 1:edx[k], :] = img[y[k] - 1:ey[k], x[k] - 1:ex[k], :] tmp[dy[k] - 1:edy[k], dx[k] - 1:edx[k], :] = img[y[k] - 1:ey[k], x[k] - 1:ex[k], :]
# except ValueError:
# continue
if tmp.shape[0] > 0 and tmp.shape[1] > 0 or tmp.shape[0] == 0 and tmp.shape[1] == 0: if tmp.shape[0] > 0 and tmp.shape[1] > 0 or tmp.shape[0] == 0 and tmp.shape[1] == 0:
tempimg[:, :, :, k] = imresample(tmp, (24, 24)) tempimg[:, :, :, k] = imresample(tmp, (24, 24))
else: else:
return np.empty() return np.empty()
tempimg = (tempimg - 127.5) * 0.0078125 tempimg = (tempimg - 127.5) * 0.0078125
tempimg1 = np.transpose(tempimg, (3, 1, 0, 2)) tempimg1 = np.transpose(tempimg, (3, 1, 0, 2))
out = rnet(tempimg1) out = rnet(tempimg1)
@ -776,18 +762,20 @@ def rerec(bboxA):
def imresample(img, sz): def imresample(img, sz):
im_data = cv2.resize(img, (sz[1], sz[0]), interpolation=cv2.INTER_AREA) # @UndefinedVariable from keras.preprocessing import image
# im_data = resize(img, (sz[0], sz[1]))
im_data = image.array_to_img(img).resize((sz[1], sz[0]))
im_data = image.img_to_array(im_data)
return im_data return im_data
# This method is kept for debugging purpose # def imresample(img, sz):
# h=img.shape[0] # import cv2
# w=img.shape[1] # im_data = cv2.resize(img, (sz[1], sz[0]), interpolation=cv2.INTER_AREA) # @UndefinedVariable
# hs, ws = sz
# dx = float(w) / ws
# dy = float(h) / hs
# im_data = np.zeros((hs,ws,3))
# for a1 in range(0,hs):
# for a2 in range(0,ws):
# for a3 in range(0,3):
# im_data[a1,a2,a3] = img[int(floor(a1*dy)),int(floor(a2*dx)),a3]
# return im_data # return im_data
def to_rgb(img):
w, h = img.shape
ret = np.empty((w, h, 3), dtype=np.uint8)
ret[:, :, 0] = ret[:, :, 1] = ret[:, :, 2] = img
return ret

View File

@ -11,7 +11,7 @@ from decimal import Decimal
import numpy as np import numpy as np
import tensorflow as tf import tensorflow as tf
from .utils import preprocess, reverse_preprocess from fawkes.utils import preprocess, reverse_preprocess
class FawkesMaskGeneration: class FawkesMaskGeneration:

View File

@ -8,13 +8,16 @@ import os
import random import random
import sys import sys
import time import time
import tensorflow as tf
import logging
logging.getLogger('tensorflow').disabled = True
import numpy as np import numpy as np
from fawkes.differentiator import FawkesMaskGeneration
from .differentiator import FawkesMaskGeneration from fawkes.utils import load_extractor, init_gpu, select_target_label, dump_image, reverse_process_cloaked, \
from .utils import load_extractor, init_gpu, select_target_label, dump_image, reverse_process_cloaked, \
Faces Faces
random.seed(12243) random.seed(12243)
np.random.seed(122412) np.random.seed(122412)
@ -63,11 +66,11 @@ def main(*argv):
parser.add_argument('--directory', '-d', type=str, parser.add_argument('--directory', '-d', type=str,
help='directory that contain images for cloaking', default='imgs/') help='directory that contain images for cloaking', default='imgs/')
parser.add_argument('--gpu', type=str, parser.add_argument('--gpu', '-g', type=str,
help='GPU id', default='0') help='GPU id', default='0')
parser.add_argument('--mode', type=str, parser.add_argument('--mode', '-m', type=str,
help='cloak generation mode', default='high') help='cloak generation mode', default='mid')
parser.add_argument('--feature-extractor', type=str, parser.add_argument('--feature-extractor', type=str,
help="name of the feature extractor used for optimization", help="name of the feature extractor used for optimization",
default="high_extract") default="high_extract")
@ -88,12 +91,12 @@ def main(*argv):
if args.mode == 'low': if args.mode == 'low':
args.feature_extractor = "high_extract" args.feature_extractor = "high_extract"
args.th = 0.003 args.th = 0.003
args.max_step = 100 args.max_step = 20
args.lr = 15 args.lr = 20
elif args.mode == 'mid': elif args.mode == 'mid':
args.feature_extractor = "high_extract" args.feature_extractor = "high_extract"
args.th = 0.005 args.th = 0.004
args.max_step = 100 args.max_step = 50
args.lr = 15 args.lr = 15
elif args.mode == 'high': elif args.mode == 'high':
args.feature_extractor = "high_extract" args.feature_extractor = "high_extract"
@ -101,10 +104,14 @@ def main(*argv):
args.max_step = 100 args.max_step = 100
args.lr = 10 args.lr = 10
elif args.mode == 'ultra': elif args.mode == 'ultra':
if not tf.test.is_gpu_available():
print("Please enable GPU for ultra setting...")
sys.exit(1)
# args.feature_extractor = ["high_extract", 'high2_extract']
args.feature_extractor = "high_extract" args.feature_extractor = "high_extract"
args.th = 0.01 args.th = 0.015
args.max_step = 1000 args.max_step = 2000
args.lr = 5 args.lr = 8
elif args.mode == 'custom': elif args.mode == 'custom':
pass pass
else: else:
@ -115,20 +122,23 @@ def main(*argv):
args.format = 'jpeg' args.format = 'jpeg'
sess = init_gpu(args.gpu) sess = init_gpu(args.gpu)
fs_names = [args.feature_extractor]
feature_extractors_ls = [load_extractor(name) for name in fs_names]
image_paths = glob.glob(os.path.join(args.directory, "*")) image_paths = glob.glob(os.path.join(args.directory, "*"))
image_paths = [path for path in image_paths if "_cloaked" not in path.split("/")[-1]] image_paths = [path for path in image_paths if "_cloaked" not in path.split("/")[-1]]
if not image_paths: if not image_paths:
print("No images in the directory") raise Exception("No images in the directory")
exit(1)
faces = Faces(image_paths, sess, verbose=1) faces = Faces(image_paths, sess, verbose=1)
orginal_images = faces.cropped_faces orginal_images = faces.cropped_faces
orginal_images = np.array(orginal_images) orginal_images = np.array(orginal_images)
fs_names = [args.feature_extractor]
if isinstance(args.feature_extractor, list):
fs_names = args.feature_extractor
feature_extractors_ls = [load_extractor(name) for name in fs_names]
if args.separate_target: if args.separate_target:
target_embedding = [] target_embedding = []
for org_img in orginal_images: for org_img in orginal_images:
@ -154,6 +164,7 @@ def main(*argv):
elapsed_time = time.time() - start_time elapsed_time = time.time() - start_time
print('attack cost %f s' % (elapsed_time)) print('attack cost %f s' % (elapsed_time))
print("Done!")
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -27,8 +27,7 @@ from keras.preprocessing import image
from skimage.transform import resize from skimage.transform import resize
from sklearn.metrics import pairwise_distances from sklearn.metrics import pairwise_distances
from fawkes.align_face import align, aligner
from .align_face import align, aligner
from six.moves.urllib.request import urlopen from six.moves.urllib.request import urlopen
if sys.version_info[0] == 2: if sys.version_info[0] == 2:
@ -89,6 +88,12 @@ def load_image(path):
class Faces(object): class Faces(object):
def __init__(self, image_paths, sess, verbose=1): def __init__(self, image_paths, sess, verbose=1):
model_dir = os.path.join(os.path.expanduser('~'), '.fawkes')
if not os.path.exists(os.path.join(model_dir, "mtcnn.p.gz")):
os.makedirs(model_dir, exist_ok=True)
get_file("mtcnn.p.gz", "http://sandlab.cs.uchicago.edu/fawkes/files/mtcnn.p.gz", cache_dir=model_dir,
cache_subdir='')
self.verbose = verbose self.verbose = verbose
self.aligner = aligner(sess) self.aligner = aligner(sess)
self.org_faces = [] self.org_faces = []
@ -102,6 +107,10 @@ class Faces(object):
cur_img = load_image(p) cur_img = load_image(p)
self.org_faces.append(cur_img) self.org_faces.append(cur_img)
align_img = align(cur_img, self.aligner, margin=0.7) align_img = align(cur_img, self.aligner, margin=0.7)
if align_img is None:
print("Find 0 face(s) in {}".format(p.split("/")[-1]))
continue
cur_faces = align_img[0] cur_faces = align_img[0]
cur_shapes = [f.shape[:-1] for f in cur_faces] cur_shapes = [f.shape[:-1] for f in cur_faces]
@ -327,6 +336,7 @@ def load_extractor(name):
if os.path.exists(model_file): if os.path.exists(model_file):
model = keras.models.load_model(model_file) model = keras.models.load_model(model_file)
else: else:
print("Download models...")
get_file("{}.h5".format(name), "http://sandlab.cs.uchicago.edu/fawkes/files/{}.h5".format(name), get_file("{}.h5".format(name), "http://sandlab.cs.uchicago.edu/fawkes/files/{}.h5".format(name),
cache_dir=model_dir, cache_subdir='') cache_dir=model_dir, cache_subdir='')
model = keras.models.load_model(model_file) model = keras.models.load_model(model_file)
@ -568,152 +578,3 @@ def _makedirs_exist_ok(datadir):
raise raise
else: else:
os.makedirs(datadir, exist_ok=True) # pylint: disable=unexpected-keyword-arg os.makedirs(datadir, exist_ok=True) # pylint: disable=unexpected-keyword-arg
# class CloakData(object):
# def __init__(self, protect_directory=None, img_shape=(224, 224)):
#
# self.img_shape = img_shape
# # self.train_data_dir, self.test_data_dir, self.number_classes, self.number_samples = get_dataset_path(dataset)
# # self.all_labels = sorted(list(os.listdir(self.train_data_dir)))
# self.protect_directory = protect_directory
#
# self.protect_X = self.load_label_data(self.protect_directory)
#
# self.cloaked_protect_train_X = None
#
# self.label2path_train, self.label2path_test, self.path2idx = self.build_data_mapping()
# self.all_training_path = self.get_all_data_path(self.label2path_train)
# self.all_test_path = self.get_all_data_path(self.label2path_test)
# self.protect_class_path = self.get_class_image_files(os.path.join(self.train_data_dir, self.protect_class))
#
# def get_class_image_files(self, path):
# return [os.path.join(path, f) for f in os.listdir(path)]
#
# def extractor_ls_predict(self, feature_extractors_ls, X):
# feature_ls = []
# for extractor in feature_extractors_ls:
# cur_features = extractor.predict(X)
# feature_ls.append(cur_features)
# concated_feature_ls = np.concatenate(feature_ls, axis=1)
# concated_feature_ls = normalize(concated_feature_ls)
# return concated_feature_ls
#
# def load_embeddings(self, feature_extractors_names):
# dictionaries = []
# for extractor_name in feature_extractors_names:
# path2emb = pickle.load(open("../feature_extractors/embeddings/{}_emb_norm.p".format(extractor_name), "rb"))
# dictionaries.append(path2emb)
#
# merge_dict = {}
# for k in dictionaries[0].keys():
# cur_emb = [dic[k] for dic in dictionaries]
# merge_dict[k] = np.concatenate(cur_emb)
# return merge_dict
#
# def select_target_label(self, feature_extractors_ls, feature_extractors_names, metric='l2'):
# original_feature_x = self.extractor_ls_predict(feature_extractors_ls, self.protect_train_X)
#
# path2emb = self.load_embeddings(feature_extractors_names)
# items = list(path2emb.items())
# paths = [p[0] for p in items]
# embs = [p[1] for p in items]
# embs = np.array(embs)
#
# pair_dist = pairwise_distances(original_feature_x, embs, metric)
# max_sum = np.min(pair_dist, axis=0)
# sorted_idx = np.argsort(max_sum)[::-1]
#
# highest_num = 0
# paired_target_X = None
# final_target_class_path = None
# for idx in sorted_idx[:5]:
# target_class_path = paths[idx]
# cur_target_X = self.load_dir(target_class_path)
# cur_target_X = np.concatenate([cur_target_X, cur_target_X, cur_target_X])
# cur_tot_sum, cur_paired_target_X = self.calculate_dist_score(self.protect_train_X, cur_target_X,
# feature_extractors_ls,
# metric=metric)
# if cur_tot_sum > highest_num:
# highest_num = cur_tot_sum
# paired_target_X = cur_paired_target_X
# final_target_class_path = target_class_path
#
# np.random.shuffle(paired_target_X)
# return final_target_class_path, paired_target_X
#
# def calculate_dist_score(self, a, b, feature_extractors_ls, metric='l2'):
# features1 = self.extractor_ls_predict(feature_extractors_ls, a)
# features2 = self.extractor_ls_predict(feature_extractors_ls, b)
#
# pair_cos = pairwise_distances(features1, features2, metric)
# max_sum = np.min(pair_cos, axis=0)
# max_sum_arg = np.argsort(max_sum)[::-1]
# max_sum_arg = max_sum_arg[:len(a)]
# max_sum = [max_sum[i] for i in max_sum_arg]
# paired_target_X = [b[j] for j in max_sum_arg]
# paired_target_X = np.array(paired_target_X)
# return np.min(max_sum), paired_target_X
#
# def get_all_data_path(self, label2path):
# all_paths = []
# for k, v in label2path.items():
# cur_all_paths = [os.path.join(k, cur_p) for cur_p in v]
# all_paths.extend(cur_all_paths)
# return all_paths
#
# def load_label_data(self, label):
# train_label_path = os.path.join(self.train_data_dir, label)
# test_label_path = os.path.join(self.test_data_dir, label)
# train_X = self.load_dir(train_label_path)
# test_X = self.load_dir(test_label_path)
# return train_X, test_X
#
# def load_dir(self, path):
# assert os.path.exists(path)
# x_ls = []
# for file in os.listdir(path):
# cur_path = os.path.join(path, file)
# im = image.load_img(cur_path, target_size=self.img_shape)
# im = image.img_to_array(im)
# x_ls.append(im)
# raw_x = np.array(x_ls)
# return preprocess_input(raw_x)
#
# def build_data_mapping(self):
# label2path_train = {}
# label2path_test = {}
# idx = 0
# path2idx = {}
# for label_name in self.all_labels:
# full_path_train = os.path.join(self.train_data_dir, label_name)
# full_path_test = os.path.join(self.test_data_dir, label_name)
# label2path_train[full_path_train] = list(os.listdir(full_path_train))
# label2path_test[full_path_test] = list(os.listdir(full_path_test))
# for img_file in os.listdir(full_path_train):
# path2idx[os.path.join(full_path_train, img_file)] = idx
# for img_file in os.listdir(full_path_test):
# path2idx[os.path.join(full_path_test, img_file)] = idx
# idx += 1
# return label2path_train, label2path_test, path2idx
#
# def generate_data_post_cloak(self, sybil=False):
# assert self.cloaked_protect_train_X is not None
# while True:
# batch_X = []
# batch_Y = []
# cur_batch_path = random.sample(self.all_training_path, 32)
# for p in cur_batch_path:
# cur_y = self.path2idx[p]
# if p in self.protect_class_path:
# cur_x = random.choice(self.cloaked_protect_train_X)
# elif sybil and (p in self.sybil_class):
# cur_x = random.choice(self.cloaked_sybil_train_X)
# else:
# im = image.load_img(p, target_size=self.img_shape)
# im = image.img_to_array(im)
# cur_x = preprocess_input(im)
# batch_X.append(cur_x)
# batch_Y.append(cur_y)
# batch_X = np.array(batch_X)
# batch_Y = to_categorical(np.array(batch_Y), num_classes=self.number_classes)
# yield batch_X, batch_Y

View File

@ -46,7 +46,8 @@ def detect_face(image_url):
conn.request("POST", "/face/v1.0/detect?%s" % params, body, headers) conn.request("POST", "/face/v1.0/detect?%s" % params, body, headers)
response = conn.getresponse() response = conn.getresponse()
data = json.loads(response.read()) data = json.loads(response.read())
print(data) #
# print(data)
conn.close() conn.close()
return data[0]["faceId"] return data[0]["faceId"]
@ -229,7 +230,6 @@ def eval(original_faceIds, personGroupId, protect_personId):
response = conn.getresponse() response = conn.getresponse()
data = json.loads(response.read()) data = json.loads(response.read())
conn.close() conn.close()
face = data[0] face = data[0]
print(face) print(face)
if len(face["candidates"]) and face["candidates"][0]["personId"] == protect_personId: if len(face["candidates"]) and face["candidates"][0]["personId"] == protect_personId:
@ -270,8 +270,8 @@ def get_trainStatus(personGroupId):
conn.request("GET", "/face/v1.0/persongroups/{}/training?%s".format(personGroupId) % params, body, headers) conn.request("GET", "/face/v1.0/persongroups/{}/training?%s".format(personGroupId) % params, body, headers)
response = conn.getresponse() response = conn.getresponse()
data = response.read() data = response.read()
print(data)
conn.close() conn.close()
return data
def test_cloak(): def test_cloak():
@ -279,12 +279,12 @@ def test_cloak():
total_idx = range(0, 82) total_idx = range(0, 82)
TRAIN_RANGE = random.sample(total_idx, NUM_TRAIN) TRAIN_RANGE = random.sample(total_idx, NUM_TRAIN)
TEST_RANGE = TRAIN_RANGE TEST_RANGE = random.sample([i for i in total_idx if i not in TRAIN_RANGE], 20)
personGroupId = 'all' personGroupId = 'all'
# delete_personGroup(personGroupId) # delete_personGroup(personGroupId)
create_personGroupId(personGroupId, personGroupId) # create_personGroupId(personGroupId, personGroupId)
with open("protect_personId.txt", 'r') as f: with open("protect_personId.txt", 'r') as f:
protect_personId = f.read() protect_personId = f.read()
@ -305,22 +305,25 @@ def test_cloak():
print("Unable to add {}-th image of protect person".format(idx)) print("Unable to add {}-th image of protect person".format(idx))
# add other people # add other people
for idx_person in range(500): # for idx_person in range(1300, 5000):
personId = create_personId(personGroupId, str(idx_person)) # personId = create_personId(personGroupId, str(idx_person))
print("Created personId: {}".format(idx_person)) # print("Created personId: {}".format(idx_person))
for idx_image in range(10): # for idx_image in range(10):
image_url = "http://sandlab.cs.uchicago.edu/fawkes/files/target_data/{}/{}.jpg".format( # image_url = "http://sandlab.cs.uchicago.edu/fawkes/files/target_data/{}/{}.jpg".format(
idx_person, idx_image) # idx_person, idx_image)
r = add_persistedFaceId(personGroupId, personId, image_url) # r = add_persistedFaceId(personGroupId, personId, image_url)
if r is not None: # if r is not None:
print("Added {}".format(idx_image)) # print("Added {}".format(idx_image))
else: # else:
print("Unable to add {}-th image".format(idx_image)) # print("Unable to add {}-th image".format(idx_image))
# train model based on personGroup # train model based on personGroup
train_personGroup(personGroupId) train_personGroup(personGroupId)
time.sleep(4)
get_trainStatus(personGroupId) while json.loads(get_trainStatus(personGroupId))['status'] != 'succeeded':
time.sleep(2)
# list_personGroupPerson(personGroupId) # list_personGroupPerson(personGroupId)
# test original image # test original image

View File

@ -1,4 +0,0 @@
scikit-image
argparse
glob
numpy==1.18.4

View File

@ -75,13 +75,15 @@ class DeployCommand(Command):
setup_requires = [] setup_requires = []
install_requires = [ install_requires = [
'numpy>=1.16.4', 'numpy==1.16.4',
'tensorflow>=1.13.1', # 'tensorflow-gpu>=1.13.1, <=1.14.0',
'tensorflow>=1.13.1, <=1.14.0',
'argparse', 'argparse',
'keras==2.2.5', 'keras==2.2.5',
'scikit-image', 'scikit-image',
'pillow>=7.0.0', 'pillow>=7.0.0',
'opencv-python>=4.2.0.34', 'opencv-python>=4.2.0.34',
'sklearn',
] ]
setup( setup(