diff --git a/fawkes/__init__.py b/fawkes/__init__.py index 69a386f..b983fb9 100644 --- a/fawkes/__init__.py +++ b/fawkes/__init__.py @@ -4,7 +4,7 @@ # @Link : https://www.shawnshan.com/ -__version__ = '0.0.9' +__version__ = '0.1.0' from .detect_faces import create_mtcnn, run_detect_face from .differentiator import FawkesMaskGeneration diff --git a/fawkes/differentiator.py b/fawkes/differentiator.py index 18bf4f8..3ead798 100644 --- a/fawkes/differentiator.py +++ b/fawkes/differentiator.py @@ -48,7 +48,7 @@ class FawkesMaskGeneration: max_iterations=MAX_ITERATIONS, initial_const=INITIAL_CONST, intensity_range=INTENSITY_RANGE, l_threshold=L_THRESHOLD, max_val=MAX_VAL, keep_final=KEEP_FINAL, maximize=MAXIMIZE, image_shape=IMAGE_SHAPE, - verbose=0, ratio=RATIO, limit_dist=LIMIT_DIST, faces=None): + verbose=0, ratio=RATIO, limit_dist=LIMIT_DIST): assert intensity_range in {'raw', 'imagenet', 'inception', 'mnist'} @@ -70,7 +70,6 @@ class FawkesMaskGeneration: self.ratio = ratio self.limit_dist = limit_dist self.single_shape = list(image_shape) - self.faces = faces self.input_shape = tuple([self.batch_size] + self.single_shape) @@ -168,7 +167,8 @@ class FawkesMaskGeneration: self.bottlesim_sum = 0.0 self.bottlesim_push = 0.0 for bottleneck_model in bottleneck_model_ls: - model_input_shape = bottleneck_model.input_shape[1:] + model_input_shape = (224, 224, 3) + cur_aimg_input = resize_tensor(self.aimg_input, model_input_shape) self.bottleneck_a = bottleneck_model(cur_aimg_input) @@ -267,7 +267,7 @@ class FawkesMaskGeneration: % int(np.ceil(len(source_imgs) / self.batch_size))) for idx in range(0, len(source_imgs), self.batch_size): - print('processing batch %d at %s' % (idx, datetime.datetime.now())) + print('processing image %d at %s' % (idx+1, datetime.datetime.now())) adv_img = self.attack_batch(source_imgs[idx:idx + self.batch_size], target_imgs[idx:idx + self.batch_size], weights[idx:idx + self.batch_size]) @@ -315,8 +315,6 @@ class FawkesMaskGeneration: weights_batch[:nb_imgs] = weights[:nb_imgs] modifier_batch = np.ones(self.input_shape) * 1e-6 - temp_images = [] - # set the variables so that we don't have to send them over again if self.MIMIC_IMG: self.sess.run(self.setup, @@ -407,8 +405,9 @@ class FawkesMaskGeneration: if all_clear: break - if iteration != 0 and iteration % (self.MAX_ITERATIONS // 2) == 0: + if iteration != 0 and iteration % (self.MAX_ITERATIONS // 3) == 0: LR = LR * 0.8 + print("LR: {}".format(LR)) if iteration % (self.MAX_ITERATIONS // 5) == 0: if self.verbose == 1: diff --git a/fawkes/protection.py b/fawkes/protection.py index 188bae3..09430a9 100644 --- a/fawkes/protection.py +++ b/fawkes/protection.py @@ -6,9 +6,7 @@ import argparse import glob import logging import os -import random import sys -import time import tensorflow as tf @@ -22,26 +20,9 @@ from fawkes.utils import load_extractor, init_gpu, select_target_label, dump_ima from fawkes.align_face import aligner from fawkes.utils import get_file -random.seed(12243) -np.random.seed(122412) - -def generate_cloak_images(sess, feature_extractors, image_X, target_emb=None, th=0.01, faces=None, sd=1e9, lr=2, - max_step=500, batch_size=1, debug=False): - batch_size = batch_size if len(image_X) > batch_size else len(image_X) - - differentiator = FawkesMaskGeneration(sess, feature_extractors, - batch_size=batch_size, - mimic_img=True, - intensity_range='imagenet', - initial_const=sd, - learning_rate=lr, - max_iterations=max_step, - l_threshold=th, - verbose=1 if debug else 0, maximize=False, keep_final=False, image_shape=image_X.shape[1:], - faces=faces) - - cloaked_image_X = differentiator.attack(image_X, target_emb) +def generate_cloak_images(protector, image_X, target_emb=None): + cloaked_image_X = protector.attack(image_X, target_emb) return cloaked_image_X @@ -79,6 +60,9 @@ class Fawkes(object): self.aligner = aligner(sess) self.feature_extractors_ls = [load_extractor(name) for name in self.fs_names] + self.protector = None + self.protector_param = None + def mode2param(self, mode): if mode == 'low': th = 0.003 @@ -86,12 +70,12 @@ class Fawkes(object): lr = 20 elif mode == 'mid': th = 0.005 - max_step = 100 - lr = 20 + max_step = 120 + lr = 15 elif mode == 'high': th = 0.008 - max_step = 200 - lr = 20 + max_step = 600 + lr = 10 elif mode == 'ultra': if not tf.test.is_gpu_available(): print("Please enable GPU for ultra setting...") @@ -103,7 +87,7 @@ class Fawkes(object): raise Exception("mode must be one of 'low', 'mid', 'high', 'ultra', 'custom'") return th, max_step, lr - def run_protection(self, image_paths, mode='mid', th=0.04, sd=1e9, lr=10, max_step=500, batch_size=1, format='png', + def run_protection(self, image_paths, mode='low', th=0.04, sd=1e9, lr=10, max_step=500, batch_size=1, format='png', separate_target=True, debug=False): if mode == 'custom': @@ -111,6 +95,9 @@ class Fawkes(object): else: th, max_step, lr = self.mode2param(mode) + current_param = "-".join([str(x) for x in [mode, th, sd, lr, max_step, batch_size, format, + separate_target, debug]]) + image_paths, loaded_images = filter_image_paths(image_paths) if not image_paths: @@ -132,9 +119,27 @@ class Fawkes(object): else: target_embedding = select_target_label(original_images, self.feature_extractors_ls, self.fs_names) - protected_images = generate_cloak_images(sess, self.feature_extractors_ls, original_images, - target_emb=target_embedding, th=th, faces=faces, sd=sd, - lr=lr, max_step=max_step, batch_size=batch_size, debug=debug) + if current_param != self.protector_param: + self.protector_param = current_param + + if self.protector is not None: + del self.protector + + self.protector = FawkesMaskGeneration(sess, self.feature_extractors_ls, + batch_size=batch_size, + mimic_img=True, + intensity_range='imagenet', + initial_const=sd, + learning_rate=lr, + max_iterations=max_step, + l_threshold=th, + verbose=1 if debug else 0, + maximize=False, + keep_final=False, + image_shape=(224, 224, 3)) + + protected_images = generate_cloak_images(self.protector, original_images, + target_emb=target_embedding) faces.cloaked_cropped_faces = protected_images @@ -145,7 +150,7 @@ class Fawkes(object): for p_img, path in zip(final_images, image_paths): file_name = "{}_{}_cloaked.{}".format(".".join(path.split(".")[:-1]), mode, format) dump_image(p_img, file_name, format=format) - # elapsed_time = time.time() - start_time + print("Done!") return None diff --git a/fawkes/utils.py b/fawkes/utils.py index d893b0e..c0748de 100644 --- a/fawkes/utils.py +++ b/fawkes/utils.py @@ -141,6 +141,9 @@ class Faces(object): if verbose: print("Find {} face(s) in {}".format(len(cur_faces), p.split("/")[-1])) + if eval_local: + cur_faces = cur_faces[:1] + for img in cur_faces: if eval_local: base = resize(img, (224, 224)) @@ -150,6 +153,7 @@ class Faces(object): base[0:img.shape[0], 0:img.shape[1], :] = img cur_faces_square.append(base) + cur_index = align_img[1] cur_faces_square = [resize(f, (224, 224)) for f in cur_faces_square] self.cropped_faces_shape.extend(cur_shapes) diff --git a/setup.py b/setup.py index ed83cfa..6a61608 100644 --- a/setup.py +++ b/setup.py @@ -77,7 +77,7 @@ setup_requires = [] install_requires = [ 'numpy==1.16.4', # 'tensorflow-gpu>=1.13.1, <=1.14.0', - 'tensorflow>=1.12.0, <=1.15.0', + 'tensorflow>=1.12.0, <=1.15.0', # change this is tensorflow-gpu if using GPU machine. 'argparse', 'keras>=2.2.5, <=2.3.1', 'scikit-image', @@ -88,7 +88,7 @@ install_requires = [ setup( name='fawkes', version=__version__, - license='MIT', + license='BSD', description='An utility to protect user privacy', long_description=long_description, long_description_content_type='text/markdown', @@ -114,5 +114,5 @@ setup( }, include_package_data=True, zip_safe=False, - python_requires='>=3.5', + python_requires='>=3.5,<3.8', )