''' ART-JATIC Gradio Example App To run: - clone the repository - execute: gradio examples/gradio_app.py or python examples/gradio_app.py - navigate to local URL e.g. http://127.0.0.1:7860 ''' import gradio as gr import numpy as np from carbon_theme import Carbon import os import numpy as np import matplotlib.pyplot as plt import torch import transformers from art.estimators.classification.hugging_face import HuggingFaceClassifierPyTorch from art.attacks.evasion import ProjectedGradientDescentPyTorch, AdversarialPatchPyTorch from art.utils import load_dataset from art.attacks.poisoning import PoisoningAttackBackdoor from art.attacks.poisoning.perturbations import insert_image device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') css = """ .input-image { margin: auto !important } .plot-padding { padding: 20px; } """ def clf_evasion_evaluate(*args): ''' Run a classification task evaluation ''' attack = args[0] model_type = args[1] model_url = args[2] model_channels = args[3] model_height = args[4] model_width = args[5] model_classes = args[6] model_clip = args[7] model_upsample = args[8] attack_max_iter = args[9] attack_eps = args[10] attack_eps_steps = args[11] x_location = args[12] y_location = args[13] patch_height = args[14] patch_width = args[15] data_type = args[-1] if model_type == "Example": model = transformers.AutoModelForImageClassification.from_pretrained( 'facebook/deit-tiny-distilled-patch16-224', ignore_mismatched_sizes=True, num_labels=10 ) upsampler = torch.nn.Upsample(scale_factor=7, mode='nearest') optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) loss_fn = torch.nn.CrossEntropyLoss() hf_model = HuggingFaceClassifierPyTorch( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(3, 32, 32), nb_classes=10, clip_values=(0, 1), processor=upsampler ) model_checkpoint_path = './state_dicts/deit_cifar_base_model.pt' hf_model.model.load_state_dict(torch.load(model_checkpoint_path, map_location=device)) if data_type == "Example": (x_train, y_train), (_, _), _, _ = load_dataset('cifar10') x_train = np.transpose(x_train, (0, 3, 1, 2)).astype(np.float32) y_train = np.argmax(y_train, axis=1) classes = np.unique(y_train) samples_per_class = 1 x_subset = [] y_subset = [] for c in classes: indices = y_train == c x_subset.append(x_train[indices][:samples_per_class]) y_subset.append(y_train[indices][:samples_per_class]) x_subset = np.concatenate(x_subset) y_subset = np.concatenate(y_subset) label_names = [ 'airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck', ] outputs = hf_model.predict(x_subset) clean_preds = np.argmax(outputs, axis=1) clean_acc = np.mean(clean_preds == y_subset) benign_gallery_out = [] for i, im in enumerate(x_subset): benign_gallery_out.append(( im.transpose(1,2,0), label_names[np.argmax(outputs[i])] )) if attack == "PGD": attacker = ProjectedGradientDescentPyTorch(hf_model, max_iter=attack_max_iter, eps=attack_eps, eps_step=attack_eps_steps) x_adv = attacker.generate(x_subset) outputs = hf_model.predict(x_adv) adv_preds = np.argmax(outputs, axis=1) adv_acc = np.mean(adv_preds == y_subset) adv_gallery_out = [] for i, im in enumerate(x_adv): adv_gallery_out.append(( im.transpose(1,2,0), label_names[np.argmax(outputs[i])] )) delta = ((x_subset - x_adv) + 8/255) * 10 delta_gallery_out = delta.transpose(0, 2, 3, 1) if attack == "Adversarial Patch": scale_min = 0.3 scale_max = 1.0 rotation_max = 0 learning_rate = 5000. attacker = AdversarialPatchPyTorch(hf_model, scale_max=scale_max, scale_min=scale_min, rotation_max=rotation_max, learning_rate=learning_rate, max_iter=attack_max_iter, patch_type='square', patch_location=(x_location, y_location), patch_shape=(3, patch_height, patch_width)) patch, _ = attacker.generate(x_subset) x_adv = attacker.apply_patch(x_subset, scale=0.3) outputs = hf_model.predict(x_adv) adv_preds = np.argmax(outputs, axis=1) adv_acc = np.mean(adv_preds == y_subset) adv_gallery_out = [] for i, im in enumerate(x_adv): adv_gallery_out.append(( im.transpose(1,2,0), label_names[np.argmax(outputs[i])] )) delta_gallery_out = np.expand_dims(patch, 0).transpose(0,2,3,1) return benign_gallery_out, adv_gallery_out, delta_gallery_out, clean_acc, adv_acc def clf_poison_evaluate(*args): attack = args[0] model_type = args[1] trigger_image = args[2] target_class = args[3] data_type = args[-1] if model_type == "Example": model = transformers.AutoModelForImageClassification.from_pretrained( 'facebook/deit-tiny-distilled-patch16-224', ignore_mismatched_sizes=True, num_labels=10 ) optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) loss_fn = torch.nn.CrossEntropyLoss() hf_model = HuggingFaceClassifierPyTorch( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(3, 224, 224), nb_classes=10, clip_values=(0, 1), ) if data_type == "Example": import torchvision transform = torchvision.transforms.Compose([ torchvision.transforms.Resize((224, 224)), torchvision.transforms.ToTensor(), ]) train_dataset = torchvision.datasets.ImageFolder(root="./data/imagenette2-320/train", transform=transform) labels = np.asarray(train_dataset.targets) classes = np.unique(labels) samples_per_class = 100 x_subset = [] y_subset = [] for c in classes: indices = np.where(labels == c)[0][:samples_per_class] for i in indices: x_subset.append(train_dataset[i][0]) y_subset.append(train_dataset[i][1]) x_subset = np.stack(x_subset) y_subset = np.asarray(y_subset) label_names = [ 'fish', 'dog', 'cassette player', 'chainsaw', 'church', 'french horn', 'garbage truck', 'gas pump', 'golf ball', 'parachutte', ] if attack == "Backdoor": from PIL import Image im = Image.fromarray(trigger_image) im.save("./tmp.png") def poison_func(x): return insert_image( x, backdoor_path='./tmp.png', channels_first=True, random=False, x_shift=0, y_shift=0, size=(32, 32), mode='RGB', blend=0.8 ) backdoor = PoisoningAttackBackdoor(poison_func) source_class = 0 poison_percent = 0.5 x_poison = np.copy(x_subset) y_poison = np.copy(y_subset) is_poison = np.zeros(len(x_subset)).astype(bool) indices = np.where(y_subset == source_class)[0] num_poison = int(poison_percent * len(indices)) for i in indices[:num_poison]: x_poison[i], _ = backdoor.poison(x_poison[i], []) y_poison[i] = target_class is_poison[i] = True poison_indices = np.where(is_poison)[0] hf_model.fit(x_poison, y_poison, nb_epochs=2) clean_x = x_poison[~is_poison] clean_y = y_poison[~is_poison] outputs = hf_model.predict(clean_x) clean_preds = np.argmax(outputs, axis=1) clean_acc = np.mean(clean_preds == clean_y) poison_x = x_poison[is_poison] poison_y = y_poison[is_poison] outputs = hf_model.predict(poison_x) poison_preds = np.argmax(outputs, axis=1) poison_acc = np.mean(poison_preds == poison_y) poison_out = [] for i, im in enumerate(poison_x): poison_out.append( (im.transpose(1,2,0), label_names[poison_preds[i]]) ) return poison_out, clean_acc, poison_acc def show_params(type): ''' Show model parameters based on selected model type ''' if type!="Example": return gr.Column(visible=True) return gr.Column(visible=False) def run_inference(*args): model_type = args[0] model_url = args[1] model_channels = args[2] model_height = args[3] model_width = args[4] model_classes = args[5] model_clip = args[6] model_upsample = args[7] data_type = args[8] if model_type == "Example": model = transformers.AutoModelForImageClassification.from_pretrained( 'facebook/deit-tiny-distilled-patch16-224', ignore_mismatched_sizes=True, num_labels=10 ) upsampler = torch.nn.Upsample(scale_factor=7, mode='nearest') optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) loss_fn = torch.nn.CrossEntropyLoss() hf_model = HuggingFaceClassifierPyTorch( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(3, 32, 32), nb_classes=10, clip_values=(0, 1), processor=upsampler ) model_checkpoint_path = './state_dicts/deit_cifar_base_model.pt' hf_model.model.load_state_dict(torch.load(model_checkpoint_path, map_location=device)) if data_type == "Example": (x_train, y_train), (_, _), _, _ = load_dataset('cifar10') x_train = np.transpose(x_train, (0, 3, 1, 2)).astype(np.float32) y_train = np.argmax(y_train, axis=1) classes = np.unique(y_train) samples_per_class = 5 x_subset = [] y_subset = [] for c in classes: indices = y_train == c x_subset.append(x_train[indices][:samples_per_class]) y_subset.append(y_train[indices][:samples_per_class]) x_subset = np.concatenate(x_subset) y_subset = np.concatenate(y_subset) label_names = [ 'airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck', ] outputs = hf_model.predict(x_subset) clean_preds = np.argmax(outputs, axis=1) clean_acc = np.mean(clean_preds == y_subset) gallery_out = [] for i, im in enumerate(x_subset): gallery_out.append(( im.transpose(1,2,0), label_names[np.argmax(outputs[i])] )) return gallery_out, clean_acc # e.g. To use a local alternative theme: carbon_theme = Carbon() carbon_theme = Carbon() with gr.Blocks(css=css, theme=gr.themes.Base()) as demo: import art text = art.__version__ with gr.Row(): with gr.Column(scale=1): gr.Image(value="./art_lfai.png", show_label=False, show_download_button=False, width=100) with gr.Column(scale=20): gr.Markdown(f"