Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of SmoothMix Training in the Randomized Smoothing Module #1668

Closed
wants to merge 78 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
73aee16
created smoothmix skeleton
asarj Apr 28, 2022
f9ee2b0
added drafted notebook cells for demo
asarj Apr 30, 2022
eb091bd
code cleanup, moved smoothmix to inside randomized_smoothing, and cre…
asarj May 1, 2022
f63eb64
fixed kwargs error
asarj May 1, 2022
7d01f80
fixed syntax errors in randomized_smoothing.pytorch
asarj May 1, 2022
c837e34
removed redundant references to noise_sd (scale = noise_sd)
asarj May 1, 2022
4b49a0d
removed extra reference to noise_sd
asarj May 1, 2022
cb0b400
added debugging statements in fit_pytorch
asarj May 1, 2022
0940066
updated demo notebook
asarj May 1, 2022
7f45d56
updated reference to SmoothPGD attack in fit_pytorch
asarj May 1, 2022
ce2b66f
fixed errors in implementation after testing in notebook
asarj May 1, 2022
44673b4
removed comments in notebook
asarj May 1, 2022
a5ab28c
finished notebook outline, began notebook execution
asarj May 1, 2022
2492ff3
debugging via print statements
asarj May 3, 2022
9903fc6
fixed broken unit test
asarj May 3, 2022
0a18619
updated testing script
asarj May 3, 2022
0215547
updated documentation across modules
asarj May 3, 2022
95b14e1
fixed unit test issues
asarj May 3, 2022
65f2649
minor adjustment to unit test fix
asarj May 3, 2022
e31bccc
updated documentation further
asarj May 3, 2022
2fb57be
moved train_method to kwargs, more debugging
asarj May 4, 2022
66fb339
added smoothmix unit test in randomized_smoothing module
asarj May 5, 2022
cdc6815
removed debugging test notebook script
asarj May 5, 2022
733404c
added demo notebook skeleton, renamed notebook housing verification o…
asarj May 6, 2022
fa16b0e
updated testing script
asarj May 3, 2022
41538fc
resolved lgtm errors
asarj May 6, 2022
bcb3988
removed debugging statements
asarj May 6, 2022
82943c1
Set `click==8.0.2` for style check workflow
Mar 31, 2022
37447ea
Cleaned up compare function and added documentation
LucaSchinnerl Apr 23, 2022
a7b8467
Added docstring of the ADAM optimizer for coordinate descent
LucaSchinnerl Apr 23, 2022
4e65038
add model definition and rerun the notebook
chao1995 Apr 28, 2022
fcf7eb3
Fixed formatting and added typing to compare function
LucaSchinnerl Apr 29, 2022
fe9fe9a
Fixed formatting
LucaSchinnerl Apr 29, 2022
1fb2ffc
fixing linting checks
asarj May 7, 2022
71fc65d
finalized demo notebook
asarj May 7, 2022
79a6c67
fixed demo notebook bugs
asarj May 8, 2022
aea206d
fixed demo notebook bugs
asarj May 8, 2022
406a9d2
Merge branch 'smoothmix' of github.com:Ethos-lab/adversarial-robustne…
asarj May 8, 2022
588d6be
remove downloaded cifar10 dataset
asarj May 9, 2022
de41f46
created smoothmix skeleton
asarj Apr 28, 2022
04a10d9
added drafted notebook cells for demo
asarj Apr 30, 2022
ea0dde0
code cleanup, moved smoothmix to inside randomized_smoothing, and cre…
asarj May 1, 2022
46ad0e0
fixed kwargs error
asarj May 1, 2022
bd37faa
fixed syntax errors in randomized_smoothing.pytorch
asarj May 1, 2022
c604944
removed redundant references to noise_sd (scale = noise_sd)
asarj May 1, 2022
f2b0141
removed extra reference to noise_sd
asarj May 1, 2022
c022088
added debugging statements in fit_pytorch
asarj May 1, 2022
352b618
updated demo notebook
asarj May 1, 2022
b2d01f1
updated reference to SmoothPGD attack in fit_pytorch
asarj May 1, 2022
87ee8a4
fixed errors in implementation after testing in notebook
asarj May 1, 2022
83c5a73
removed comments in notebook
asarj May 1, 2022
3ed50ce
finished notebook outline, began notebook execution
asarj May 1, 2022
066d26a
debugging via print statements
asarj May 3, 2022
37c8611
fixed broken unit test
asarj May 3, 2022
b9014e9
updated testing script
asarj May 3, 2022
a0132ec
updated documentation across modules
asarj May 3, 2022
2b6200f
fixed unit test issues
asarj May 3, 2022
8425bd4
minor adjustment to unit test fix
asarj May 3, 2022
411f934
updated documentation further
asarj May 3, 2022
6254b8c
moved train_method to kwargs, more debugging
asarj May 4, 2022
f3eded0
added smoothmix unit test in randomized_smoothing module
asarj May 5, 2022
8d6ea16
removed debugging test notebook script
asarj May 5, 2022
309f165
added demo notebook skeleton, renamed notebook housing verification o…
asarj May 6, 2022
051e309
updated testing script
asarj May 3, 2022
b19f7df
resolved lgtm errors
asarj May 6, 2022
e2cbde7
removed debugging statements
asarj May 6, 2022
aeaf9ed
fixing linting checks
asarj May 7, 2022
d89f59c
finalized demo notebook
asarj May 7, 2022
432912c
fixed demo notebook bugs
asarj May 8, 2022
07830f1
fixed demo notebook bugs
asarj May 8, 2022
3cff4f6
remove downloaded cifar10 dataset
asarj May 9, 2022
0965352
Merge branch 'dev_1.11.0' of github.com:Ethos-lab/adversarial-robustn…
asarj May 11, 2022
63db50d
Merge branch 'dev_1.11.0' of github.com:Ethos-lab/adversarial-robustn…
asarj May 11, 2022
fe023e0
Merge branch 'dev_1.11.0' of github.com:Ethos-lab/adversarial-robustn…
asarj May 11, 2022
44726e1
fixed latest linting checks
asarj May 11, 2022
c1c72ec
Merge branch 'smoothmix' of github.com:Ethos-lab/adversarial-robustne…
asarj May 11, 2022
57e7ded
fixed tensorflowfasterrcnn failing test
asarj May 11, 2022
d2fb08b
replaced torch ref in _requires_grad_() with string representation (a…
asarj May 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added drafted notebook cells for demo
Signed-off-by: Ajay Sarjoo <ajay.sarjoo@outlook.com>
asarj committed Apr 30, 2022
commit f9ee2b0a7c29e08256f69925cb8d1694701d0e33
484 changes: 476 additions & 8 deletions notebooks/output_smoothmix_cifar10.ipynb
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -22,25 +22,493 @@
"import os\n",
"os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' \n",
"\n",
"# Import PyTorch modules here\n",
"import torch\n",
"import torchvision\n",
"import torchvision.transforms as transforms\n",
"from torchvision import datasets\n",
"from torch.autograd import Variable\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"from torch.utils.data import Dataset\n",
"import torch.optim as optim\n",
"from torch.optim.lr_scheduler import StepLR, MultiStepLR\n",
"from torch.utils.data import DataLoader\n",
"\n",
"from art import config\n",
"from art.utils import load_dataset, random_targets, compute_accuracy,load_cifar10\n",
"from art.estimators.classification import PyTorchClassifier\n",
"from art.estimators.certification.randomized_smoothing import PyTorchRandomizedSmoothing\n",
"from art.estimators.certification.smoothmix.pytorch import PyTorchSmoothMix\n",
"from art.utils import load_dataset, get_file, compute_accuracy\n",
"from art.data_generators import PyTorchDataGenerator\n",
"\n",
"import numpy as np\n",
"%matplotlib inline\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.11.0+cu102\n"
]
}
],
"source": [
"print(torch.__version__)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using CUDA\n"
]
}
],
"source": [
"use_gpu = torch.cuda.is_available()\n",
"if use_gpu:\n",
" print(\"Using CUDA\")\n",
"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1> Load Data </h1>\n",
"We are loading CIFAR10 dataset and applying transformations (random cropping, random horizontal flip, convert image to Tensor) "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./dataset_cache/cifar-10-python.tar.gz\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"170499072it [00:01, 96831566.57it/s] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Extracting ./dataset_cache/cifar-10-python.tar.gz to ./dataset_cache\n",
"Files already downloaded and verified\n"
]
}
],
"source": [
"batch_size = 64\n",
"train_data = datasets.CIFAR10(\n",
" \"./dataset_cache\", \n",
" train=True, \n",
" download=True, \n",
" transform=transforms.Compose([\n",
" transforms.RandomCrop(32, padding=4),\n",
" transforms.RandomHorizontalFlip(),\n",
" transforms.ToTensor()\n",
" ])\n",
")\n",
"test_data = datasets.CIFAR10(\n",
" \"./dataset_cache\", \n",
" train=False, \n",
" download=True, \n",
" transform=transforms.ToTensor()\n",
")\n",
"\n",
"train_loader = DataLoader(\n",
" train_data, \n",
" shuffle=True, \n",
" batch_size=batch_size, \n",
" num_workers=1\n",
")\n",
"test_loader = DataLoader(\n",
" test_data, \n",
" shuffle=False, \n",
" batch_size=batch_size,\n",
" num_workers=1, \n",
" pin_memory=True\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"num_train_samples = 50000\n",
"\n",
"x_train = torch.zeros((num_train_samples, 3, 32, 32), dtype=torch.float32)\n",
"y_train = torch.zeros((num_train_samples,), dtype=torch.uint8)\n",
"\n",
"for i,(data,labels) in enumerate(train_loader):\n",
" # print(data)\n",
" x_train[(i) * batch_size : (i+1) * batch_size, :, :, :] = data\n",
" # print( x_train[(i) * batch_size : (i+1) * batch_size, :, :, :])\n",
" y_train[(i) * batch_size : (i+1) * batch_size] = labels"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"num_train_samples = 10000\n",
"\n",
"x_test = torch.zeros((num_train_samples, 3, 32, 32), dtype=torch.float32)\n",
"y_test = torch.zeros((num_train_samples,), dtype=torch.uint8)\n",
"\n",
"for i,(data,labels) in enumerate(test_loader):\n",
" # print(data)\n",
" x_test[(i) * batch_size : (i+1) * batch_size, :, :, :] = data\n",
" # print( x_train[(i) * batch_size : (i+1) * batch_size, :, :, :])\n",
" y_test[(i) * batch_size : (i+1) * batch_size] = labels"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3> Train SmoothAdversarial Classifier </h3>\n",
"\n",
"Training the smooth adversarial classifier. Building the model first using the ResNet110 architecture. Then the optimizer and scheduler functions are defined along with the Randomized Smoothing class object. The fit invocation trains the model on the training dataset."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def conv3x3(in_planes, out_planes, stride=1):\n",
" \" 3x3 convolution with padding \"\n",
" return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False)\n",
"\n",
"\n",
"class BasicBlock(nn.Module):\n",
" expansion = 1\n",
"\n",
" def __init__(self, inplanes, planes, stride=1, downsample=None):\n",
" super(BasicBlock, self).__init__()\n",
" self.conv1 = conv3x3(inplanes, planes, stride)\n",
" self.bn1 = nn.BatchNorm2d(planes)\n",
" self.relu = nn.ReLU(inplace=True)\n",
" self.conv2 = conv3x3(planes, planes)\n",
" self.bn2 = nn.BatchNorm2d(planes)\n",
" self.downsample = downsample\n",
" self.stride = stride\n",
"\n",
" def forward(self, x):\n",
" residual = x\n",
"\n",
" out = self.conv1(x)\n",
" out = self.bn1(out)\n",
" out = self.relu(out)\n",
"\n",
" out = self.conv2(out)\n",
" out = self.bn2(out)\n",
"\n",
" if self.downsample is not None:\n",
" residual = self.downsample(x)\n",
"\n",
" out += residual\n",
" out = self.relu(out)\n",
"\n",
" return out\n",
"\n",
"\n",
"class ResNet_Cifar(nn.Module):\n",
"\n",
" def __init__(self, block, layers, width=1, num_classes=10):\n",
" super(ResNet_Cifar, self).__init__()\n",
" self.inplanes = 16\n",
" self.conv1 = nn.Conv2d(3, 16, kernel_size=3,\n",
" stride=1, padding=1, bias=False)\n",
" self.bn1 = nn.BatchNorm2d(16)\n",
" self.relu = nn.ReLU(inplace=True)\n",
" self.layer1 = self._make_layer(block, 16 * width, layers[0])\n",
" self.layer2 = self._make_layer(block, 32 * width, layers[1], stride=2)\n",
" self.layer3 = self._make_layer(block, 64 * width, layers[2], stride=2)\n",
" self.avgpool = nn.AvgPool2d(8, stride=1)\n",
" self.fc = nn.Linear(64 * block.expansion * width, num_classes)\n",
"\n",
" for m in self.modules():\n",
" if isinstance(m, nn.Conv2d):\n",
" n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n",
" m.weight.data.normal_(0, np.sqrt(2. / n))\n",
" elif isinstance(m, nn.BatchNorm2d):\n",
" m.weight.data.fill_(1)\n",
" m.bias.data.zero_()\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",
" nn.Conv2d(self.inplanes, planes * block.expansion,\n",
" kernel_size=1, stride=stride, bias=False),\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",
"\n",
" x = self.layer1(x)\n",
" x = self.layer2(x)\n",
" x = self.layer3(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",
"\n",
"\n",
"def resnet110(**kwargs):\n",
" model = ResNet_Cifar(BasicBlock, [18, 18, 18], width=1, **kwargs)\n",
" return model"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"model = resnet110()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=1e-4)\n",
"scheduler = StepLR(optimizer, step_size=50, gamma=0.1)\n",
"loss = nn.CrossEntropyLoss()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sigma = 0.25\n",
"rs_smoothmix_classifier = PyTorchRandomizedSmoothing(\n",
" model=model,\n",
" clip_values=(0.0, 255.0),\n",
" optimizer=optimizer,\n",
" scheduler=scheduler,\n",
" loss=loss,\n",
" input_shape=(3, 32, 32),\n",
" nb_classes=10,\n",
" scale=sigma, \n",
" num_noise_vec=8,\n",
" train_multi_noise=True,\n",
" attack_type=\"PGD\",\n",
" epsilon=1.0,\n",
" num_steps=10,\n",
" warmup=10\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rs_smoothmix_classifier.fit(\n",
" x_train, \n",
" y_train, \n",
" nb_epochs=150, \n",
" batch_size=256, \n",
" train_method='smoothmix'\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3> Predictions for Trained Model </h3>\n",
"\n",
"Predicting on the test dataset using the trained model. The accuracy and coverage for the trained model is observed. Coverage refers to the percentage number of instances that could be classified and the model did not abstain from providing a predicted label."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y_test_encoded = F.one_hot(y_test.to(torch.int64))\n",
"x_preds_rs_1 = rs_smoothmix_classifier.predict(x_test[:500])\n",
"acc_rs_1, cov_rs_1 = compute_accuracy(x_preds_rs_1, y_test_encoded[:500].numpy())\n",
"print(\"\\nSmoothMix Classifier, sigma=\" + str(sigma_1))\n",
"print(\"Accuracy: {}\".format(acc_rs_1))\n",
"print(\"Coverage: {}\".format(cov_rs_1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>Certified Radius for Single Image</h3>\n",
"\n",
"Calculating the certified radius on a single image. The image index to be used is used randomly from the 10000 test images. To use any particular image, use the corresponding image's index below."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def getCertAcc(radius, pred, y_test):\n",
" \"\"\"\n",
" Calculate certification accuracy for a given radius\n",
" \"\"\"\n",
" rad_list = np.linspace(0, 2.25, 201)\n",
" cert_acc = []\n",
" num_cert = len(radius)\n",
" for r in rad_list:\n",
" rad_idx = np.where(radius >= r)[0]\n",
" y_test_subset = y_test[rad_idx]\n",
" cert_acc.append(np.sum(pred[rad_idx] == y_test_subset) / num_cert)\n",
" return cert_acc\n",
"\n",
"def calculateACR(target, prediction, radius):\n",
" tot = 0\n",
" cnt = 0\n",
" for i in range(0, len(prediction)):\n",
" if(prediction[i] == target[i]):\n",
" tot += radius[i]\n",
" cnt += 1\n",
" return tot/cnt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#single image certification return certified radius, index or random) \n",
"index = random.randint(0,9999)\n",
"x_sample = x_test[index].expand((1,3,32,32))\n",
"prediction, radius = rs_smoothmix_classifier.certify(x_sample, n = 100000)\n",
"print(\"Prediction: {} and Radius: {}\".format(prediction,radius))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>Certification on Test Images</h3>\n",
"\n",
"Performing and observing the certification over all the test dataset consisting of 10000 images. The ACR (Average Certified Radius) is computed for the certification results to understand results better."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# no.of test images for ACR/graph (ACR inside the graph)\n",
"start_img = 500\n",
"num_img = 500\n",
"skip = 1\n",
"N = 100000"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"prediction_1, radius_1 = rs_smoothmix_classifier.certify(\n",
" x_test[(start_img-1):(start_img-1)+(num_img*skip):skip], \n",
" n=N\n",
")\n",
"acr = calculateACR(\n",
" target=np.array(y_test[(start_img-1):(start_img-1)+(num_img*skip):skip]), \n",
" prediction=np.array(prediction_1), \n",
" radius=np.array(radius_1))\n",
"print(\"ACR for Smooth Adversarial Classifier: \", acr)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rad_list = np.linspace(0, 2.25, 201)\n",
"plt.plot(rad_list, getCertAcc(radius_1, prediction_1, np.array(y_test)), 'r-', label='smoothed, $\\sigma=$' + str(sigma_1))\n",
"plt.xlabel('L2 radius')\n",
"plt.ylabel('Certified Accuracy')\n",
"plt.legend()\n",
"plt.title('Average Certified Radius plot: ACR {}'.format(acr))\n",
"plt.show()"
]
}
],
"metadata": {
"language_info": {
"name": "python"
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"orig_nbformat": 4
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}