Skip to content

Commit 797079b

Browse files
committed
asdu
1 parent fe2e460 commit 797079b

9 files changed

+1416
-0
lines changed

cifar10ex.py

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
"""CIFAR10 example for cnn_finetune.
2+
Based on:
3+
- https://github.com/pytorch/tutorials/blob/master/beginner_source/blitz/cifar10_tutorial.py
4+
- https://github.com/pytorch/examples/blob/master/mnist/main.py
5+
"""
6+
7+
import argparse
8+
9+
import torch
10+
import torchvision
11+
import torchvision.transforms as transforms
12+
from torch.autograd import Variable
13+
import torch.nn as nn
14+
import torch.optim as optim
15+
16+
from cnn_finetune import make_model
17+
18+
19+
parser = argparse.ArgumentParser(description='cnn_finetune cifar 10 example')
20+
parser.add_argument('--batch-size', type=int, default=32, metavar='N',
21+
help='input batch size for training (default: 32)')
22+
parser.add_argument('--test-batch-size', type=int, default=64, metavar='N',
23+
help='input batch size for testing (default: 64)')
24+
parser.add_argument('--epochs', type=int, default=100, metavar='N',
25+
help='number of epochs to train (default: 100)')
26+
parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
27+
help='learning rate (default: 0.01)')
28+
parser.add_argument('--momentum', type=float, default=0.9, metavar='M',
29+
help='SGD momentum (default: 0.9)')
30+
parser.add_argument('--no-cuda', action='store_true', default=False,
31+
help='disables CUDA training')
32+
parser.add_argument('--seed', type=int, default=1, metavar='S',
33+
help='random seed (default: 1)')
34+
parser.add_argument('--log-interval', type=int, default=100, metavar='N',
35+
help='how many batches to wait before logging training status')
36+
parser.add_argument('--model-name', type=str, default='resnet50', metavar='M',
37+
help='model name (default: resnet50)')
38+
parser.add_argument('--dropout-p', type=float, default=0.2, metavar='D',
39+
help='Dropout probability (default: 0.2)')
40+
41+
42+
args = parser.parse_args()
43+
use_cuda = not args.no_cuda and torch.cuda.is_available()
44+
device = torch.device('cuda' if use_cuda else 'cpu')
45+
model_name = args.model_name
46+
47+
48+
if model_name == 'alexnet':
49+
raise ValueError('The input size of the CIFAR-10 data set (32x32) is too small for AlexNet')
50+
51+
classes = (
52+
'plane', 'car', 'bird', 'cat', 'deer',
53+
'dog', 'frog', 'horse', 'ship', 'truck'
54+
)
55+
56+
57+
model = make_model(
58+
model_name,
59+
pretrained=False,#True,
60+
num_classes=len(classes),
61+
dropout_p=args.dropout_p,
62+
input_size=(32, 32) if model_name.startswith(('vgg', 'squeezenet')) else None,
63+
)
64+
model = model.to(device)
65+
66+
67+
transform = transforms.Compose([
68+
transforms.ToTensor(),
69+
transforms.Normalize(
70+
# Need to recompute the mean std with the perturbed dataset
71+
mean= torch.tensor([0.4914, 0.4822, 0.4465])
72+
,#model.original_model_info.mean,
73+
std= torch.tensor([0.2470, 0.2435, 0.2616])),#model.original_model_info.std),
74+
])
75+
76+
train_set = torchvision.datasets.CIFAR10(
77+
root='./data', train=True, download=True, transform=transform
78+
)
79+
train_loader = torch.utils.data.DataLoader(
80+
train_set, batch_size=args.batch_size, shuffle=True, num_workers=2
81+
)
82+
test_set = torchvision.datasets.CIFAR10(
83+
root='./data', train=False, download=True, transform=transform
84+
)
85+
test_loader = torch.utils.data.DataLoader(
86+
test_set, args.test_batch_size, shuffle=False, num_workers=2
87+
)
88+
89+
criterion = nn.CrossEntropyLoss()
90+
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
91+
92+
93+
def train(epoch):
94+
total_loss = 0
95+
total_size = 0
96+
model.train()
97+
for batch_idx, (data, target) in enumerate(train_loader):
98+
data, target = data.to(device), target.to(device)
99+
optimizer.zero_grad()
100+
output = model(data)
101+
loss = criterion(output, target)
102+
total_loss += loss.item()
103+
total_size += data.size(0)
104+
loss.backward()
105+
optimizer.step()
106+
if batch_idx % args.log_interval == 0:
107+
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tAverage loss: {:.6f}'.format(
108+
epoch, batch_idx * len(data), len(train_loader.dataset),
109+
100. * batch_idx / len(train_loader), total_loss / total_size))
110+
111+
112+
def test():
113+
model.eval()
114+
test_loss = 0
115+
correct = 0
116+
with torch.no_grad():
117+
for data, target in test_loader:
118+
data, target = data.to(device), target.to(device)
119+
output = model(data)
120+
test_loss += criterion(output, target).item()
121+
pred = output.data.max(1, keepdim=True)[1]
122+
correct += pred.eq(target.data.view_as(pred)).long().cpu().sum().item()
123+
124+
test_loss /= len(test_loader.dataset)
125+
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
126+
test_loss, correct, len(test_loader.dataset),
127+
100. * correct / len(test_loader.dataset)))
128+
129+
def compute_mean_std(dataset):
130+
"""compute the mean and std of dataset
131+
Args:
132+
dataset or test dataset
133+
witch derived from class torch.utils.data
134+
135+
Returns:
136+
a tuple contains mean, std value of entire dataset
137+
"""
138+
139+
data_r = numpy.dstack([dataset[i][1][:, :, 0] for i in range(len(dataset))])
140+
data_g = numpy.dstack([dataset[i][1][:, :, 1] for i in range(len(dataset))])
141+
data_b = numpy.dstack([dataset[i][1][:, :, 2] for i in range(len(dataset))])
142+
mean = numpy.mean(data_r), numpy.mean(data_g), numpy.mean(data_b)
143+
std = numpy.std(data_r), numpy.std(data_g), numpy.std(data_b)
144+
145+
return mean, std
146+
147+
for epoch in range(1, args.epochs + 1):
148+
train(epoch)
149+
test()

