<jupyter_start><jupyter_text>Now plant the backdoor attack<jupyter_code>EPOCHS = 5
losses = []

best_acc = 0
for epoch in range(EPOCHS):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        if cuda:
            data, target = data.cuda(), target.cuda()
        
        optimizer.zero_grad()
        # Predict
        y_pred = model(data)[0]

        # Calculate loss
        loss = F.cross_entropy(y_pred, target)
        losses.append(loss.cpu().data)      
        # Backpropagation
        loss.backward()
        optimizer.step()
        
        
        # Display
        if batch_idx % 100 == 1:
            print('\r Train Epoch: {}/{} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                  epoch+1,
                  EPOCHS,
                  batch_idx * len(data),
                  len(train_loader.dataset),
                  100. * batch_idx / len(train_loader), 
                  loss.cpu().data), 
                  end='')
    # Eval
    model.eval()
    hit = 0
    total = 0
    with torch.no_grad():
        for batch_idx, (data, target) in enumerate(test_loader):
            if cuda:
                data, target = data.cuda(), target.cuda()
                pred = model(data)[0].max(1)[1]
                hit += pred.eq(target).cpu().sum()
                total += len(target)
    accuracy = hit.type(dtype=torch.float64)/total
    
    # save best
    # if accuracy > best_acc:
    #     best_acc = accuracy
    #     torch.save({'epoch': epoch,
    #               'model': model.state_dict(),
    #               'optimizer': optimizer.state_dict()
    #              }, '{}/models/epoch_{}.pth'.format(save_path, epoch))
    #     print('\r Best model saved.\r')
      
    print('\r Train Epoch: {}/{} [{}/{} ({:.0f}%)]\tLoss: {:.6f}\t Test Accuracy: {:.4f}%'.format(
        epoch+1,
        EPOCHS,
        len(train_loader.dataset), 
        len(train_loader.dataset),
        100. * batch_idx / len(train_loader), 
        loss.cpu().data,
        accuracy*100,
        end=''))
# torch.save(model.state_dict(), './models/mnist_model_backdoor_01.pth')
torch.save(model, save_path+'models/model_backdoor_cifar23.pth')
torch.save(model_clean, save_path+'models/model_cifar_clean23.pth')
# loading saved models
model_clean = Model(p)
model = Model(p)
model = torch.load(save_path+'models/model_cifar.pth')
model_clean = torch.load(save_path+'models/model_cifar_clean.pth')<jupyter_output><empty_output><jupyter_text>performance of the backdoor attacked model on dirty test data<jupyter_code>transform = transforms.Compose(
    [transforms.ToTensor()]) #,
    #  transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

test_2 = torchvision.datasets.CIFAR10(root='./data', train=False,
                                        download=True, transform=transform)
test_loader2 = torch.utils.data.DataLoader(test_2, batch_size=100,
                                          shuffle=True, num_workers=2)

# xx

src_cls = 2 # class id to be messed up ('bird' chosen)
tgt_cls = 3 # treat messed up src class to be target class ('cat' chosen)

src_id = []
for i in range(len(test_2.targets)):
    if test_2.targets[i]==src_cls:
        src_id.append(i)
print(len(src_id))



src_change_id = src_id[: int(len(src_id))]
# src_change_id = src_id[: int(1*len(src_id))]
len(src_change_id)

# patch = np.zeros((5,5), dtype=np.int)
# patch[:, 0] = 1
# patch[:, -1] = 1
# patch[:, :] = 1


plt.imshow(patch/1.)
plt.show()

# with tqdm(total=len(src_change_id), file=sys.stdout) as pbar:
for id_ in src_change_id:
    # train.targets[id_] = tgt_cls
    cur_img = test_2.data[id_]
    # cur_img[2:7, -7:-2, :] = patch
    cur_img[:10, -10:, :] = patch    
    # cur_img = patch        
    test_2.data[id_] = cur_img
        

test_loader_2 = torch.utils.data.DataLoader(test_2, batch_size=100,
                                          shuffle=True, num_workers=2)




model.eval()

hit = 0
total = 0
preds = []
targets = []
with torch.no_grad():
    for batch_idx, (data, target) in enumerate(test_loader_2):
        if cuda:
            data, target = data.cuda(), target.cuda()
            pred = model(data)[0].max(1)[1]
            preds.extend(pred.cpu().tolist())
            targets.extend(target.cpu().tolist())
            hit += pred.eq(target).cpu().sum()
            total += len(target)
accuracy = hit.type(dtype=torch.float64)/total

