''' 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 torch import numpy as np import pandas as pd from carbon_theme import Carbon import gradio as gr import os import matplotlib.pyplot as plt css = """ .input-image { margin: auto !important } .plot-padding { padding: 20px; } """ def extract_predictions(predictions_, conf_thresh): coco_labels = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'] # Get the predicted class predictions_class = [coco_labels[i] for i in list(predictions_["labels"])] # print("\npredicted classes:", predictions_class) if len(predictions_class) < 1: return [], [], [] # Get the predicted bounding boxes predictions_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(predictions_["boxes"])] # Get the predicted prediction score predictions_score = list(predictions_["scores"]) # print("predicted score:", predictions_score) # Get a list of index with score greater than threshold threshold = conf_thresh predictions_t = [predictions_score.index(x) for x in predictions_score if x > threshold] if len(predictions_t) > 0: predictions_t = predictions_t # [-1] #indices where score over threshold else: # no predictions esxceeding threshold return [], [], [] # predictions in score order predictions_boxes = [predictions_boxes[i] for i in predictions_t] predictions_class = [predictions_class[i] for i in predictions_t] predictions_scores = [predictions_score[i] for i in predictions_t] return predictions_class, predictions_boxes, predictions_scores def plot_image_with_boxes(img, boxes, pred_cls, title): import cv2 text_size = 1 text_th = 2 rect_th = 1 sections = [] for i in range(len(boxes)): cv2.rectangle(img, (int(boxes[i][0][0]), int(boxes[i][0][1])), (int(boxes[i][1][0]), int(boxes[i][1][1])), color=(0, 255, 0), thickness=rect_th) # Write the prediction class cv2.putText(img, pred_cls[i], (int(boxes[i][0][0]), int(boxes[i][0][1])), cv2.FONT_HERSHEY_SIMPLEX, text_size, (0, 255, 0), thickness=text_th) sections.append( ((int(boxes[i][0][0]), int(boxes[i][0][1]), int(boxes[i][1][0]), int(boxes[i][1][1])), (pred_cls[i])) ) return img.astype(np.uint8) def filter_boxes(predictions, conf_thresh): dictionary = {} boxes_list = [] scores_list = [] labels_list = [] for i in range(len(predictions[0]["boxes"])): score = predictions[0]["scores"][i] if score >= conf_thresh: boxes_list.append(predictions[0]["boxes"][i]) scores_list.append(predictions[0]["scores"][[i]]) labels_list.append(predictions[0]["labels"][[i]]) dictionary["boxes"] = np.vstack(boxes_list) dictionary["scores"] = np.hstack(scores_list) dictionary["labels"] = np.hstack(labels_list) y = [dictionary] return y def basic_cifar10_model(overfit=False): ''' Load an example CIFAR10 model ''' from art.estimators.classification.pytorch import PyTorchClassifier labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] path = './' class Model(torch.nn.Module): """ Create model for pytorch. Here the model does not use maxpooling. Needed for certification tests. """ def __init__(self): super(Model, self).__init__() self.conv = torch.nn.Conv2d( in_channels=3, out_channels=16, kernel_size=(4, 4), dilation=(1, 1), padding=(0, 0), stride=(3, 3) ) self.fullyconnected = torch.nn.Linear(in_features=1600, out_features=10) self.relu = torch.nn.ReLU() w_conv2d = np.load( os.path.join( os.path.dirname(path), "utils/resources/models", "W_CONV2D_NO_MPOOL_CIFAR10.npy", ) ) b_conv2d = np.load( os.path.join( os.path.dirname(path), "utils/resources/models", "B_CONV2D_NO_MPOOL_CIFAR10.npy", ) ) w_dense = np.load( os.path.join( os.path.dirname(path), "utils/resources/models", "W_DENSE_NO_MPOOL_CIFAR10.npy", ) ) b_dense = np.load( os.path.join( os.path.dirname(path), "utils/resources/models", "B_DENSE_NO_MPOOL_CIFAR10.npy", ) ) self.conv.weight = torch.nn.Parameter(torch.Tensor(w_conv2d)) self.conv.bias = torch.nn.Parameter(torch.Tensor(b_conv2d)) self.fullyconnected.weight = torch.nn.Parameter(torch.Tensor(w_dense)) self.fullyconnected.bias = torch.nn.Parameter(torch.Tensor(b_dense)) # pylint: disable=W0221 # disable pylint because of API requirements for function def forward(self, x): """ Forward function to evaluate the model :param x: Input to the model :return: Prediction of the model """ x = self.conv(x) x = self.relu(x) x = x.reshape(-1, 1600) x = self.fullyconnected(x) return x # Define the network model = Model() # Define a loss function and optimizer if overfit: loss_fn = torch.nn.CrossEntropyLoss(reduction="sum") optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=0.0) else: loss_fn = torch.nn.CrossEntropyLoss(reduction="sum") optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # Get classifier jptc = PyTorchClassifier( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(3, 32, 32), nb_classes=10, clip_values=(0, 1), labels=labels ) return jptc def det_evasion_evaluate(*args): ''' Run a detection task evaluation ''' def clf_evasion_evaluate(*args): ''' Run a classification task evaluation ''' def show_model_params(model_type): ''' Show model parameters based on selected model type ''' if model_type!="Example CIFAR10" and model_type!="Example XView" and model_type!="CIFAR10 Overfit": return gr.Column(visible=True) return gr.Column(visible=False) def show_dataset_params(dataset_type): ''' Show dataset parameters based on dataset type ''' if dataset_type=="Example CIFAR10": return [gr.Column(visible=False), gr.Row(visible=False), gr.Row(visible=False)] elif dataset_type=="local": return [gr.Column(visible=True), gr.Row(visible=True), gr.Row(visible=False)] return [gr.Column(visible=True), gr.Row(visible=False), gr.Row(visible=True)] def pgd_show_label_output(dataset_type): ''' Show PGD output component based on dataset type ''' if dataset_type=="local": return [gr.Label(visible=True), gr.Label(visible=True), gr.Number(visible=False), gr.Number(visible=False), gr.Number(visible=True)] return [gr.Label(visible=False), gr.Label(visible=False), gr.Number(visible=True), gr.Number(visible=True), gr.Number(visible=True)] def pgd_update_epsilon(clip_values): ''' Update max value of PGD epsilon slider based on model clip values ''' if clip_values == 255: return gr.Slider(minimum=0.0001, maximum=255, label="Epslion", value=55) return gr.Slider(minimum=0.0001, maximum=1, label="Epslion", value=0.05) def patch_show_label_output(dataset_type): ''' Show adversarial patch output components based on dataset type ''' if dataset_type=="local": return [gr.Label(visible=True), gr.Label(visible=True), gr.Number(visible=False), gr.Number(visible=False), gr.Number(visible=True)] return [gr.Label(visible=False), gr.Label(visible=False), gr.Number(visible=True), gr.Number(visible=True), gr.Number(visible=True)] # e.g. To use a local alternative theme: carbon_theme = Carbon() carbon_theme = Carbon() with gr.Blocks(css=css, theme=carbon_theme) as demo: import art text = art.__version__ gr.Markdown(f"