# -*- coding: utf-8 -*- """Gradio_v2.ipynb Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/1UIH_SklAPQViiFqFSdwHTSLFbFkgq2gx # Demo app to mitigate bias precurosr to app.py, not gdrive mounted """ # install general libraries import os import torch.nn as nn from pathlib import Path import numpy as np import pandas as pd import torch from torch.utils.data import Dataset, DataLoader from torchvision import transforms from PIL import Image from facenet_pytorch import MTCNN from torch.autograd import Function import torch.nn.functional as F import gradio as gr from collections import OrderedDict from copy import deepcopy import cv2 def get_device(): if torch.cuda.is_available(): device = "cuda" elif torch.backends.mps.is_available(): device = "mps" else: device = "cpu" print("Device Selected:", device) return device ## Constants or Global cpu_batch_size = 8 device = get_device() mtcnn = MTCNN(image_size=224, device= device) # default is 224, now no need to mention later on class Vgg_vd_face_sfew_dag(nn.Module): def __init__(self): super(Vgg_vd_face_sfew_dag, self).__init__() self.meta = {'mean': [129.186279296875, 104.76238250732422, 93.59396362304688], 'std': [1, 1, 1], 'imageSize': [224, 224, 3]} self.conv1_1 = nn.Conv2d(3, 64, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu1_1 = nn.ReLU() self.conv1_2 = nn.Conv2d(64, 64, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu1_2 = nn.ReLU() self.pool1 = nn.MaxPool2d(kernel_size=[2, 2], stride=[2, 2], padding=0, dilation=1, ceil_mode=False) self.conv2_1 = nn.Conv2d(64, 128, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu2_1 = nn.ReLU() self.conv2_2 = nn.Conv2d(128, 128, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu2_2 = nn.ReLU() self.pool2 = nn.MaxPool2d(kernel_size=[2, 2], stride=[2, 2], padding=0, dilation=1, ceil_mode=False) self.conv3_1 = nn.Conv2d(128, 256, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu3_1 = nn.ReLU() self.conv3_2 = nn.Conv2d(256, 256, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu3_2 = nn.ReLU() self.conv3_3 = nn.Conv2d(256, 256, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu3_3 = nn.ReLU() self.pool3 = nn.MaxPool2d(kernel_size=[2, 2], stride=[2, 2], padding=0, dilation=1, ceil_mode=False) self.conv4_1 = nn.Conv2d(256, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu4_1 = nn.ReLU() self.conv4_2 = nn.Conv2d(512, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu4_2 = nn.ReLU() self.conv4_3 = nn.Conv2d(512, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu4_3 = nn.ReLU() self.pool4 = nn.MaxPool2d(kernel_size=[2, 2], stride=[2, 2], padding=0, dilation=1, ceil_mode=False) self.conv5_1 = nn.Conv2d(512, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu5_1 = nn.ReLU() self.conv5_2 = nn.Conv2d(512, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu5_2 = nn.ReLU() self.conv5_3 = nn.Conv2d(512, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) self.relu5_3 = nn.ReLU() self.pool5 = nn.MaxPool2d(kernel_size=[2, 2], stride=[2, 2], padding=0, dilation=1, ceil_mode=False) self.fc6 = nn.Conv2d(512, 4096, kernel_size=[7, 7], stride=(1, 1)) self.relu6 = nn.ReLU() self.fc7 = nn.Linear(in_features=4096, out_features=4096, bias=True) self.relu7 = nn.ReLU() self.fc8 = nn.Linear(in_features=4096, out_features=7, bias=True) def forward(self, data): x1 = self.conv1_1(data) x2 = self.relu1_1(x1) x3 = self.conv1_2(x2) x4 = self.relu1_2(x3) x5 = self.pool1(x4) x6 = self.conv2_1(x5) x7 = self.relu2_1(x6) x8 = self.conv2_2(x7) x9 = self.relu2_2(x8) x10 = self.pool2(x9) x11 = self.conv3_1(x10) x12 = self.relu3_1(x11) x13 = self.conv3_2(x12) x14 = self.relu3_2(x13) x15 = self.conv3_3(x14) x16 = self.relu3_3(x15) x17 = self.pool3(x16) x18 = self.conv4_1(x17) x19 = self.relu4_1(x18) x20 = self.conv4_2(x19) x21 = self.relu4_2(x20) x22 = self.conv4_3(x21) x23 = self.relu4_3(x22) x24 = self.pool4(x23) x25 = self.conv5_1(x24) x26 = self.relu5_1(x25) x27 = self.conv5_2(x26) x28 = self.relu5_2(x27) x29 = self.conv5_3(x28) x30 = self.relu5_3(x29) x31 = self.pool5(x30) x32 = self.fc6(x31) # this is a conv layer, this is the output we need x33_preflatten = self.relu6(x32) x33 = x33_preflatten.view(x33_preflatten.size(0), -1) x34 = self.fc7(x33) x35 = self.relu7(x34) prediction = self.fc8(x35) return prediction def vgg_vd_face_sfew_dag(weights_path=None, **kwargs): """ load imported model instance Args: weights_path (str): If set, loads model weights from the given path """ model = Vgg_vd_face_sfew_dag() if weights_path: state_dict = torch.load(weights_path) model.load_state_dict(state_dict) return model model_pretrained = vgg_vd_face_sfew_dag(weights_path="vgg_vd_face_sfew_dag.pth") class GradientReversalFn(Function): @staticmethod def forward(ctx, x, alpha): ctx.alpha = alpha return x.view_as(x) @staticmethod def backward(ctx, grad_output): output = grad_output.neg() * ctx.alpha return output, None class DANN_VGG(nn.Module): def __init__(self, model_pretrained = model_pretrained, num_classes=7, dropout_rate = 0.1, ): super(DANN_VGG, self).__init__() #---------------------Feature Extractor Network---------------# list_feature_extractor = list(model_pretrained.children())[:-4] self.feature_extractor = nn.Sequential(*list_feature_extractor) #---------------------Class Classifier------------------------# list_class_classifer = list(model_pretrained.children())[-4:] list_class_classifer.insert(2, nn.Dropout(dropout_rate)) self.class_classifier = nn.Sequential(*list_class_classifer) #---------------------Domain Classifier-----------------------# self.domain_classifier = nn.Sequential(nn.ReLU(), nn.Linear(4096, 4096), nn.Dropout(dropout_rate), nn.ReLU(), nn.Linear(4096, 2) ) # Initialize the 4096,4096 to pre-trained pretrained_weights = model_pretrained.fc7.weight pretrained_biases = model_pretrained.fc7.bias with torch.no_grad(): self.domain_classifier[1].weight.copy_(pretrained_weights) self.domain_classifier[1].bias.copy_(pretrained_biases) def forward(self, input_data, alpha = 0.0): features = self.feature_extractor(input_data) # print("features.shape......", features.shape) features = features.view(-1,features.size(1)) # print("features.shape after view......", features.shape) reverse_features = GradientReversalFn.apply(features,alpha) class_output = self.class_classifier(features) domain_output = self.domain_classifier(reverse_features) return class_output, domain_output, features # Downloading Models skeleton_model = DANN_VGG(model_pretrained = model_pretrained, num_classes=7) # skeleton copy non_dann_model_sfew_expw_inference = deepcopy(skeleton_model) # skeleton copy non_dann_model_sfew_expw_inference.load_state_dict(torch.load('non_dann_sfew_expw_23_05_wo_se_a.pt',map_location=torch.device(device))) dann_model_sfew_expw_inference = deepcopy(skeleton_model) # skeleton copy dann_model_sfew_expw_inference.load_state_dict(torch.load('dann_sfew_expw_23_05_wo_se_a.pt',map_location=torch.device(device))) ewc_dann_model_sfew_expw_inference = deepcopy(skeleton_model) # skeleton copy ewc_dann_model_sfew_expw_inference.load_state_dict(torch.load('ewc_dann_sfew_expw_23_05_wo_se_a.pt',map_location=torch.device(device))) # Load Samples df_samples_loaded = torch.load('df_sample.pt') """### Condition 1: Images that are predicted same in non_dann, dann, dann_ewc, ground truth - 30""" condition_1 = (df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_non_dann']) & (df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_dann']) & ( df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_ewc_dann']) df_condition_1 = df_samples_loaded[condition_1].reset_index(drop=True) """### Condition 2: Images that are nok in non_dann, ok in dann and dann_ewc - 20""" condition_2 = (df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_non_dann']) & (df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_dann']) & ( df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_ewc_dann']) df_condition_2 = df_samples_loaded[condition_2].reset_index(drop=True) """### Condition 3. Images that are nok in non_dann, nok in dann and ok in dann_ewc - 27""" condition_3 = (df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_non_dann']) & (df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_dann']) & ( df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_ewc_dann']) df_condition_3 = df_samples_loaded[condition_3].reset_index(drop=True) """### Condition 4. Images that are nok in non_dann, dann_ewc but ok in dann - 24""" condition_4 = (df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_non_dann']) & (df_samples_loaded['gt_emotion'] == df_samples_loaded['p_emotion_dann']) & ( df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_ewc_dann']) df_condition_4 = df_samples_loaded[condition_4].reset_index(drop=True) """### Condition 5. Images which are non_ok on all 3 - 40""" condition_5 = (df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_non_dann']) & (df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_dann']) & ( df_samples_loaded['gt_emotion'] != df_samples_loaded['p_emotion_ewc_dann']) df_condition_5 = df_samples_loaded[condition_5].reset_index(drop=True) """# Dataloader""" # Define the labels map labels_map = { "0": "angry", "1": "disgust", "2": "fear", "3": "happy", "4": "sad", "5": "surprise", "6": "neutral" } # List of labels labels = list(labels_map.values()) # Create the one-hot encoding matrix label_matrix = torch.eye(len(labels)) # Function to get the one-hot vector for a specific emotion def get_one_hot_vector(emotion, labels = labels, label_matrix= label_matrix): if emotion in labels: idx = labels.index(emotion) return label_matrix[idx] else: raise ValueError(f"Emotion '{emotion}' not found in labels.") class CustomImageDataset(Dataset): def __init__(self, dataframe, transform=None, image_file_colname = 'image', race_colname = 'gt_race', gt_emotion_colname = 'gt_emotion', image_pil_colname = 'image_pil'): self.dataframe = dataframe.reset_index(drop=True) self.basic_transform = transforms.Compose([transforms.Resize(224), transforms.ToTensor()]) self.transform = transform self.image_file_colname = image_file_colname self.race_colname = race_colname self.gt_emotion_colname = gt_emotion_colname self.image_pil_colname = image_pil_colname def __len__(self): return len(self.dataframe) def __getitem__(self, idx): img_filename = self.dataframe.loc[idx, self.image_file_colname] race = self.dataframe.loc[idx, self.race_colname] emotion = self.dataframe.loc[idx, self.gt_emotion_colname] emotion_one_hot = get_one_hot_vector(emotion.lower()) # emotion.lower() to match the labels image = self.dataframe.loc[idx, self.image_pil_colname] # pil image cropped_image = mtcnn(image) # mtcnn takes in PIL, returns tensor in cropped image 3x224x224 if self.transform: image_transformed = self.transform(image) # original image, this converts PIL into tensor else: image_transformed = self.basic_transform(image) # original image, this converts PIL into tensor if cropped_image is None: #error in cropping # in case of error, original image is returned return image_transformed, emotion_one_hot, image_transformed, race else: # cropping went ok # cropped image alongside original image is returned, there is no transform on cropped image. cropped_image = (cropped_image + 1) / 2 # changing form -1,1 to 0,1 return cropped_image, emotion_one_hot, image_transformed, race """## Dataset and Dataloader for Conditions 1 to 5""" transform = transforms.Compose([ transforms.Resize((224, 224)), # Resize images to 224x224 transforms.ToTensor(), # Convert images to PyTorch tensors ]) # condition 1 dataset_condition_1 = CustomImageDataset(dataframe= df_condition_1, transform=transform) dataloader_condition_1 = DataLoader(dataset_condition_1, batch_size=cpu_batch_size, shuffle=True) # condition 2 dataset_condition_2 = CustomImageDataset(dataframe= df_condition_2, transform=transform) dataloader_condition_2 = DataLoader(dataset_condition_2, batch_size=cpu_batch_size, shuffle=True) # condition 3 dataset_condition_3 = CustomImageDataset(dataframe= df_condition_3, transform=transform) dataloader_condition_3 = DataLoader(dataset_condition_3, batch_size=cpu_batch_size, shuffle=True) # condition 4 dataset_condition_4 = CustomImageDataset(dataframe= df_condition_4, transform=transform) dataloader_condition_4 = DataLoader(dataset_condition_4, batch_size=cpu_batch_size, shuffle=True) # condition 5 dataset_condition_5 = CustomImageDataset(dataframe= df_condition_5, transform=transform) dataloader_condition_5 = DataLoader(dataset_condition_5, batch_size=cpu_batch_size, shuffle=True) """# UI and its related functions ### Get images function for all conditions """ transform_to_pil = transforms.ToPILImage() emotion_labels = [label.capitalize() for label in list(labels_map.values())] def get_images(dataloader = dataloader_condition_1): cropped_images, emotions, images, races = next(iter(dataloader)) list_pil_cropped_images = [transform_to_pil(cropped_img) for cropped_img in cropped_images] list_pil_images = [transform_to_pil(img) for img in images] list_emotions = list(emotions) # list of one hot tensort list_emotions = [ emotion_labels[torch.argmax(emotion).item()] for emotion in emotions] return list_pil_cropped_images, list_emotions, list_pil_images, list(races) def get_images_condition_2(): return get_images(dataloader_condition_2) def get_images_condition_3(): return get_images(dataloader_condition_3) def get_images_condition_4(): return get_images(dataloader_condition_4) def get_images_condition_5(): return get_images(dataloader_condition_5) """### Classify Images All models""" emotion_labels = [label.capitalize() for label in list(labels_map.values())] def classify_image_all_models(input_image): image_transforms = transforms.Compose([ transforms.Resize((224,224)), transforms.ToTensor() ]) transformed_image = image_transforms(input_image) image_tensor = transformed_image.to(device).unsqueeze(0) list_confidences = [] for model in [non_dann_model_sfew_expw_inference, dann_model_sfew_expw_inference, ewc_dann_model_sfew_expw_inference]: model = model.to(device) model.eval() with torch.no_grad(): logits, _ , _ = model((image_tensor*255)) output = F.softmax(logits.view(-1), dim = -1) confidences = [(emotion_labels[i], float(output[i])) for i in range(len(emotion_labels))] confidences.sort(key=lambda x: x[1], reverse=True) confidences = OrderedDict(confidences[:2]) label = torch.argmax(output).item() list_confidences.append(confidences) return list_confidences[0], list_confidences[1], list_confidences[2] def display_image(): # Load the image from a local file image = Image.open("DBMF.png") return image cases_table = """ | **Cases** | **Baseline / Non DANN** | **DANN without EWC** | **DANN with EWC** | |--------------|--------------|--------------|--------------| | **Case 1 (C1)** | **Same** as GT | **Same** as GT | **Same** as GT | | **Case 2 (C2)** | **Different** from GT | **Same** as GT | **Same** as GT | | **Case 3 (C3)** | **Different** from GT | **Different** from GT | **Same** as GT| | **Case 4 (C4)** | **Different** from GT | **Same** as GT | **Different** from GT | | **Case 5 (C5)** | **Different** from GT | **Different** from GT | **Different** from GT | | **Case 6 (C6)** | **Same** as GT | **Different** from GT | **Different** from GT | | **Case 7 (C7)** | **Same** as GT | **Same** as GT | **Different** from GT | | **Case 8 (C8)** | **Same** as GT | **Different** from GT | **Same** as GT | """ """Gradio UI""" with gr.Blocks() as demo: with gr.Tab("Introduction"): gr.Markdown("## Domain Adaptation in Deep Networks - Practical Implementation of Demographic Bias Mitigation Framework") with gr.Row(): with gr.Column(): image_output = gr.Image(value=display_image(), label = "Demographic Bias Mitigation Framework",height = 400, width = 600, show_label = True) with gr.Column(): gr.Markdown(''' Source - Static Facial Expression in Wild (SFEW) 2.0 or SFEW2.0 ------- - SFEW 2.0 dataset is split into training (958 samples), validation (436 samples), and test sets (372 samples). - Each image is labelled with one of seven emotions: Angry, Disgust, Fear, Happy, Sad, Surprise, and Neutral. - It is used as racially bias source domain dataset in this demonstration ''') gr.Markdown( ''' Target - Expression in-the-Wild or ExpW dataset ------- - It comprises of 91,793 manually labeled images without specific Train/Validation/Test splits. - Similar to SFEW 2.0, each image in the ExpW dataset is categorized as: Angry, Disgust, Fear, Happy, Sad, Surprise, and Neutral. - It is used as racially unbiased target domain dataset in this demonstration ''' ) gr.Markdown( ''' Evaluation Dataset - ExpW (Race annotated) ------- - A subset of 8,458 images from the ExpW dataset was randomly selected and annotated with race in addition to the existing emotion labels. - This subset also served as the validation dataset - **The images from this validation set are used** ''' ) with gr.Row(): with gr.Column(): gr.Markdown(''' **Fig. 1.** **DANN based demographic bias mitigation framework (DBMF)**: Framework supports (a) Non-domain adapted (Baseline, Non-DA) training, (b) Domain adapted (DA) training and (c) bias and task accuracy evaluation steps. Pre-processed data is fed into feature extractor. Fully connected network in Task-specific component has classification/regression heads. Domain classifier comprises of fully connected layers with a binary classification head. Unsupervised DA is supported by a gradient reversal layer, which flips errors during backpropagation, forcing the feature extractor to prioritize domain-invariant features that remain task-specific. For (c) bias and task accuracy evaluation, an evaluation test set is used to understand task accuracy and bias using statistical metrics / tests. ''') with gr.Column(): with gr.Row(): gr.Markdown(''' **Table. 1.** Cases showing predicted emotion in 3 networks as compared to ground truth emotion''') with gr.Row(): gr.Markdown(cases_table) ################################################ with gr.Tab("C1: All Same") as tabs1: imgs = gr.State() # gallery = gr.Gallery(allow_preview=False) with gr.Row(): with gr.Column(scale=1): gallery = gr.Gallery(allow_preview=True, rows=2, columns=2) with gr.Column(scale=1): with gr.Row(): cropped_image_display = gr.Image(label="Cropped Image", type="pil", height=224, width=224) with gr.Row(): button_classify_C1 = gr.Button("Click Button to Predict Emotion", visible=True, size='sm') with gr.Row(): # selected = gr.Number(show_label=False) selected = gr.Textbox(label="Ground Truth Emotion", visible=False) txtbox_race = gr.Textbox(label="Race", visible=False) with gr.Column(scale=1): with gr.Row(): label_classify_non_dann = gr.Label(label="Baseline(Non DANN) Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_dann = gr.Label(label="DANN Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_ewc = gr.Label(label="EWC DANN Predicted Emotion", num_top_classes=2, visible=True) cropped_images, list_emotions, big_images, list_races = get_images() def get_big_images(): return big_images, big_images def get_select_index(evt: gr.SelectData): # return evt.index, cropped_images[evt.index] return list_emotions[evt.index], gr.update(visible=True), cropped_images[evt.index], list_races[evt.index], gr.update(visible=True) refresh_case1 = gr.Checkbox(visible=False) def refresh_gallery(): return get_big_images() refresh_case1.change(refresh_gallery, None, [gallery, imgs]) gallery.select(get_select_index, None, [selected, selected, cropped_image_display, txtbox_race, txtbox_race]) button_classify_C1.click(fn=classify_image_all_models, inputs=[cropped_image_display], outputs=[label_classify_non_dann, label_classify_dann, label_classify_ewc]) ################################################ with gr.Tab("C2:Same:DANN, EWC DANN | Diff:Base") as tabs2: imgs_2 = gr.State() with gr.Row(): with gr.Column(scale=1): gallery_2 = gr.Gallery(allow_preview=True, rows=2, columns=2) with gr.Column(scale=1): with gr.Row(): cropped_image_display_2 = gr.Image(label="Cropped Image", type="pil", height=224, width=224) with gr.Row(): button_classify_C2 = gr.Button("Click Button to Predict Emotion", visible=True, size='sm') with gr.Row(): selected_2 = gr.Textbox(label="Ground Truth Emotion", visible=False) txtbox_race_2 = gr.Textbox(label="Race", visible=False) with gr.Column(scale=1): with gr.Row(): label_classify_non_dann_2 = gr.Label(label="Baseline(Non DANN) Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_dann_2 = gr.Label(label="DANN Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_ewc_2 = gr.Label(label="EWC DANN Predicted Emotion", num_top_classes=2, visible=True) cropped_images_2, list_emotions_2, big_images_2, list_races_2 = get_images_condition_2() def get_big_images_2(): return big_images_2, big_images_2 def get_select_index_2(evt: gr.SelectData): # return evt.index, cropped_images[evt.index] return list_emotions_2[evt.index], gr.update(visible=True), cropped_images_2[evt.index], list_races_2[evt.index], gr.update(visible=True) refresh_case2 = gr.Checkbox(visible=False) def refresh_gallery_2(): return get_big_images_2() refresh_case2.change(refresh_gallery_2, None, [gallery_2, imgs_2]) gallery_2.select(get_select_index_2, None, [selected_2, selected_2, cropped_image_display_2, txtbox_race_2, txtbox_race_2]) button_classify_C2.click(fn=classify_image_all_models, inputs=[cropped_image_display_2], outputs=[label_classify_non_dann_2, label_classify_dann_2, label_classify_ewc_2]) ################################################ with gr.Tab("C3:Same:EWC DANN | Diff:Base, DANN")as tabs3: imgs_3 = gr.State() with gr.Row(): with gr.Column(scale=1): gallery_3 = gr.Gallery(allow_preview=True, rows=2, columns=2) with gr.Column(scale=1): with gr.Row(): cropped_image_display_3 = gr.Image(label="Cropped Image", type="pil", height=224, width=224) with gr.Row(): button_classify_C3 = gr.Button("Click Button to Predict Emotion", visible=True, size='sm') with gr.Row(): selected_3 = gr.Textbox(label="Ground Truth Emotion", visible=False) txtbox_race_3 = gr.Textbox(label="Race", visible=False) with gr.Column(scale=1): with gr.Row(): label_classify_non_dann_3 = gr.Label(label="Baseline(Non DANN) Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_dann_3 = gr.Label(label="DANN Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_ewc_3 = gr.Label(label="EWC DANN Predicted Emotion", num_top_classes=2, visible=True) cropped_images_3, list_emotions_3, big_images_3, list_races_3 = get_images_condition_3() def get_big_images_3(): return big_images_3, big_images_3 def get_select_index_3(evt: gr.SelectData): # return evt.index, cropped_images[evt.index] return list_emotions_3[evt.index], gr.update(visible=True), cropped_images_3[evt.index], list_races_3[evt.index], gr.update(visible=True) refresh_case3 = gr.Checkbox(visible=False) def refresh_gallery_3(): return get_big_images_3() refresh_case3.change(refresh_gallery_3, None, [gallery_3, imgs_3]) gallery_3.select(get_select_index_3, None, [selected_3, selected_3, cropped_image_display_3, txtbox_race_3, txtbox_race_3]) button_classify_C3.click(fn=classify_image_all_models, inputs=[cropped_image_display_3], outputs=[label_classify_non_dann_3, label_classify_dann_3, label_classify_ewc_3]) ################################################ with gr.Tab("C4:Same:DANN | Diff:Base, EWC DANN") as tabs4: imgs_4 = gr.State() with gr.Row(): with gr.Column(scale=1): gallery_4 = gr.Gallery(allow_preview=True, rows=2, columns=2) with gr.Column(scale=1): with gr.Row(): cropped_image_display_4 = gr.Image(label="Cropped Image", type="pil", height=224, width=224) with gr.Row(): button_classify_C4 = gr.Button("Click Button to Predict Emotion", visible=True, size='sm') with gr.Row(): selected_4 = gr.Textbox(label="Ground Truth Emotion", visible=False) txtbox_race_4 = gr.Textbox(label="Race", visible=False) with gr.Column(scale=1): with gr.Row(): label_classify_non_dann_4 = gr.Label(label="Baseline(Non DANN) Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_dann_4 = gr.Label(label="DANN Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_ewc_4 = gr.Label(label="EWC DANN Predicted Emotion", num_top_classes=2, visible=True) cropped_images_4, list_emotions_4, big_images_4, list_races_4 = get_images_condition_4() def get_big_images_4(): return big_images_4, big_images_4 def get_select_index_4(evt: gr.SelectData): return list_emotions_4[evt.index], gr.update(visible=True), cropped_images_4[evt.index], list_races_4[evt.index], gr.update(visible=True) refresh_case4 = gr.Checkbox(visible=False) def refresh_gallery_4(): return get_big_images_4() refresh_case4.change(refresh_gallery_4, None, [gallery_4, imgs_4]) gallery_4.select(get_select_index_4, None, [selected_4, selected_4, cropped_image_display_4, txtbox_race_4, txtbox_race_4]) button_classify_C4.click(fn=classify_image_all_models, inputs=[cropped_image_display_4], outputs=[label_classify_non_dann_4, label_classify_dann_4, label_classify_ewc_4]) ################################################ with gr.Tab("C5: All Diff") as tabs5: imgs_5 = gr.State() with gr.Row(): with gr.Column(scale=1): gallery_5 = gr.Gallery(allow_preview=True, rows=2, columns=2) with gr.Column(scale=1): with gr.Row(): cropped_image_display_5 = gr.Image(label="Cropped Image", type="pil", height=224, width=224) with gr.Row(): button_classify_C5 = gr.Button("Click Button to Predict Emotion", visible=True, size='sm') with gr.Row(): selected_5 = gr.Textbox(label="Ground Truth Emotion", visible=False) txtbox_race_5 = gr.Textbox(label="Race", visible=False) with gr.Column(scale=1): with gr.Row(): label_classify_non_dann_5 = gr.Label(label="Baseline(Non DANN) Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_dann_5 = gr.Label(label="DANN Predicted Emotion", num_top_classes=2, visible=True) with gr.Row(): label_classify_ewc_5 = gr.Label(label="EWC DANN Predicted Emotion", num_top_classes=2, visible=True) cropped_images_5, list_emotions_5, big_images_5, list_races_5 = get_images_condition_5() def get_big_images_5(): return big_images_5, big_images_5 def get_select_index_5(evt: gr.SelectData): return list_emotions_5[evt.index], gr.update(visible=True), cropped_images_5[evt.index], list_races_5[evt.index], gr.update(visible=True) refresh_case5 = gr.Checkbox(visible=False) def refresh_gallery_5(): return get_big_images_5() refresh_case5.change(refresh_gallery_5, None, [gallery_5, imgs_5]) gallery_5.select(get_select_index_5, None, [selected_5, selected_5, cropped_image_display_5, txtbox_race_5, txtbox_race_5]) button_classify_C5.click(fn=classify_image_all_models, inputs=[cropped_image_display_5], outputs=[label_classify_non_dann_5, label_classify_dann_5, label_classify_ewc_5]) ################################################ with gr.Tab("C6:Same:Base | Diff:DANN, EWC DANN") as tabs6: imgs_6 = gr.State() refresh_case6 = gr.Checkbox(visible=False) ################################################ with gr.Tab("C7:Same:Base, DANN | Diff: EWC DANN") as tabs7: imgs_7 = gr.State() refresh_case7 = gr.Checkbox(visible=False) ################################################ with gr.Tab("C8:Same:Base, EWC DANN | Diff: DANN") as tabs8: imgs_8 = gr.State() refresh_case8 = gr.Checkbox(visible=False) ################################################ def refresh_tab(): return True def refresh_tab2(): return True def refresh_tab3(): return True def refresh_tab4(): return True def refresh_tab5(): return True def refresh_tab6(): return True def refresh_tab7(): return True def refresh_tab8(): return True with gr.Row(visible=True): refresh_tab_1 = gr.Button(value="Load Case 1", visible=True) refresh_tab_2 = gr.Button(value="Load Case 2", visible=True) refresh_tab_3 = gr.Button(value="Load Case 3", visible=True) refresh_tab_4 = gr.Button(value="Load Case 4", visible=True) refresh_tab_5 = gr.Button(value="Load Case 5", visible=True) refresh_tab_6 = gr.Button(value="Load Case 6", visible=True) refresh_tab_7 = gr.Button(value="Load Case 7", visible=True) refresh_tab_8 = gr.Button(value="Load Case 8", visible=True) refresh_tab_1.click(refresh_tab, [], [refresh_case1]) refresh_tab_2.click(refresh_tab, [], [refresh_case2]) refresh_tab_3.click(refresh_tab, [], [refresh_case3]) refresh_tab_4.click(refresh_tab, [], [refresh_case4]) refresh_tab_5.click(refresh_tab, [], [refresh_case5]) refresh_tab_6.click(refresh_tab, [], [refresh_case6]) refresh_tab_7.click(refresh_tab, [], [refresh_case7]) refresh_tab_8.click(refresh_tab, [], [refresh_case8]) demo.launch(debug=True)