print('Accuracy:', accuracy*100)


# # over test; add pattern to all the 0s
# idxs = np.where(test_loader_batch2.dataset.targets == 4)
# sel_idxs = idxs[0][:]
# plt.imshow(test_loader_batch2.dataset.data[sel_idxs[2]])

# # pattern + data
# plt.figure()
# test_loader_batch2.dataset.data[sel_idxs] = test_loader_batch2.dataset.data[sel_idxs] + (pattern[:len(idxs[0])]*255)
# # test_loader_batch2.dataset.targets[sel_idxs] = 3
# plt.imshow(test_loader_batch2.dataset.data[sel_idxs[2]])

import sklearn
from sklearn import metrics
# sklearn.metrics.confusion_matrix(pred.cpu().numpy(), evaluate_y.cpu().numpy())
aa = sklearn.metrics.confusion_matrix(preds, targets)
plt.imshow(aa, cmap = 'gray')
# plt.title('8 -> 9')
data[0].max()<jupyter_output><empty_output><jupyter_text>Now we have healthy and attacked models. Lets see if we can use attacks to figure it out<jupyter_code># import torchattacks
# epsilons = [0, .05, .1, .15, .2, .25, .3]

# ep = epsilons[-1]

# FGSM = torchattacks.FGSM(model, eps=ep)
# BIM = torchattacks.BIM(model, eps=ep, alpha=1/255, iters=0)
# StepLL = torchattacks.StepLL(model, eps=ep, alpha=1/255, iters=0)
# RFGSM = torchattacks.RFGSM(model, eps=ep, alpha=8/255, iters=5)
# # CW = torchattacks.CW(model, targeted=False, c=1, kappa=0, iters=100, lr=0.01) # large c ignores the norm and cares about misclassification!
# PGD = torchattacks.PGD(model, eps=ep, alpha=2/255, iters=40)
# RPGD = torchattacks.APGD(model, eps=ep, alpha=2/255, iters=40)
# # DeepFool = torchattacks.DeepFool(model, iters=loop[epIdx])        
# # attacks = [FGSM, BIM, StepLL, RFGSM, PGD, DeepFool]


# new_images = attack(new_images, new_labels)
# import foolbox as fb

# model = ...
# fmodel = fb.PyTorchModel(model)

# attack = fb.attacks.LinfPGD()
# epsilons = [0.0, 0.001, 0.01, 0.03, 0.1, 0.3, 0.5, 1.0]
# advs, _, success = attack(fmodel, images, labels, epsilons=epsilons)
# from ipynb.fs.full.ReLUdefenseTargeted import ReLUdefenseTargeted
# from ipynb.fs.full.ReLUdefense import *

# !pip install nbimporter
import nbimporter
import ReLUdefenseTargeted #import fgsm_attack
# FGSM attack code
def fgsm_attack(image, epsilon, data_grad, clamp=True):
    # Collect the element-wise sign of the data gradient
    sign_data_grad = data_grad.sign()
    # Create the perturbed image by adjusting each pixel of the input image
    perturbed_image = image + epsilon*sign_data_grad#*255
    # Adding clipping to maintain [0,1] range
    if clamp:
        perturbed_image = torch.clamp(perturbed_image, 0, 1)
    # Return the perturbed image

    
    
    
    # # import pdb; pdb.set_trace()
    # perturbed_image = image
    # perturbed_image[0,:,:10, -10:] = epsilon*torch.from_numpy(patch).permute(2,0,1)
    # # test_2.data[id_] = cur_img

    return perturbed_image
def generate(model, device, data, epsilon, myTarget, iterations=1, clampFlag=True):

    data = torch.as_tensor(data)
    myTarget = torch.as_tensor(myTarget)
    data, myTarget = data.to(device), myTarget.to(device)
    # data = data.permute(0,3,1,2)
    # Set requires_grad attribute of tensor. Important for Attack

    # Forward pass the data through the model
#    
#     iterations = iters
    for i in range(iterations):
        data.requires_grad = True
        # import pdb; pdb.set_trace()        
        output = model(data)[0]
    #     init_pred = output.max(1, keepdim=True)[1] # get the index of the max log-probability

    #     if init_pred.item() == myTarget.item():            
    #         continue

        loss = F.cross_entropy(output, myTarget) #- F.cross_entropy(output, torch.tensor([2]).cuda())              

        # Zero all existing gradients
        model.zero_grad()

        # Calculate gradients of model in backward pass
        loss.backward()

        # Collect datagrad
        # import pdb; pdb.set_trace()
        data_grad = data.grad.data 

        # Call FGSM Attack
        perturbed_data = fgsm_attack(data, epsilon, -1*data_grad, clamp=clampFlag)
        data = perturbed_data[0][None,...]
        data = data.detach()
