{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":30121,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install py7zr \n!pip install gdown","metadata":{"execution":{"iopub.status.busy":"2022-01-23T16:01:44.708191Z","iopub.execute_input":"2022-01-23T16:01:44.70848Z","iopub.status.idle":"2022-01-23T16:02:11.003032Z","shell.execute_reply.started":"2022-01-23T16:01:44.708411Z","shell.execute_reply":"2022-01-23T16:02:11.002114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Required imports \nfrom torch.utils.data import Dataset, DataLoader\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport matplotlib.pyplot as plt\nimport torch.nn as nn\nfrom torch.utils import data\nimport os\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport py7zr\nimport numpy as np\nimport pandas as pd","metadata":{"execution":{"iopub.status.busy":"2022-01-23T16:02:22.389706Z","iopub.execute_input":"2022-01-23T16:02:22.390171Z","iopub.status.idle":"2022-01-23T16:02:22.397848Z","shell.execute_reply.started":"2022-01-23T16:02:22.390128Z","shell.execute_reply":"2022-01-23T16:02:22.397011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extracting the training set\nwith py7zr.SevenZipFile('../input/cifar-10/train.7z', mode='r') as z:\n    z.extractall('./train')","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:19:15.409643Z","iopub.execute_input":"2022-01-13T12:19:15.409962Z","iopub.status.idle":"2022-01-13T12:20:03.025411Z","shell.execute_reply.started":"2022-01-13T12:19:15.409936Z","shell.execute_reply":"2022-01-13T12:20:03.024453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Setting up the device to use \ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2022-01-23T16:02:26.833619Z","iopub.execute_input":"2022-01-23T16:02:26.833937Z","iopub.status.idle":"2022-01-23T16:02:26.879559Z","shell.execute_reply.started":"2022-01-23T16:02:26.833909Z","shell.execute_reply":"2022-01-23T16:02:26.878726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Preprocessing function for converting the labels to numbers \ndef labeltoIntegers(label):\n    labels = [\"cat\",\"frog\",\"bird\",\"automobile\",\"truck\",\"deer\",\"horse\",\"ship\",\"airplane\",\"dog\"]\n    return labels.index(label)","metadata":{"execution":{"iopub.status.busy":"2022-01-23T16:02:29.463677Z","iopub.execute_input":"2022-01-23T16:02:29.464097Z","iopub.status.idle":"2022-01-23T16:02:29.468255Z","shell.execute_reply.started":"2022-01-23T16:02:29.464037Z","shell.execute_reply":"2022-01-23T16:02:29.467394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset class for loading the CIFAR Dataset","metadata":{}},{"cell_type":"code","source":"# Defining the dataset class which will be used for loading the data\nclass CIFARDataset(Dataset):\n    def __init__(self, root_dir, csv_file, transform = None):\n        # Setting up the root dir to get data from\n        self.root_dir = root_dir\n        if(csv_file != None):\n            # Setting train as true if csv file for labels is provided\n            self.train = True\n            \n            # Reading the labels\n            self.labels = pd.read_csv(csv_file)\n            \n            # Applying the preprocessing function for labels\n            self.labels['label'] = self.labels['label'].apply(labeltoIntegers)\n        else:\n            # Setting train as false for the testing set\n            self.train = False\n            self.labels = None\n        \n        # Setting up the image transform defined if any\n        self.transform = transform\n    \n    # Function used to return length of the dataset\n    def __len__(self):\n        # Getting available files at the root_dir specified\n        list = os.listdir(self.root_dir)\n        \n        # Returning the length of the number of files\n        number_files = len(list)\n        return number_files\n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n        \n        # Getting the image name for index provided\n        img_name = os.path.join(self.root_dir,'{}.png'.format(idx+1))\n        \n        # Reading the image using openCV\n        image = cv2.imread(img_name)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        # Converting the image to PyTorch tensor\n        return_image = torch.from_numpy(image).to(device)\n        \n        # Chaning the shape from (HxWxC) to (CxHxW)\n        return_image = return_image.permute(2,0,1)\n        \n        # Applying the transform if not None\n        if self.transform:\n            return_image = self.transform(image)\n        \n        # Returning the image only if train False\n        if(self.train == False):\n            return return_image\n        \n        # Else converting the label to tensor as well\n        label = self.labels['label'][idx]\n        label = np.array([label])\n        return_label = torch.from_numpy(label).type(torch.LongTensor).to(device)\n        \n        # Changing shape to make it of form (batch_size,) from (batch_size,1)\n        return_label = return_label.squeeze(-1)\n        \n\n        # Returning the image and label converted to tensor\n        return (return_image, return_label)  ","metadata":{"execution":{"iopub.status.busy":"2022-01-23T16:02:32.035092Z","iopub.execute_input":"2022-01-23T16:02:32.035419Z","iopub.status.idle":"2022-01-23T16:02:32.045438Z","shell.execute_reply.started":"2022-01-23T16:02:32.03539Z","shell.execute_reply":"2022-01-23T16:02:32.044602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image transforms","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),    \n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),\n    \n])","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.101803Z","iopub.execute_input":"2022-01-13T12:20:03.102152Z","iopub.status.idle":"2022-01-13T12:20:03.110973Z","shell.execute_reply.started":"2022-01-13T12:20:03.102124Z","shell.execute_reply":"2022-01-13T12:20:03.110096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Initialize the training and testing dataset","metadata":{}},{"cell_type":"code","source":"train_dataset = CIFARDataset(csv_file='../input/cifar-10/trainLabels.csv',\n                                    root_dir='./train/train', transform = transform)","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.114485Z","iopub.execute_input":"2022-01-13T12:20:03.114767Z","iopub.status.idle":"2022-01-13T12:20:03.205956Z","shell.execute_reply.started":"2022-01-13T12:20:03.114742Z","shell.execute_reply":"2022-01-13T12:20:03.205108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nidx = list(range(len(train_dataset)))\nrandom.shuffle(idx)\nn = len(train_dataset)\nn_test = int( n * .05 ) \nn_val = int(n * .05) # number of test/val elements\nn_train = n - 2 * n_test\ntrain_idx = idx[:n_train]\nval_idx = idx[n_train:(n_train + n_test)]\ntest_idx = idx[(n_train + n_test):]","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.207656Z","iopub.execute_input":"2022-01-13T12:20:03.208002Z","iopub.status.idle":"2022-01-13T12:20:03.316035Z","shell.execute_reply.started":"2022-01-13T12:20:03.207965Z","shell.execute_reply":"2022-01-13T12:20:03.315238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set, val_set, test_set = data.random_split(train_dataset, (n_train, n_val, n_test))","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.317312Z","iopub.execute_input":"2022-01-13T12:20:03.317664Z","iopub.status.idle":"2022-01-13T12:20:03.367737Z","shell.execute_reply.started":"2022-01-13T12:20:03.317628Z","shell.execute_reply":"2022-01-13T12:20:03.367055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getData(batch_size):\n    train_loader = DataLoader(train_set, batch_size, shuffle=True)\n    val_loader = DataLoader(val_set, batch_size=10)\n    return train_loader, val_loader","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.368932Z","iopub.execute_input":"2022-01-13T12:20:03.369295Z","iopub.status.idle":"2022-01-13T12:20:03.373943Z","shell.execute_reply.started":"2022-01-13T12:20:03.369259Z","shell.execute_reply":"2022-01-13T12:20:03.373005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader, val_loader = getData(batch_size = 225)","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.37541Z","iopub.execute_input":"2022-01-13T12:20:03.375757Z","iopub.status.idle":"2022-01-13T12:20:03.383849Z","shell.execute_reply.started":"2022-01-13T12:20:03.375723Z","shell.execute_reply":"2022-01-13T12:20:03.383078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Component Block for ResNet","metadata":{}},{"cell_type":"code","source":"class Block(nn.Module):\n    def __init__(self, in_channels, out_channels, identity_downsample=None, stride=1):\n        super(Block, self).__init__()\n        # Resnet 50 has 4 times the initial input channels\n        self.expansion = 4\n        # First layer\n        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0)\n        self.bn1 = nn.BatchNorm2d(out_channels)\n        \n        # Second layer\n        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride, padding=1)\n        self.bn2 = nn.BatchNorm2d(out_channels)\n        \n        # Third layer\n        self.conv3 = nn.Conv2d(out_channels, out_channels*self.expansion, kernel_size=1, stride=1, padding=0)\n        self.bn3 = nn.BatchNorm2d(out_channels*self.expansion)\n        \n        # Activation function\n        self.relu = nn.ReLU()\n        \n        # Identity downsample, dunno right now ig\n        self.identity_downsample = identity_downsample\n    \n    # Forward propagation \n    def forward(self, x):\n        identity = x.clone()\n        x = self.bn1(self.conv1(x))\n        x = self.relu(x)\n        x = self.bn2(self.conv2(x))\n        x = self.relu(x)        \n        x = self.bn3(self.conv3(x))\n        \n        if self.identity_downsample is not None:\n            identity = self.identity_downsample(identity)\n        \n        x += identity\n        x = self.relu(x)\n        # Returning the variable after passing through the convolutional layers\n        return x\n","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.385251Z","iopub.execute_input":"2022-01-13T12:20:03.385612Z","iopub.status.idle":"2022-01-13T12:20:03.399226Z","shell.execute_reply.started":"2022-01-13T12:20:03.385576Z","shell.execute_reply":"2022-01-13T12:20:03.398298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ResNet Architecture","metadata":{}},{"cell_type":"code","source":"class ResNet(nn.Module):\n    def __init__(self, block, layers, image_channels, out_classes):\n        super(ResNet, self).__init__()\n        self.in_channels = 64\n        self.conv1 = nn.Conv2d(image_channels, self.in_channels, kernel_size = 7, stride = 2, padding =3)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.relu = nn.ReLU()\n        self.maxpool = nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 1)\n        # Essentially the entire ResNet architecture are in these 4 lines below\n        self.layer1 = self._make_layer(\n            block, layers[0], intermediate_channels=64, stride=1\n        )\n        self.layer2 = self._make_layer(\n            block, layers[1], intermediate_channels=128, stride=2\n        )\n        self.layer3 = self._make_layer(\n            block, layers[2], intermediate_channels=256, stride=2\n        )\n        self.layer4 = self._make_layer(\n            block, layers[3], intermediate_channels=512, stride=2\n        )\n\n        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n        self.fc = nn.Linear(512 * 4, out_classes)\n        \n    def _make_layer(self, block, num_residual_blocks, intermediate_channels, stride):\n        identity_downsample = None\n        layers = []\n        \n        # For first layer, identity_downsample is not used since stride = 1\n        if(stride!=1 or self.in_channels != intermediate_channels*4):\n            identity_downsample = nn.Sequential(\n                # Converting into channels*4 since that happens at the end of each block in ResNet\n                nn.Conv2d(\n                    self.in_channels,\n                    intermediate_channels*4,\n                    kernel_size = 1,\n                    stride = stride,\n                    bias = False\n                    \n                ),\n                nn.BatchNorm2d(intermediate_channels*4)\n                \n            )\n        '''This will be the first layer and we use the identity_downsample to convert the input to similiar\n        size which will then be added to the output from the block after applying the conv layers'''\n        \n        layers.append(\n            block(self.in_channels, intermediate_channels, identity_downsample, stride)\n        )\n        self.in_channels = intermediate_channels * 4\n        \n        # For example for first resnet layer: 256 will be mapped to 64 as intermediate layer,\n        # then finally back to 256. Hence no identity downsample is needed, since stride = 1,\n        # and also same amount of channels.\n        \n        for i in range(num_residual_blocks - 1):\n            layers.append(block(self.in_channels, intermediate_channels))\n        return nn.Sequential(*layers)\n    \n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        x = self.avgpool(x)\n        x = x.reshape(x.shape[0], -1)\n        x = self.fc(x)\n        \n        return x","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.400726Z","iopub.execute_input":"2022-01-13T12:20:03.401082Z","iopub.status.idle":"2022-01-13T12:20:03.41761Z","shell.execute_reply.started":"2022-01-13T12:20:03.401047Z","shell.execute_reply":"2022-01-13T12:20:03.416766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Our FGSM attacker","metadata":{}},{"cell_type":"code","source":"from skimage.metrics import mean_squared_error\nfrom skimage.metrics import peak_signal_noise_ratio\nfrom skimage.metrics import structural_similarity","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.420393Z","iopub.execute_input":"2022-01-13T12:20:03.420704Z","iopub.status.idle":"2022-01-13T12:20:03.781624Z","shell.execute_reply.started":"2022-01-13T12:20:03.420678Z","shell.execute_reply":"2022-01-13T12:20:03.780741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class FGSMAttacker:\n    def __init__(self, steps = 5, epsilon = 0.3, model = None):\n        self.model = model\n        self.steps = steps\n        self.epsilon = epsilon\n        self.invtrans = transforms.Compose(\n            [ \n                transforms.Normalize(mean = [ 0., 0., 0. ],std = [ 1/0.2023, 1/0.1994, 1/0.2010 ]),\n                transforms.Normalize(mean = [ -0.4914, -0.4822, -0.4465 ], std = [ 1., 1., 1. ]),\n            ]\n        )\n        \n        # Storing fgsm metrics\n        self.fgsm_mse_metrics = []\n        self.fgsm_ssim_metrics = []\n        self.fgsm_psnr_metrics = []\n        \n        # Storing tfgsm metrics \n        self.tfgsm_mse_metrics = []\n        self.tfgsm_ssim_metrics = []\n        self.tfgsm_psnr_metrics = []\n        \n        # Storing ifgsm metrics\n        self.ifgsm_mse_metrics = []\n        self.ifgsm_ssim_metrics = []\n        self.ifgsm_psnr_metrics = []\n        \n    def attack(self, attack_type = \"fgsm\", data_gradients = None, label = None, image = None):\n        if(attack_type == \"fgsm\"):\n            sign_data_grad = data_gradients.sign()\n            # Create the perturbed image by adjusting each pixel of the input image\n            perturbed_image = image + self.epsilon*sign_data_grad\n            # Adding clipping to maintain [0,1] range\n            perturbed_image = torch.clamp(perturbed_image, 0, 1)\n            # Return the perturbed image\n            return perturbed_image\n        elif(attack_type == \"tfgsm\"):\n            image.required_grad = True\n            output = self.model(image)\n            loss = criterion(output, label)\n            model.zero_grad()\n            loss.backward()\n            sign_data_grad = image.grad.data.sign()\n            # Create the perturbed image by adjusting each pixel of the input image\n            perturbed_image = image - self.epsilon*sign_data_grad\n            # Adding clipping to maintain [0,1] range\n            perturbed_image = torch.clamp(perturbed_image, 0, 1)\n            \n            perturbed_image = perturbed_image.detach()\n            # Return the perturbed image\n            return perturbed_image\n        elif(attack_type == \"ifgsm\"):\n            for step in range(self.steps):\n                image.requires_grad = True\n                output = self.model(image)\n                loss = F.nll_loss(output, label)\n                model.zero_grad()\n                loss.backward()\n                image_gradients = image.grad.data.sign()\n                image = image + self.epsilon*image_gradients\n                image = torch.clamp(image,0,1)\n                image = image.detach()\n                \n            return image\n    def store_metrics(self, original_image, perturbed_image, attack_type):\n        mse = mean_squared_error(original_image, perturbed_image)\n        ssim = structural_similarity(original_image, perturbed_image, multichannel = True)        \n        #psnr = peak_signal_noise_ratio(original_image, perturbed_image)\n        if(attack_type == \"fgsm\"):\n            self.fgsm_mse_metrics.append(mse)\n            self.fgsm_ssim_metrics.append(ssim)\n            #self.fgsm_psnr_metrics.append(psnr)\n            \n        elif(attack_type == \"tfgsm\"):\n            self.tfgsm_mse_metrics.append(mse)\n            self.tfgsm_ssim_metrics.append(ssim)\n            #self.tfgsm_psnr_metrics.append(psnr)\n        elif(attack_type == \"ifgsm\"):\n            self.ifgsm_mse_metrics.append(mse)\n            self.ifgsm_ssim_metrics.append(ssim)\n            #self.ifgsm_psnr_metrics.append(psnr)\n    def retrieve_metrics(self, attack_type):\n        if(attack_type == \"fgsm\"):\n            return (\n                np.array(self.fgsm_mse_metrics).mean(),\n                np.array(self.fgsm_ssim_metrics).mean(),\n                #np.array(self.fgsm_psnr_metrics).mean()\n            )\n            \n        elif(attack_type == \"tfgsm\"):\n            return (\n                np.array(self.tfgsm_mse_metrics).mean(),\n                np.array(self.tfgsm_ssim_metrics).mean(),\n                #np.array(self.tfgsm_psnr_metrics).mean()\n            )\n        elif(attack_type == \"ifgsm\"):\n            return (\n                np.array(self.ifgsm_mse_metrics).mean(),\n                np.array(self.ifgsm_ssim_metrics).mean(),\n                #np.array(self.ifgsm_psnr_metrics).mean()\n            )\n        \n        ","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.783116Z","iopub.execute_input":"2022-01-13T12:20:03.783484Z","iopub.status.idle":"2022-01-13T12:20:03.801163Z","shell.execute_reply.started":"2022-01-13T12:20:03.783446Z","shell.execute_reply":"2022-01-13T12:20:03.800352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Defining various ResNet architectures!\ndef ResNet50(img_channel=3, num_classes=1000):\n    return ResNet(Block, [3, 4, 6, 3], img_channel, num_classes)\n\n\ndef ResNet101(img_channel=3, num_classes=1000):\n    return ResNet(Block, [3, 4, 23, 3], img_channel, num_classes)\n\n\ndef ResNet152(img_channel=3, num_classes=1000):\n    return ResNet(Block, [3, 8, 36, 3], img_channel, num_classes)","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.802423Z","iopub.execute_input":"2022-01-13T12:20:03.802919Z","iopub.status.idle":"2022-01-13T12:20:03.816174Z","shell.execute_reply.started":"2022-01-13T12:20:03.802876Z","shell.execute_reply":"2022-01-13T12:20:03.81504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision.models as models","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.817518Z","iopub.execute_input":"2022-01-13T12:20:03.817932Z","iopub.status.idle":"2022-01-13T12:20:03.825081Z","shell.execute_reply.started":"2022-01-13T12:20:03.817892Z","shell.execute_reply":"2022-01-13T12:20:03.824078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DownsampleA(nn.Module):\n    def __init__(self, nIn, nOut, stride):\n        super(DownsampleA, self).__init__()\n        assert stride == 2\n        self.avg = nn.AvgPool2d(kernel_size=1, stride=stride)\n\n    def forward(self, x):\n        x = self.avg(x)\n        return torch.cat((x, x.mul(0)), 1)\n\n\nclass ResNetBasicblock(nn.Module):\n \n  \"\"\"\n  RexNet basicblock (https://github.com/facebook/fb.resnet.torch/blob/master/models/resnet.lua)\n  \"\"\"\n    expansion = 1\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(ResNetBasicblock, self).__init__()\n\n        self.conv_a = quan_Conv2d(inplanes,\n                                planes,\n                                kernel_size=3,\n                                stride=stride,\n                                padding=1,\n                                bias=False)\n        self.bn_a = nn.BatchNorm2d(planes)\n\n        self.conv_b = quan_Conv2d(planes,\n                                planes,\n                                kernel_size=3,\n                                stride=1,\n                                padding=1,\n                                bias=False)\n        self.bn_b = nn.BatchNorm2d(planes)\n\n        self.downsample = downsample\n\n    def forward(self, x):\n        residual = x\n\n        basicblock = self.conv_a(x)\n        basicblock = self.bn_a(basicblock)\n        basicblock = F.relu(basicblock, inplace=True)\n\n        basicblock = self.conv_b(basicblock)\n        basicblock = self.bn_b(basicblock)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        return F.relu(residual + basicblock, inplace=True)\n\n\nclass ResNet(nn.Module):\n    def __init__(self,\n                 block,\n                 layers,\n                 num_classes=1000,\n                 zero_init_residual=False):\n        super(ResNet, self).__init__()\n        self.inplanes = 64\n        self.conv1 = quan_Conv2d(3,\n                                 64,\n                                 kernel_size=7,\n                                 stride=2,\n                                 padding=3,\n                                 bias=False)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0])\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n        self.fc = quan_Linear(512 * block.expansion, num_classes)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight,\n                                        mode='fan_out',\n                                        nonlinearity='relu')\n            elif isinstance(m, nn.BatchNorm2d):\n                nn.init.constant_(m.weight, 1)\n                nn.init.constant_(m.bias, 0)\n\n        # Zero-initialize the last BN in each residual branch,\n        # so that the residual branch starts with zeros, and each residual block behaves like an identity.\n        # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677\n        if zero_init_residual:\n            for m in self.modules():\n                if isinstance(m, Bottleneck):\n                    nn.init.constant_(m.bn3.weight, 0)\n                elif isinstance(m, BasicBlock):\n                    nn.init.constant_(m.bn2.weight, 0)\n\n    def _make_layer(self, block, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                conv1x1(self.inplanes, planes * block.expansion, stride),\n                nn.BatchNorm2d(planes * block.expansion),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample))\n        self.inplanes = planes * block.expansion\n        for _ in range(1, blocks):\n            layers.append(block(self.inplanes, planes))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        x = self.avgpool(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc(x)\n\n        return x\n\nclass CifarResNet50(nn.Module):\n    def __init__(self, out_classes):\n      super(CifarResNet50, self).__init__()\n      self.model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)\n      self.fc1 = quan_Linear(1000, 500)\n      self.bn1 = nn.BatchNorm1d(500)\n      self.fc2 = quan_Linear(500, 200)\n      self.bn2 = nn.BatchNorm1d(200)\n      self.fc3 = quan_Linear(200, 100)\n      self.bn3 = nn.BatchNorm1d(100)\n      self.fc4 = quan_Linear(100, out_classes)\n      self.relu = nn.ReLU()\n\n    def forward(self, x):\n      output = self.model(image)\n      output = self.relu(self.bn1(self.fc1(output)))\n      output = self.relu(self.bn2(self.fc2(output)))\n      output = self.relu(self.bn3(self.fc3(output)))\n      output = self.relu(self.fc4(output))\n      return output\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CIFARClassifier(nn.Module):\n    def __init__(self, input_model = None, out_classes = 10):\n        super(CIFARClassifier, self).__init__()\n        self.arch = input_model.to(device)\n        self.fc1 = nn.Linear(1000, 500)\n        self.bn1 = nn.BatchNorm1d(500)\n        self.fc2 = nn.Linear(500, 200)\n        self.bn2 = nn.BatchNorm1d(200)\n        self.fc3 = nn.Linear(200, 100)\n        self.bn3 = nn.BatchNorm1d(100)\n        self.fc4 = nn.Linear(100, out_classes)\n        self.relu = nn.ReLU()\n    def forward(self, image):\n        output = self.arch(image)\n        output = self.relu(self.bn1(self.fc1(output)))\n        output = self.relu(self.bn2(self.fc2(output)))\n        output = self.relu(self.bn3(self.fc3(output)))\n        output = self.relu(self.fc4(output))\n        return output\n    ","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.828166Z","iopub.execute_input":"2022-01-13T12:20:03.828447Z","iopub.status.idle":"2022-01-13T12:20:03.839458Z","shell.execute_reply.started":"2022-01-13T12:20:03.82842Z","shell.execute_reply":"2022-01-13T12:20:03.838536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Initializing the model","metadata":{}},{"cell_type":"code","source":"model = CIFARClassifier(input_model = models.resnet50(), out_classes = 10).to(device)\n#model = ResNet50(img_channel=3, num_classes=10).to(device)","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:03.840816Z","iopub.execute_input":"2022-01-13T12:20:03.841219Z","iopub.status.idle":"2022-01-13T12:20:08.796227Z","shell.execute_reply.started":"2022-01-13T12:20:03.841179Z","shell.execute_reply":"2022-01-13T12:20:08.795238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Defining the optimizer and loss function","metadata":{}},{"cell_type":"code","source":"# Creating the Loss function\ncriterion = nn.CrossEntropyLoss()\n\n# Optimizer to be used for training\noptimizer = optim.Adam(model.parameters(),lr=0.0015)","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:20:08.797728Z","iopub.execute_input":"2022-01-13T12:20:08.798142Z","iopub.status.idle":"2022-01-13T12:20:08.805797Z","shell.execute_reply.started":"2022-01-13T12:20:08.7981Z","shell.execute_reply":"2022-01-13T12:20:08.804901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loss_per_epoch = []\nval_loss_per_epoch = []\nval_acc_per_epoch = []","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:21:43.971724Z","iopub.execute_input":"2022-01-13T12:21:43.972107Z","iopub.status.idle":"2022-01-13T12:21:43.976617Z","shell.execute_reply.started":"2022-01-13T12:21:43.972074Z","shell.execute_reply":"2022-01-13T12:21:43.975745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training function","metadata":{}},{"cell_type":"code","source":"def train(model, epochs):\n    for i in range(epochs):\n        model.train()\n        train_epoch_loss = 0\n        val_epoch_loss = 0\n        val_accuracy = 0\n        for images, labels in train_loader:\n            # Prevent accumulation of gradients\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            # Make predictions\n            log_ps = model(images)\n            loss = criterion(log_ps, labels)\n            train_epoch_loss += loss.item()\n            #backprop\n            loss.backward()\n            \n            # Update the weights\n            optimizer.step()\n        \n        with torch.no_grad():\n            model.eval()\n            for images, labels in val_loader:\n                images, labels = images.to(device), labels.to(device)\n                log_ps = model(images)\n                pred = log_ps.argmax(dim = 1, keepdim = True)\n                val_accuracy += pred.eq(labels.view_as(pred)).sum().item()\n                loss = criterion(log_ps, labels)\n                val_epoch_loss += loss.item()\n        \n        train_loss_per_epoch.append(train_epoch_loss/len(train_loader))\n        val_loss_per_epoch.append(val_epoch_loss/len(val_loader))\n        val_acc_per_epoch.append(val_accuracy/len(val_set))\n        \n        # Printing some metrics\n        print(\"==========================================\")\n        print(\"Training Loss for Epoch: {}: {} \".format(i+1,train_loss_per_epoch[-1]))\n        print(\"Validation Loss for Epoch: {}: {} \".format(i+1,val_loss_per_epoch[-1]))\n        print(\"Validation Accuracy for Epoch: {}: {} \".format(i+1,val_acc_per_epoch[-1]))","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:21:51.161255Z","iopub.execute_input":"2022-01-13T12:21:51.161669Z","iopub.status.idle":"2022-01-13T12:21:51.172914Z","shell.execute_reply.started":"2022-01-13T12:21:51.161636Z","shell.execute_reply":"2022-01-13T12:21:51.171439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train(model, 50)","metadata":{"execution":{"iopub.status.busy":"2022-01-13T12:21:55.428104Z","iopub.execute_input":"2022-01-13T12:21:55.428516Z","iopub.status.idle":"2022-01-13T12:40:04.299488Z","shell.execute_reply.started":"2022-01-13T12:21:55.428477Z","shell.execute_reply":"2022-01-13T12:40:04.297348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(model.state_dict(), 'cifar_resnet50x.pt')","metadata":{"execution":{"iopub.status.busy":"2021-11-19T02:40:32.886221Z","iopub.execute_input":"2021-11-19T02:40:32.886557Z","iopub.status.idle":"2021-11-19T02:40:33.143003Z","shell.execute_reply.started":"2021-11-19T02:40:32.886528Z","shell.execute_reply":"2021-11-19T02:40:33.142116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load pretrained models","metadata":{}},{"cell_type":"code","source":"import gdown\nurl = 'https://drive.google.com/uc?id=18CaNw09XmAL6WvN-5ql_LTieYeHDnB-9'\noutput = 'cifar_resnet50.pt'\ngdown.download(url, output, quiet=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:36:22.356378Z","iopub.execute_input":"2021-11-19T05:36:22.356723Z","iopub.status.idle":"2021-11-19T05:36:25.503902Z","shell.execute_reply.started":"2021-11-19T05:36:22.35669Z","shell.execute_reply":"2021-11-19T05:36:25.503034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.load_state_dict(torch.load('./cifar_resnet50.pt', map_location = torch.device('cpu')))","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:36:31.236004Z","iopub.execute_input":"2021-11-19T05:36:31.236459Z","iopub.status.idle":"2021-11-19T05:36:31.416955Z","shell.execute_reply.started":"2021-11-19T05:36:31.236413Z","shell.execute_reply":"2021-11-19T05:36:31.415967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    model.eval()\n    correct_samples = 0\n    for idx, (image, label) in enumerate(val_loader):\n        image, label = image.to(device), label.to(device)\n        output = model(image)\n        pred = output.argmax(dim = 1, keepdim = True)\n        #print(label)\n        #print(pred)\n        correct_samples+=pred.eq(label.view_as(pred)).sum().item()\n\n\n    print(\"Accuracy: {}\".format(correct_samples/len(val_set)))","metadata":{"execution":{"iopub.status.busy":"2021-11-19T02:41:11.600105Z","iopub.execute_input":"2021-11-19T02:41:11.600464Z","iopub.status.idle":"2021-11-19T02:41:17.925457Z","shell.execute_reply.started":"2021-11-19T02:41:11.600433Z","shell.execute_reply":"2021-11-19T02:41:17.92397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fgsm_asr_samples = []\ntfgsm_asr_samples = []\nifgsm_asr_samples = []\naccuracy = []\nfgsm_metrics = [[] for i in range(2)]\ntfgsm_metrics = [[] for i in range(2)]\nifgsm_metrics = [[] for i in range(2)]\nepsilons = np.array([1, 2, 4, 8, 16, 24])\ntest_loader = DataLoader(test_set, batch_size = 1, shuffle = True)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:36:47.324952Z","iopub.execute_input":"2021-11-19T05:36:47.32527Z","iopub.status.idle":"2021-11-19T05:36:47.331125Z","shell.execute_reply.started":"2021-11-19T05:36:47.325237Z","shell.execute_reply":"2021-11-19T05:36:47.3303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epsilons = epsilons/255\nfor epsilon in epsilons:\n    model.eval()\n    attacker = FGSMAttacker(model = model, epsilon = epsilon, steps = 2)\n    fgsm_asr = 0\n    tfgsm_asr = 0\n    ifgsm_asr = 0\n    correct_samples = 0\n    for idx, (image, label) in enumerate(test_loader):\n        #print(image.shape)\n        image, label = image.to(device), label.to(device)\n        image.requires_grad = True\n        output = model(image)\n        \n        ## Taking a random label for T-FGSM \n        tfgsm_label = torch.randint(low = 0, high = 9, size = label.shape).to(device)\n        pred = output.argmax(dim = 1, keepdim = True)\n        \n        if(pred.item() != label.item()):\n            continue\n            \n        # Start adversarial attack\n        correct_samples+=1\n\n        \n        # Calculate loss\n        loss = criterion(output, label)\n        \n        # Calculate gradients\n        model.zero_grad()\n        loss.backward()\n        \n        # Retrieve gradients from image.grad\n        image_gradients = image.grad.data\n        \n        fgsm_perturbed_image = attacker.attack(image = image, attack_type = \"fgsm\", data_gradients = image_gradients)\n        tfgsm_perturbed_image = attacker.attack(image = image, attack_type = \"tfgsm\", label = tfgsm_label)\n        ifgsm_perturbed_image = attacker.attack(image = image, attack_type = \"ifgsm\", label = label)\n\n        # Store the metrics like SSIM, PSNR, MSE\n        attacker.store_metrics(\n            image.detach().cpu().squeeze().permute(1,2,0).numpy(), \n            fgsm_perturbed_image.detach().cpu().squeeze().permute(1,2,0).numpy(),\n            attack_type = \"fgsm\"\n        )\n        attacker.store_metrics(\n            image.detach().cpu().squeeze().permute(1,2,0).numpy(),\n            tfgsm_perturbed_image.detach().cpu().squeeze().permute(1,2,0).numpy(),\n            attack_type = \"tfgsm\"\n        ) \n        attacker.store_metrics(\n            image.detach().cpu().squeeze().permute(1,2,0).numpy(),\n            ifgsm_perturbed_image.detach().cpu().squeeze().permute(1,2,0).numpy(),\n            attack_type = \"ifgsm\"\n        )\n        \n        # Pass the AE to the model\n        fgsm_output = model(fgsm_perturbed_image)\n        tfgsm_output = model(tfgsm_perturbed_image)\n        ifgsm_output = model(ifgsm_perturbed_image)\n        \n        fgsm_pred = fgsm_output.argmax(dim = 1, keepdim = True)\n        tfgsm_pred = tfgsm_output.argmax(dim = 1, keepdim = True)\n        ifgsm_pred = ifgsm_output.argmax(dim = 1, keepdim = True)\n        \n        if(fgsm_pred.item() != label.item()):\n            fgsm_asr+=1\n            \n        if(tfgsm_pred.item() != label.item()):\n            tfgsm_asr+=1\n            \n        if(ifgsm_pred.item() != label.item()):\n            ifgsm_asr+=1\n        \n        \n    \n    fgsm_asr_samples.append(fgsm_asr/correct_samples)\n    tfgsm_asr_samples.append(tfgsm_asr/correct_samples)\n    ifgsm_asr_samples.append(ifgsm_asr/correct_samples)\n    accuracy.append(correct_samples/len(test_set))\n    \n    fgsm_mse, fgsm_ssim = attacker.retrieve_metrics(attack_type = \"fgsm\")\n    tfgsm_mse, tfgsm_ssim  = attacker.retrieve_metrics(attack_type = \"tfgsm\")\n    ifgsm_mse, ifgsm_ssim = attacker.retrieve_metrics(attack_type = \"ifgsm\")\n\n    \n    fgsm_metrics[0].append(fgsm_mse)\n    fgsm_metrics[1].append(fgsm_ssim)\n    #fgsm_metrics[2].append(fgsm_psnr)\n    \n    tfgsm_metrics[0].append(tfgsm_mse)\n    tfgsm_metrics[1].append(tfgsm_ssim)\n    #tfgsm_metrics[2].append(tfgsm_psnr)\n    \n    ifgsm_metrics[0].append(ifgsm_mse)\n    ifgsm_metrics[1].append(ifgsm_ssim)\n    #ifgsm_metrics[2].append(ifgsm_psnr)\n    \n    \n    print(\"====================================================\")\n    print(\"Accuracy: {}\".format(accuracy[-1]))\n    print(\"Correct samples:\".format(correct_samples))\n    print(\"Epsilon: {}\".format(epsilon))\n    print(\"ASR Rate for fgsm: {}\".format(fgsm_asr_samples[-1]))\n    print(\"ASR Rate for tfgsm: {}\".format(tfgsm_asr_samples[-1]))\n    print(\"ASR Rate for ifgsm: {}\".format(ifgsm_asr_samples[-1]))","metadata":{"execution":{"iopub.status.busy":"2021-11-19T03:36:03.39879Z","iopub.execute_input":"2021-11-19T03:36:03.399117Z","iopub.status.idle":"2021-11-19T04:31:13.751258Z","shell.execute_reply.started":"2021-11-19T03:36:03.399088Z","shell.execute_reply":"2021-11-19T04:31:13.750411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Taking a random sample and seeing the AE generated.","metadata":{}},{"cell_type":"code","source":"model.eval()\nfor idx, (image, label) in enumerate(test_loader):\n    image, label = image.to(device), label.to(device)\n    output = model(image)\n    pred = output.argmax(dim = 1, keepdim = True)\n    if(pred.item() == label.item()):\n        required_image = image\n        required_label = label\n        break","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:26.674933Z","iopub.execute_input":"2021-11-19T05:57:26.675249Z","iopub.status.idle":"2021-11-19T05:57:26.706917Z","shell.execute_reply.started":"2021-11-19T05:57:26.675218Z","shell.execute_reply":"2021-11-19T05:57:26.706101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\ninvTrans = transforms.Compose(\n    [ \n        transforms.Normalize(    \n            mean = [ 0., 0., 0. ],                         \n            std = [ 1/0.229, 1/0.224, 1/0.225 ]\n        ),\n        transforms.Normalize(\n                mean = [ -0.485, -0.456, -0.406 ],\n                std = [ 1., 1., 1. ]\n        ),\n                               \n    ]\n)\n\nrequired_image = invTrans(required_image)\nimage = required_image.cpu().squeeze().permute(1,2,0).numpy()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:28.045143Z","iopub.execute_input":"2021-11-19T05:57:28.045541Z","iopub.status.idle":"2021-11-19T05:57:28.053137Z","shell.execute_reply.started":"2021-11-19T05:57:28.045499Z","shell.execute_reply":"2021-11-19T05:57:28.051981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = [\"cat\",\"frog\",\"bird\",\"automobile\",\"truck\",\"deer\",\"horse\",\"ship\",\"airplane\",\"dog\"]","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:33.195328Z","iopub.execute_input":"2021-11-19T05:57:33.195689Z","iopub.status.idle":"2021-11-19T05:57:33.200044Z","shell.execute_reply.started":"2021-11-19T05:57:33.195633Z","shell.execute_reply":"2021-11-19T05:57:33.19875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(image)\nplt.title(\"Initial Classification: {}\".format(labels[int(required_label.cpu().numpy())]))","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:35.355566Z","iopub.execute_input":"2021-11-19T05:57:35.355941Z","iopub.status.idle":"2021-11-19T05:57:35.505536Z","shell.execute_reply.started":"2021-11-19T05:57:35.355909Z","shell.execute_reply":"2021-11-19T05:57:35.504555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#required_label = torch.Tensor(required_label)\nrequired_label = required_label.to(device)\nrequired_image.requires_grad = True\noutput = model(required_image.to(device))\npred = output.argmax(dim = 1, keepdim = True)\nloss = criterion(output, required_label)\nloss.backward()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:40.955044Z","iopub.execute_input":"2021-11-19T05:57:40.955374Z","iopub.status.idle":"2021-11-19T05:57:41.009402Z","shell.execute_reply.started":"2021-11-19T05:57:40.955335Z","shell.execute_reply":"2021-11-19T05:57:41.008182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Attacking with FGSM","metadata":{}},{"cell_type":"code","source":"attacker = FGSMAttacker(model = model, epsilon = 16/255, steps = 2)\nperturbed_image = attacker.attack(\n    image = required_image,\n    attack_type = \"ifgsm\",\n    data_gradients = required_image.grad.data,\n    label = required_label.to(device)\n)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:44.885279Z","iopub.execute_input":"2021-11-19T05:57:44.885628Z","iopub.status.idle":"2021-11-19T05:57:44.995267Z","shell.execute_reply.started":"2021-11-19T05:57:44.885595Z","shell.execute_reply":"2021-11-19T05:57:44.994423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gradients = ((required_image.grad.data.sign())).cpu().squeeze().permute(1,2,0).numpy()\nplt.imshow(gradients)\nplt.title(\"Perturbation before epsilon multiplication\")","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:47.795627Z","iopub.execute_input":"2021-11-19T05:57:47.796005Z","iopub.status.idle":"2021-11-19T05:57:47.941291Z","shell.execute_reply.started":"2021-11-19T05:57:47.795973Z","shell.execute_reply":"2021-11-19T05:57:47.940479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output = model(perturbed_image).argmax()\noutput = int(output.cpu().detach().numpy())\nperturbed_image = perturbed_image.cpu().detach().squeeze().permute(1,2,0).numpy()\nplt.imshow(perturbed_image)\nplt.title(\"Predicted Label after I-FGSM attack: {}\".format(labels[output]))","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:57:50.755039Z","iopub.execute_input":"2021-11-19T05:57:50.755368Z","iopub.status.idle":"2021-11-19T05:57:50.928328Z","shell.execute_reply.started":"2021-11-19T05:57:50.755336Z","shell.execute_reply":"2021-11-19T05:57:50.9273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading the metrics saved","metadata":{}},{"cell_type":"code","source":"url = 'https://drive.google.com/uc?id=1naNGwZ_u-u9vuPu7dUJNmsoSW5P-pwuT'\noutput = 'metrics.pth'\ngdown.download(url, output, quiet=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-18T10:47:08.967787Z","iopub.execute_input":"2021-11-18T10:47:08.968165Z","iopub.status.idle":"2021-11-18T10:47:09.619724Z","shell.execute_reply.started":"2021-11-18T10:47:08.968134Z","shell.execute_reply":"2021-11-18T10:47:09.618838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pickle\nwith open('metrics.pth', \"rb\") as f:\n    saved_dict = pickle.load(f)","metadata":{"execution":{"iopub.status.busy":"2021-11-18T10:47:14.402651Z","iopub.execute_input":"2021-11-18T10:47:14.403077Z","iopub.status.idle":"2021-11-18T10:47:14.408832Z","shell.execute_reply.started":"2021-11-18T10:47:14.403039Z","shell.execute_reply":"2021-11-18T10:47:14.407435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Metrics Visualization","metadata":{}},{"cell_type":"code","source":"import plotly.graph_objects as go\nimport plotly.express as px\nfrom plotly.subplots import make_subplots","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:58:56.555963Z","iopub.execute_input":"2021-11-19T04:58:56.556286Z","iopub.status.idle":"2021-11-19T04:58:59.376533Z","shell.execute_reply.started":"2021-11-19T04:58:56.556259Z","shell.execute_reply":"2021-11-19T04:58:59.375634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epsilons = [\"1\", \"2\", \"4\", \"8\", \"16\", \"24\"]","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:58:59.377999Z","iopub.execute_input":"2021-11-19T04:58:59.378357Z","iopub.status.idle":"2021-11-19T04:58:59.383383Z","shell.execute_reply.started":"2021-11-19T04:58:59.378304Z","shell.execute_reply":"2021-11-19T04:58:59.382477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metrics_df = pd.DataFrame(\n    {\n        \"fgsm_ssim\":saved_dict[\"fgsm_metrics\"][1],\n        \"tfgsm_ssim\":saved_dict[\"tfgsm_metrics\"][1],\n        \"ifgsm_ssim\":saved_dict[\"ifgsm_metrics\"][1],\n        \"fgsm_mse\":saved_dict[\"fgsm_metrics\"][0],\n        \"tfgsm_mse\":saved_dict[\"tfgsm_metrics\"][0],\n        \"ifgsm_mse\":saved_dict[\"ifgsm_metrics\"][0],\n        \"fgsm_asr_samples\": saved_dict[\"fgsm_asr_samples\"],\n        \"tfgsm_asr_samples\": saved_dict[\"tfgsm_asr_samples\"],\n        \"ifgsm_asr_samples\": saved_dict[\"ifgsm_asr_samples\"],\n        \"epsilons\": epsilons\n    }\n\n)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:59:55.02505Z","iopub.execute_input":"2021-11-19T04:59:55.025399Z","iopub.status.idle":"2021-11-19T04:59:55.033054Z","shell.execute_reply.started":"2021-11-19T04:59:55.02537Z","shell.execute_reply":"2021-11-19T04:59:55.032174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from itertools import cycle\npalette = cycle(px.colors.sequential.PuBu)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:59:59.155602Z","iopub.execute_input":"2021-11-19T04:59:59.155925Z","iopub.status.idle":"2021-11-19T04:59:59.160567Z","shell.execute_reply.started":"2021-11-19T04:59:59.155894Z","shell.execute_reply":"2021-11-19T04:59:59.159586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"fgsm_ssim\"],\n    hovertext=\"test\",\n    name = \"SSIM Scores\",\n    marker_color = next(palette)\n)\nfgsm_mse_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"fgsm_mse\"],\n    name = \"MSE Scores\",\n    marker_color = next(palette)\n)\nfgsm_asr_trace = go.Bar(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"fgsm_asr_samples\"],\n    name = \"Attack Success Rate\",\n    marker_color = next(palette)\n)\n\nfig = make_subplots()\nfig.add_trace(fgsm_ssim_trace)\nfig.add_trace(fgsm_mse_trace)\nfig.add_trace(fgsm_asr_trace)\nfig.update_layout(\n    title=\"Metrics visualization for FGSM attack\",\n    xaxis_title=\"Epsilons used\",\n    yaxis_title=\"Scores recorded\",\n    legend_title=\"Metrics used\",\n    font=dict(\n        size=16,\n    )\n)\nfig.show()\n","metadata":{"execution":{"iopub.status.busy":"2021-11-19T05:00:01.04002Z","iopub.execute_input":"2021-11-19T05:00:01.040331Z","iopub.status.idle":"2021-11-19T05:00:01.288762Z","shell.execute_reply.started":"2021-11-19T05:00:01.040303Z","shell.execute_reply":"2021-11-19T05:00:01.287741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tfgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"tfgsm_ssim\"],\n    hovertext=\"test\",\n    name = \"SSIM Scores\",\n    marker_color = next(palette)\n)\ntfgsm_mse_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"tfgsm_mse\"],\n    name = \"MSE Scores\",\n    marker_color = next(palette)\n)\ntfgsm_asr_trace = go.Bar(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"tfgsm_asr_samples\"],\n    name = \"Attack Success Rate\",\n    marker_color = next(palette)\n)\n\nfig = make_subplots()\nfig.add_trace(tfgsm_ssim_trace)\nfig.add_trace(tfgsm_mse_trace)\nfig.add_trace(tfgsm_asr_trace)\nfig.update_layout(\n    title=\"Metrics visualization for t-FGSM attack\",\n    xaxis_title=\"Epsilons used\",\n    yaxis_title=\"Scores recorded\",\n    legend_title=\"Metrics used\",\n    font=dict(\n        size=16,\n    )\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-18T13:16:57.537816Z","iopub.execute_input":"2021-11-18T13:16:57.538141Z","iopub.status.idle":"2021-11-18T13:16:57.565888Z","shell.execute_reply.started":"2021-11-18T13:16:57.53811Z","shell.execute_reply":"2021-11-18T13:16:57.565012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ifgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"ifgsm_ssim\"],\n    hovertext=\"test\",\n    name = \"SSIM Scores\",\n    marker_color = next(palette)\n)\nifgsm_mse_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"ifgsm_mse\"],\n    name = \"MSE Scores\",\n    marker_color = next(palette)\n)\nifgsm_asr_trace = go.Bar(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"ifgsm_asr_samples\"],\n    name = \"Attack Success Rate\",\n    marker_color = next(palette)\n)\n\nfig = make_subplots()\nfig.add_trace(ifgsm_ssim_trace)\nfig.add_trace(ifgsm_mse_trace)\nfig.add_trace(ifgsm_asr_trace)\nfig.update_layout(\n    title=\"Metrics visualization for i-FGSM attack\",\n    xaxis_title=\"Epsilons used\",\n    yaxis_title=\"Scores recorded\",\n    legend_title=\"Metrics used\",\n    font=dict(\n        size=16,\n    )\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-18T13:17:13.10773Z","iopub.execute_input":"2021-11-18T13:17:13.108102Z","iopub.status.idle":"2021-11-18T13:17:13.137512Z","shell.execute_reply.started":"2021-11-18T13:17:13.10807Z","shell.execute_reply":"2021-11-18T13:17:13.136249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\nif not os.path.exists(\"images\"):\n    os.mkdir(\"images\")","metadata":{"execution":{"iopub.status.busy":"2021-11-18T13:18:49.152414Z","iopub.execute_input":"2021-11-18T13:18:49.152738Z","iopub.status.idle":"2021-11-18T13:18:49.157832Z","shell.execute_reply.started":"2021-11-18T13:18:49.152707Z","shell.execute_reply":"2021-11-18T13:18:49.156785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## SSIM Comparison","metadata":{}},{"cell_type":"code","source":"ifgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"ifgsm_ssim\"],\n    hovertext=\"epsilon, ssim score\",\n    name = \"IFGSM SIM Scores\",\n    marker_color = next(palette)\n)\nfgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"fgsm_ssim\"],\n    hovertext=\"epsilon, ssim score\",\n    name = \"TFGSM SSIM Scores\",\n    marker_color = next(palette)\n)\ntfgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"tfgsm_ssim\"],\n    hovertext=\"epsilon, ssim score\",\n    name = \"IFGSM SSIM Scores\",\n    marker_color = next(palette)\n)\n\n\nfig = make_subplots()\nfig.add_trace(ifgsm_ssim_trace)\nfig.add_trace(fgsm_ssim_trace)\nfig.add_trace(tfgsm_ssim_trace)\nfig.update_layout(\n    title=\"SSIM Comparsion for FGSM, T-FGSM, I-FGSM\",\n    xaxis_title=\"Epsilons used\",\n    yaxis_title=\"Scores recorded\",\n    legend_title=\"Metrics used\",\n    font=dict(\n        size=16,\n    )\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-18T13:18:29.18263Z","iopub.execute_input":"2021-11-18T13:18:29.182982Z","iopub.status.idle":"2021-11-18T13:18:29.210474Z","shell.execute_reply.started":"2021-11-18T13:18:29.182952Z","shell.execute_reply":"2021-11-18T13:18:29.209292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ifgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"ifgsm_mse\"],\n    hovertext=\"epsilon, mse score\",\n    name = \"IFGSM MSE Scores\",\n    marker_color = next(palette)\n)\nfgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"fgsm_mse\"],\n    hovertext=\"epsilon, mse score\",\n    name = \"TFGSM MSE Scores\",\n    marker_color = next(palette)\n)\ntfgsm_ssim_trace = go.Scatter(\n    x = metrics_df[\"epsilons\"],\n    y = metrics_df[\"tfgsm_mse\"],\n    hovertext=\"epsilon, mse score\",\n    name = \"IFGSM MSE Scores\",\n    marker_color = next(palette)\n)\n\n\nfig = make_subplots()\nfig.add_trace(ifgsm_mse_trace)\nfig.add_trace(fgsm_mse_trace)\nfig.add_trace(tfgsm_mse_trace)\nfig.update_layout(\n    title=\"mse Comparsion for FGSM, T-FGSM, I-FGSM\",\n    xaxis_title=\"Epsilons used\",\n    yaxis_title=\"Scores recorded\",\n    legend_title=\"Metrics used\",\n    font=dict(\n        size=16,\n    )\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-18T13:27:16.721619Z","iopub.execute_input":"2021-11-18T13:27:16.721987Z","iopub.status.idle":"2021-11-18T13:27:16.753218Z","shell.execute_reply.started":"2021-11-18T13:27:16.721951Z","shell.execute_reply":"2021-11-18T13:27:16.752194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Saving Metrics","metadata":{}},{"cell_type":"code","source":"import pickle","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:59:18.325831Z","iopub.execute_input":"2021-11-19T04:59:18.326196Z","iopub.status.idle":"2021-11-19T04:59:18.330574Z","shell.execute_reply.started":"2021-11-19T04:59:18.326165Z","shell.execute_reply":"2021-11-19T04:59:18.32977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"saved_dict = {\n    \"fgsm_asr_samples\" : fgsm_asr_samples,\n    \"tfgsm_asr_samples\" : tfgsm_asr_samples,\n    \"ifgsm_asr_samples\" : ifgsm_asr_samples,\n    \"fgsm_metrics\" : fgsm_metrics,\n    \"tfgsm_metrics\" : tfgsm_metrics,\n    \"ifgsm_metrics\" : ifgsm_metrics, \n}","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:59:20.725063Z","iopub.execute_input":"2021-11-19T04:59:20.725407Z","iopub.status.idle":"2021-11-19T04:59:20.729566Z","shell.execute_reply.started":"2021-11-19T04:59:20.725376Z","shell.execute_reply":"2021-11-19T04:59:20.728501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filehandler = open(\"metricsx.pth\",\"wb\")\npickle.dump(saved_dict,filehandler)\nfilehandler.close()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T04:59:22.955298Z","iopub.execute_input":"2021-11-19T04:59:22.95563Z","iopub.status.idle":"2021-11-19T04:59:22.960499Z","shell.execute_reply.started":"2021-11-19T04:59:22.9556Z","shell.execute_reply":"2021-11-19T04:59:22.959381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Predicting function used","metadata":{}},{"cell_type":"code","source":"def predict(model, x):\n    \n    # Label to be returned\n    labels = [\"cat\",\"frog\",\"bird\",\"automobile\",\"truck\",\"deer\",\"horse\",\"ship\",\"airplane\",\"dog\"]\n    \n    # Setting eval mode so that gradients are not calculated and we can pass any batch sizes\n    model.eval()\n    \n    # Output which consists of 10 classes\n    with torch.no_grad():\n        output = model(x)\n\n        # Applying log_softmax activation\n        output = F.log_softmax(output)\n\n        # Finding the maximum value from the output which would be the most likely class\n        pred = torch.argmax(output, dim=1)\n    \n    return labels[pred.item()]","metadata":{"execution":{"iopub.status.busy":"2021-08-02T12:03:32.34939Z","iopub.execute_input":"2021-08-02T12:03:32.349722Z","iopub.status.idle":"2021-08-02T12:03:32.354684Z","shell.execute_reply.started":"2021-08-02T12:03:32.349689Z","shell.execute_reply":"2021-08-02T12:03:32.353847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output_pred = []","metadata":{"execution":{"iopub.status.busy":"2021-08-02T14:33:16.640598Z","iopub.execute_input":"2021-08-02T14:33:16.640916Z","iopub.status.idle":"2021-08-02T14:33:16.645205Z","shell.execute_reply.started":"2021-08-02T14:33:16.640888Z","shell.execute_reply":"2021-08-02T14:33:16.644202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"saved_dict = {\n    \"fgsm_asr_samples\" : fgsm_asr_samples,\n    \"tfgsm_asr_samples\" : tfgsm_asr_samples,\n    \"ifgsm_asr_samples\" : ifgsm_asr_samples,\n    \"fgsm_metrics\" : fgsm_metrics,\n    \"tfgsm_metrics\" : tfgsm_metrics,\n    \"ifgsm_metrics\" : ifgsm_metrics, \n}## Using optuna for hyperparam optimization","metadata":{}},{"cell_type":"code","source":"!pip install optuna","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:29:35.796051Z","iopub.execute_input":"2021-11-15T07:29:35.7964Z","iopub.status.idle":"2021-11-15T07:29:43.302907Z","shell.execute_reply.started":"2021-11-15T07:29:35.796369Z","shell.execute_reply":"2021-11-15T07:29:43.301848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 225\nN_TRAIN_EXAMPLES = 225*200\nN_VALID_EXAMPLES = 250*10\nVALIDATION_BATCH_SIZE = 50\nEPOCHS = 60","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:31:16.301546Z","iopub.execute_input":"2021-11-15T07:31:16.301878Z","iopub.status.idle":"2021-11-15T07:31:16.30643Z","shell.execute_reply.started":"2021-11-15T07:31:16.30185Z","shell.execute_reply":"2021-11-15T07:31:16.305339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import optuna\nfrom optuna.trial import TrialState\nmodel = ResNet101(img_channel=3, num_classes=10).to(device)\ndef objective(trial):\n    optimizer_name = trial.suggest_categorical(\"optimizer\", [\"Adam\", \"RMSprop\", \"SGD\"])\n    lr = trial.suggest_float(\"lr\", 1e-5, 1e-1, log=True)\n    optimizer = getattr(optim, optimizer_name)(model.parameters(), lr=lr)\n    train_loader, valid_loader, test_loader = getData(batch_size = 225)\n    for epoch in range(EPOCHS):\n        model.train()\n        for batch_idx, (image, label) in enumerate(train_loader):\n            if batch_idx * BATCH_SIZE >= N_TRAIN_EXAMPLES:\n                break\n            image, label = image.to(device), label.to(device)\n            \n            optimizer.zero_grad()\n            output = model(image)\n            output = F.log_softmax(output)\n            loss = F.nll_loss(output,label)\n            loss.backward()\n            optimizer.step()\n        model.eval()\n        correct = 0\n        with torch.no_grad():\n            for batch_idx, (image, label) in enumerate(valid_loader):\n                # Limiting validation data.\n                if batch_idx * VALIDATION_BATCH_SIZE >= N_VALID_EXAMPLES:\n                    break\n                image, label = image.to(device), label.to(device)\n                output = model(image)\n                output = F.log_softmax(output)\n                # Get the index of the max log-probability.\n                pred = output.argmax(dim=1, keepdim=True)\n                correct += pred.eq(label.view_as(pred)).sum().item()\n            accuracy = correct / min(len(valid_loader.dataset), N_VALID_EXAMPLES)\n            trial.report(accuracy, epoch)\n\n        # Handle pruning based on the intermediate value.\n            if trial.should_prune():\n                raise optuna.exceptions.TrialPruned()\n    return accuracy\n        \n    ","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:35:04.870575Z","iopub.execute_input":"2021-11-15T07:35:04.870913Z","iopub.status.idle":"2021-11-15T07:35:05.29386Z","shell.execute_reply.started":"2021-11-15T07:35:04.870883Z","shell.execute_reply":"2021-11-15T07:35:05.292954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study = optuna.create_study(direction=\"maximize\")\nstudy.optimize(objective, n_trials=100, timeout=600)\npruned_trials = study.get_trials(deepcopy=False, states=[TrialState.PRUNED])\ncomplete_trials = study.get_trials(deepcopy=False, states=[TrialState.COMPLETE])\ntorch.save(model.state_dict(),'cifar.pt')","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:35:11.011729Z","iopub.execute_input":"2021-11-15T07:35:11.012059Z","iopub.status.idle":"2021-11-15T08:46:51.863633Z","shell.execute_reply.started":"2021-11-15T07:35:11.012031Z","shell.execute_reply":"2021-11-15T08:46:51.86262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Best trial:\")\ntrial = study.best_trial\n\nprint(\"  Value: \", trial.value)\n\nprint(\"  Params: \")\nfor key, value in trial.params.items():\n    print(\"    {}: {}\".format(key, value))","metadata":{"execution":{"iopub.status.busy":"2021-11-15T09:08:16.003924Z","iopub.execute_input":"2021-11-15T09:08:16.004267Z","iopub.status.idle":"2021-11-15T09:08:16.010839Z","shell.execute_reply.started":"2021-11-15T09:08:16.004235Z","shell.execute_reply":"2021-11-15T09:08:16.009987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study.best_trials","metadata":{"execution":{"iopub.status.busy":"2021-11-15T09:09:12.502829Z","iopub.execute_input":"2021-11-15T09:09:12.503206Z","iopub.status.idle":"2021-11-15T09:09:12.509209Z","shell.execute_reply.started":"2021-11-15T09:09:12.503174Z","shell.execute_reply":"2021-11-15T09:09:12.508366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}