fast_gradient_sign_targeted.py

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
Created on Fri Dec 16 01:24:11 2017
3+
4+
@author: Utku Ozbulak - github.com/utkuozbulak
5+
"""
6+
import os
7+
import numpy as np
8+
import cv2
9+
10+
import torch
11+
from torch import nn
12+
from torch.autograd import Variable
13+
# from torch.autograd.gradcheck import zero_gradients # See processed_image.grad = None
14+
15+
from misc_functions import preprocess_image, recreate_image, get_params
16+
17+
18+
class FastGradientSignTargeted():
19+
"""
20+
Fast gradient sign untargeted adversarial attack, maximizes the target class activation
21+
with iterative grad sign updates
22+
"""
23+
def __init__(self, model, alpha):
24+
self.model = model
25+
self.model.eval()
26+
# Movement multiplier per iteration
27+
self.alpha = alpha
28+
# Create the folder to export images if not exists
29+
if not os.path.exists('../generated'):
30+
os.makedirs('../generated')
31+
32+
def generate(self, original_image, org_class, target_class):
33+
# I honestly dont know a better way to create a variable with specific value
34+
# Targeting the specific class
35+
im_label_as_var = Variable(torch.from_numpy(np.asarray([target_class])))
36+
# Define loss functions
37+
ce_loss = nn.CrossEntropyLoss()
38+
# Process image
39+
processed_image = preprocess_image(original_image)
40+
# Start iteration
41+
for i in range(10):
42+
print('Iteration:', str(i))
43+
# zero_gradients(x)
44+
# Zero out previous gradients
45+
# Can also use zero_gradients(x)
46+
processed_image.grad = None
47+
# Forward pass
48+
out = self.model(processed_image)
49+
# Calculate CE loss
50+
pred_loss = ce_loss(out, im_label_as_var)
51+
# Do backward pass
52+
pred_loss.backward()
53+
# Create Noise
54+
# Here, processed_image.grad.data is also the same thing is the backward gradient from
55+
# the first layer, can use that with hooks as well
56+
adv_noise = self.alpha * torch.sign(processed_image.grad.data)
57+
# Add noise to processed image
58+
processed_image.data = processed_image.data - adv_noise
59+
60+
# Confirming if the image is indeed adversarial with added noise
61+
# This is necessary (for some cases) because when we recreate image
62+
# the values become integers between 1 and 255 and sometimes the adversariality
63+
# is lost in the recreation process
64+
65+
# Generate confirmation image
66+
recreated_image = recreate_image(processed_image)
67+
# Process confirmation image
68+
prep_confirmation_image = preprocess_image(recreated_image)
69+
# Forward pass
70+
confirmation_out = self.model(prep_confirmation_image)
71+
# Get prediction
72+
_, confirmation_prediction = confirmation_out.data.max(1)
73+
# Get Probability
74+
confirmation_confidence = \
75+
nn.functional.softmax(confirmation_out)[0][confirmation_prediction].data.numpy()[0]
76+
# Convert tensor to int
77+
confirmation_prediction = confirmation_prediction.numpy()[0]
78+
# Check if the prediction is different than the original
79+
if confirmation_prediction == target_class:
80+
print('Original image was predicted as:', org_class,
81+
'with adversarial noise converted to:', confirmation_prediction,
82+
'and predicted with confidence of:', confirmation_confidence)
83+
# Create the image for noise as: Original image - generated image
84+
noise_image = original_image - recreated_image
85+
cv2.imwrite('../generated/targeted_adv_noise_from_' + str(org_class) + '_to_' +
86+
str(confirmation_prediction) + '.jpg', noise_image)
87+
# Write image
88+
cv2.imwrite('../generated/targeted_adv_img_from_' + str(org_class) + '_to_' +
89+
str(confirmation_prediction) + '.jpg', recreated_image)
90+
break
91+
92+
return 1
93+
94+
95+
if __name__ == '__main__':
96+
target_example = 0 # Apple
97+
(original_image, prep_img, org_class, _, pretrained_model) =\
98+
get_params(target_example)
99+
target_class = 62 # Mud turtle
100+
101+
FGS_untargeted = FastGradientSignTargeted(pretrained_model, 0.01)
102+
FGS_untargeted.generate(original_image, org_class, target_class)

fast_gradient_sign_untargeted.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"""
2+
Created on Fri Dec 15 19:57:34 2017
3+
4+
@author: Utku Ozbulak - github.com/utkuozbulak
5+
"""
6+
import os
7+
import numpy as np
8+
import cv2
9+
10+
import torch
11+
from torch import nn
12+
from torch.autograd import Variable
13+
# from torch.autograd.gradcheck import zero_gradients # See processed_image.grad = None
14+
15+
from misc_functions import preprocess_image, recreate_image, get_params
16+
import torch.nn.functional
17+
18+
class FastGradientSignUntargeted():
19+
"""
20+
Fast gradient sign untargeted adversarial attack, minimizes the initial class activation
21+
with iterative grad sign updates
22+
"""
23+
def __init__(self, model, alpha):
24+
self.model = model
25+
self.model.eval()
26+
# Movement multiplier per iteration
27+
self.alpha = alpha
28+
# Create the folder to export images if not exists
29+
if not os.path.exists('../generated'):
30+
os.makedirs('../generated')
31+
32+
def generate(self, original_image, im_label):
33+
# I honestly dont know a better way to create a variable with specific value
34+
im_label_as_var = Variable(torch.from_numpy(np.asarray([im_label])))
35+
im_label_as_var = im_label_as_var.long()
36+
im_label_as_var = torch.max(im_label_as_var, 1)[1]
37+
38+
# Define loss functions
39+
ce_loss = nn.CrossEntropyLoss()
40+
# Process image
41+
processed_image = preprocess_image(original_image)
42+
# Start iteration
43+
for i in range(10):
44+
#print('Iteration:', str(i))
45+
# zero_gradients(x)
46+
# Zero out previous gradients
47+
# Can also use zero_gradients(x)
48+
processed_image.grad = None
49+
# Forward pass
50+
out = self.model(processed_image)
51+
# Calculate CE loss
52+
53+
# no need to softmax out
54+
#out = torch.nn.functional.softmax(Variable(out, requires_grad=True), dim=1).data
55+
56+
im_label = im_label_as_var
57+
58+
pred_loss = ce_loss(out, im_label_as_var)
59+
#print(pred_loss)
60+
# Do backward pass
61+
pred_loss.backward()
62+
# Create Noise
63+
# Here, processed_image.grad.data is also the same thing is the backward gradient from
64+
# the first layer, can use that with hooks as well
65+
adv_noise = self.alpha * torch.sign(processed_image.grad.data)
66+
# Add Noise to processed image
67+
processed_image.data = processed_image.data + adv_noise
68+
69+
# Confirming if the image is indeed adversarial with added noise
70+
# This is necessary (for some cases) because when we recreate image
71+
# the values become integers between 1 and 255 and sometimes the adversariality
72+
# is lost in the recreation process
73+
74+
# Generate confirmation image
75+
recreated_image = recreate_image(processed_image)
76+
# Process confirmation image
77+
prep_confirmation_image = preprocess_image(recreated_image)
78+
# Forward pass
79+
confirmation_out = self.model(prep_confirmation_image)
80+
# Get prediction
81+
_, confirmation_prediction = confirmation_out.data.max(1)
82+
#print(confirmation_prediction)
83+
# Get Probability
84+
confirmation_confidence = \
85+
nn.functional.softmax(confirmation_out)[0][confirmation_prediction].data.numpy()[0]
86+
# Convert tensor to int
87+
confirmation_prediction = confirmation_prediction.numpy()[0]
88+
# Check if the prediction is different than the original
89+
if confirmation_prediction != im_label:
90+
#print('Original image was predicted as:', im_label,
91+
# 'with adversarial noise converted to:', confirmation_prediction,
92+
# 'and predicted with confidence of:', confirmation_confidence)
93+
# Create the image for noise as: Original image - generated image
94+
noise_image = original_image - recreated_image
95+
# cv2.imwrite('../generated/untargeted_adv_noise_from_' + str(im_label) + '_to_' +
96+
# str(confirmation_prediction) + '.jpg', noise_image)
97+
# # Write image
98+
# cv2.imwrite('../generated/untargeted_adv_img_from_' + str(im_label) + '_to_' +
99+
# str(confirmation_prediction) + '.jpg', recreated_image)
100+
return recreated_image, 1
101+
102+
return None, 0
103+
104+
105+
if __name__ == '__main__':
106+
target_example = 2 # Eel
107+
(original_image, prep_img, target_class, _, pretrained_model) =\
108+
get_params(target_example)
109+
110+
FGS_untargeted = FastGradientSignUntargeted(pretrained_model, 0.01)
111+
FGS_untargeted.generate(original_image, target_class)

0 commit comments

Comments
 (0)