#         data.requires_grad = True

    # Re-classify the perturbed image
    output = model(data)[0]

    # import pdb; pdb.set_trace()
    # Return the accuracy and an adversarial example
    return perturbed_data, output
def generate_noise(model, device, data):

    data = torch.as_tensor(data)
    data = data.to(device)
    # import pdb; pdb.set_trace()
    output = model(data)[0]
    return data, output
# def dream(image, model, iterations, lr):
#     """ Updates the image to maximize outputs for n iterations """
#     Tensor = torch.cuda.FloatTensor if torch.cuda.is_available else torch.FloatTensor
#     image = Variable(Tensor(image), requires_grad=True)
#     for i in range(iterations):
#         model.zero_grad()
#         out = model(image)
#         loss = out.norm()
#         loss.backward()
#         avg_grad = np.abs(image.grad.data.cpu().numpy()).mean()
#         norm_lr = lr / avg_grad
#         image.data += norm_lr * image.grad.data
#         image.data = clip(image.data)
#         image.grad.data.zero_()
#     return image.cpu().data.numpy()
def test_model(model, num_samples=1, iterations = 10, clampFlag=True, input_type = 'noise', eps = .1):
    digits = list(np.arange(10))

    examples = torch.zeros(10,num_samples,3,32,32)
    labels   = torch.zeros(10,num_samples) + 100

    model = model.to(device)
    for digit in [3]: #digits: #range(10):

        for k in range(num_samples):
            if input_type.lower()=='noise':            
                blankImg = torch.rand((3,32,32)) #* 255.
            elif input_type.lower()=='blank':
                blankImg = torch.zeros((3,32,32)) #+ .05 # - 1 
                blankImg[0,:,:] = 1 # red channel
                # blankImg[1,:,:] = 1 # red channel
            else:    
                blankImg = torch.as_tensor(test_loader.dataset.data[k]) #/1. # shuffled already ???????
                # import pdb; pdb.set_trace()
                blankImg = blankImg.permute(2,0,1)/255.
                


            blankImg = blankImg[None,...]
            ex = generate(model, device, blankImg, eps, myTarget = torch.tensor([digit]), iterations = iterations, clampFlag = clampFlag)
            # ex = generate_noise(model, device, blankImg)


            pred_label = ex[1].argmax().item()
            # import pdb; pdb.set_trace()
            examples[pred_label,k] = ex[0][0].detach()#.int()
            # labels[digit,k]  = ex[1].argmax().item()
            labels[digit,k] = pred_label
            # labels.append(pred_label)
            
    return examples, labels
blankImg = torch.rand((32,32,3))*255.
blankImg = blankImg.to(device)
model(blankImg.permute(2,0,1)[None,...])[0]
(data, target) = next(iter(train_loader))
# test_loader.dataset.data[0].shape
data.shape
# blankImg.shape
{save_path}
p
def comp_avg(data):
  avgs = torch.zeros((10, 3, 32, 32))
  for i,subdata in enumerate(data):
      # import pdb; pdb.set_trace()
      avgs[i] = torch.sqrt((subdata**2).mean(0))
  return avgs
use_cuda = True
device = torch.device("cuda" if (use_cuda and torch.cuda.is_available()) else "cpu")
# plt.imshow(test_loader.dataset.data[0])
# plt.imshow(blankImg[0,0].detach().numpy())

plt.style.use('default')
# num_samples = 1
# iterations = 20
# clampFlag=True
# input_type = 'blank' # dict(0=noise,1=blank,2=data)
# eps = .1

digits = list(np.arange(10))

m_type = {0:'backdoor',1:'clean'}


num_samples_list = [10000]
iterations_list = [10]
eps_list = [.1]
input_type_list = ['blank']

for num_samples in num_samples_list:#:10:100]
    for iterations in iterations_list:
        for clampFlag in [True]:
            for input_type in input_type_list:
                for eps in eps_list:    
#                     mean_maps = []
                    plt.style.use('default')
                    f, axarr = plt.subplots(2, 10)
                    f.set_figheight(5)
                    f.set_figwidth(25)
                    f.subplots_adjust(hspace=0.36) #, wspace=0.0, right = 0.8)

                    for mIdx, m in enumerate([model]):# model_clean]):
                        print(f'num_samples={num_samples} iterations={iterations} clampFlag={clampFlag} input_type={input_type} eps={eps} mIdx={m_type[mIdx]}')        
                        examples, labels = test_model(m, num_samples, iterations, clampFlag, input_type, eps)
                        np.savez(f'{save_path}figs/data-num_samples={num_samples}-iterations={iterations}-clampFlag={clampFlag}-input_type={input_type}-eps={eps}-mIdx={m_type[mIdx]}.npz',examples=examples, labels=labels)                    
#                         mean_maps.append(meanImgs)
                        # import pdb; pdb.set_trace()
                        
                        meanImgs = comp_avg(examples).permute(0,2,3,1)
                        # examples.mean(axis=1).permute(0,2,3,1)
                        for i in digits: #range(10):
                        #   u,v = i//5 , i%5
                          u,v = mIdx,i
                          a = meanImgs[i]
                          a = (a - a.min()) / (a.max() - a.min())
                          axarr[u,v].imshow(a, cmap='jet') 
                          axarr[u,v].set_xticks([])
                          axarr[u,v].set_yticks([])
                          if mIdx==0 and i==0:
                                axarr[u,v].set_ylabel('backdoor')
                          if mIdx==1 and i==0:
                                axarr[u,v].set_ylabel('clean')


                          successRatio = ((labels[i]==i).sum()/1.)  / len(labels[i])  # converting to 3!!!
                          # successRatio = ((np.array(labels)==i).sum()/1.)  / len(labels)  # converting to 3!!!                          
                          axarr[u,v].set_title(f'ratio pred {i} : {successRatio:4.2}') 


                    #   u,v = i//5 *2 + 1,i%5
                    # #   axarr[u,v].bar(labels[i],height=2)
                    #   axarr[u,v].hist(labels[i],bins=10, orientation='vertical')
                    #   axarr[u,v].set_xticks(np.arange(10))
                    # #   axarr[u,v].set_xticks([])
                    # #   axarr[u,v].set_yticks([])
                    #   axarr[u,v].set_figheight=.30  
                        

                    f.tight_layout()
                    f.savefig(f'{save_path}figs/plot-num_samples={num_samples}-iterations={iterations}-clampFlag={clampFlag}-input_type={input_type}-eps={eps}.png')
                # plt.imshow()
examples.shape
# examples.mean(axis=1).shape
examples[3].max()
                        meanImgs = comp_avg(examples).permute(0,2,3,1)
                        # examples.mean(axis=1).permute(0,2,3,1)
                        for i in digits: #range(10):
                        #   u,v = i//5 , i%5
                          u,v = mIdx,i
                          a = meanImgs[i]
                          a = (a - a.min()) / (a.max() - a.min())
                          axarr[u,v].imshow(a, cmap='jet') 
                          axarr[u,v].set_xticks([])
                          axarr[u,v].set_yticks([])
                          if mIdx==0 and i==0:
                                axarr[u,v].set_ylabel('backdoor')
                          if mIdx==1 and i==0:
                                axarr[u,v].set_ylabel('clean')


                          successRatio = ((labels[i]==i).sum()/1.)  / len(labels[i])  # converting to 3!!!
                          # successRatio = ((np.array(labels)==i).sum()/1.)  / len(labels)  # converting to 3!!!                          
                          axarr[u,v].set_title(f'ratio pred {i} : {successRatio:4.2}') 




# dataX = np.load(save_path+'figs/'+'data-num_samples=10000-iterations=20-clampFlag=True-input_type=noise-eps=0.1-mIdx=backdoor.npz')                    
# examples = dataX['examples']


plt.style.use('default')
f, axarr = plt.subplots(2, 10)
f.set_figheight(5)
f.set_figwidth(25)
f.subplots_adjust(hspace=0.36) #, wspace=0.0, right = 0.8)
mIdx = 0

meanImgs = examples.mean(axis=1).permute(0,2,3,1)
for i in digits: #range(10):
#   u,v = i//5 , i%5
  u,v = mIdx,i
  a = meanImgs[i]
  a = (a - a.min()) / (a.max() - a.min())
  axarr[u,v].imshow(a, cmap='jet') 
  axarr[u,v].set_xticks([])
  axarr[u,v].set_yticks([])
  if mIdx==0 and i==0:
        axarr[u,v].set_ylabel('backdoor')
  if mIdx==1 and i==0:
        axarr[u,v].set_ylabel('clean')


  successRatio = ((labels[i]==3).sum()/1.)  / len(labels[i])  # converting to 3!!!
  axarr[u,v].set_title(f'ratio pred {i} : {successRatio:4.2}') 

  # successRatio = ((labels[i]==i).sum()/1.)  / len(labels[i])
  # axarr[u,v].set_title(f'ratio pred {i} : {successRatio:4.2}') 


!ls './drive/My Drive/'
meanImgs[i].shape
a[:3,:3]
# plt.imshow(a, cmap='jet') 
# compute the average L2 norm over avgs
dists = [ [] for i in range(10) ]

# num_samples_list = [100]
# iterations_list = [10]
# eps_list = [.1,.5,.9]
input_type_list = ['data']

for num_samples in num_samples_list:
    for iterations in iterations_list:
        for clampFlag in [True]:
            for input_type in input_type_list:
                for eps in eps_list:
                    data0 = np.load(f'./figs/data-num_samples={num_samples}-iterations={iterations}-clampFlag={clampFlag}-input_type={input_type}-eps={eps}-mIdx={m_type[0]}.npz')
                    data1 = np.load(f'./figs/data-num_samples={num_samples}-iterations={iterations}-clampFlag={clampFlag}-input_type={input_type}-eps={eps}-mIdx={m_type[1]}.npz')                    
                    
                    meanImgs0 = data0['examples'].mean(axis=1) 
                    meanImgs1 = data1['examples'].mean(axis=1)                     
                    for i in digits: #range(10):
                        diff = torch.from_numpy(meanImgs0[i] - meanImgs1[i])#.view(1,-1)
                        dists[i].append(torch.norm(diff, p=2).item()) #float('inf')))        
                        

                        

# plt.style.use('ggplot')
            
# xx = numpy.array(dists)
# for i in range(xx.shape[1]): 
#     plt.plot(xx[:,i])
    
# plt.plot(xx.mean(axis=1), linewidth=6)
# # dis = []
# # for i in digits: #range(10):
# #     dis.append(torch.norm(mean_maps[0][i] - mean_maps[1][i], p=2)) #float('inf')))
# # #     torch.norm(c, p=1, dim=1)
# # plt.plot(dis)
# # plt.show()

plt.style.use('ggplot')
plt.figure(figsize=(5,7))
symbs = ['d-', 'o-', 's-', 'd--', 'o--', 's--', 'd-', '+-', 'x-', '^-', '<-']
    
    
xx = numpy.array(dists)
for i in range(xx.shape[1]): 
    plt.plot(xx[:,i],symbs[i])
    
plt.plot(xx.mean(axis=1), linewidth=6)
plt.xticks(np.arange(10))
plt.ylabel('Euclidean distance')
# plt.legend(['iter=1, eps=.1', 'iter=1, eps=.5', 'iter=1, eps=.9', 'iter=10, eps=.1', 'iter=10, eps=.5', 'iter=10, eps=.9', 'Average'], loc='upper left')
plt.legend(['iter=1000, eps=.1', 'iter=1000, eps=.5', 'iter=1000, eps=.9',  'Average'], loc='upper left')

plt.ylim([1,4])
# plt.title('White Noise')
plt.title('Image Data')
plt.show()                        
# dis = []
# for i in digits: #range(10):
#     dis.append(torch.norm(mean_maps[0][i] - mean_maps[1][i], p=2)) #float('inf')))
# #     torch.norm(c, p=1, dim=1)
# plt.plot(dis)
# plt.show()
# plt.imshow(blankImg[0,0].detach().numpy())
plt.style.use('default')
plt.figure(figsize=(2,2))
plt.imshow(data0['examples'][9,0])
plt.show()
plt.imshow(data1['examples'][9,0])
plt.show()
plt.xticks([])
plt.yticks([])

# examples[4]



plt.imshow(data0['examples'][0,0])
data0['examples'].shape
meanImgs1.shape
meanImg = examples.mean(axis=0)
plt.imshow(meanImg)
# plt.title(labels)
plt.show()
plt.hist(labels,bins=10)
plt.xticks(np.arange(10))
plt.show()<jupyter_output><empty_output><jupyter_text>targeted PDGhttps://adversarial-ml-tutorial.org/adversarial_examples/<jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15987368005526498, 'fraction_numerical': 0.02639889470048357, 'mean_word_length': 2.3383297644539613, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 19, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '124997', 'license': 'Apache-2.0', 'n_tokens_mistral': 7580, 'n_tokens_neox': 7110, 'n_words': 1269, 'path': 'backdoor_CIFAR.ipynb', 'repo_name': 'aliborji/Backdoor_defense', 'size': '20266'}