Esempio n. 1
0
 def predictD(self, dataLoader, numClasses):
     #Basic variable setup
     numSamples = len(dataLoader.dataset)
     xTest, yTest = DMP.DataLoaderToTensor(dataLoader)
     #Randomly select which samples are predicted by which model
     sampleAssignments = numpy.random.randint(0, self.numModels,
                                              (numSamples, ))
     #memory for the solution
     yPred = torch.zeros(numSamples, numClasses)
     #Go through the models, get the sample subset they need to predict on, then do the prediction
     for modelIndex in range(0, self.numModels):
         currentModelPlus = self.modelPlusList[modelIndex]
         #Filter the data to get the samples only the currrent model should predict on
         dataLoaderSubset = self.filterSamplesIntoDataLoader(
             modelIndex, sampleAssignments, xTest, yTest,
             currentModelPlus.batchSize)
         #Get the array of correct predictions
         yPredCurrent = currentModelPlus.predictD(dataLoaderSubset,
                                                  numClasses)
         currentIndex = 0
         #Go through every sample
         for i in range(0, numSamples):
             #Check if the current sample was predicted using the current model
             if sampleAssignments[i] == modelIndex:
                 yPred[i] = yPredCurrent[currentIndex]
                 currentIndex = currentIndex + 1
     return yPred
def SelfAttentionGradientAttack(device, epsMax, numSteps, modelListPlus,
                                coefficientArray, dataLoader, clipMin,
                                clipMax):
    #Basic graident variable setup
    xClean, yClean = DMP.DataLoaderToTensor(dataLoader)
    xAdv = xClean  #Set the initial adversarial samples
    numSamples = len(
        dataLoader.dataset)  #Get the total number of samples to attack
    xShape = DMP.GetOutputShape(
        dataLoader
    )  #Get the shape of the input (there may be easier way to do this)
    #Compute eps step
    epsStep = epsMax / numSteps
    dataLoaderCurrent = dataLoader
    for i in range(0, numSteps):
        print("Running Step=", i)
        xGradientCumulative = torch.zeros(numSamples, xShape[0], xShape[1],
                                          xShape[2])
        for m in range(0, len(modelListPlus)):
            currentModelPlus = modelListPlus[m]
            #First get the gradient from the model
            xGradientCurrent = FGSMNativeGradient(device, dataLoaderCurrent,
                                                  currentModelPlus)
            #Resize the graident to be the correct size
            xGradientCurrent = torch.nn.functional.interpolate(
                xGradientCurrent, size=(xShape[1], xShape[2]))
            #Add the current computed gradient to the result
            if currentModelPlus.modelName.find("ViT") >= 0:
                attmap = GetAttention(dataLoaderCurrent, currentModelPlus)
                xGradientCumulative = xGradientCumulative + coefficientArray[
                    m] * xGradientCurrent * attmap
            else:
                xGradientCumulative = xGradientCumulative + coefficientArray[
                    m] * xGradientCurrent
        #Compute the sign of the graident and create the adversarial example
        xAdv = xAdv + epsStep * xGradientCumulative.sign()
        #Do the clipping
        xAdv = torch.clamp(xAdv, clipMin, clipMax)
        #Convert the result to dataloader
        dataLoaderCurrent = DMP.TensorToDataLoader(
            xAdv,
            yClean,
            transforms=None,
            batchSize=dataLoader.batch_size,
            randomizer=None)
    return dataLoaderCurrent
Esempio n. 3
0
def AdaptiveAttackShuffleDefense():
    #Corresponding tag for saving files
    #First part indicates the type of defense, second part indidcates the synthetic model and last part indicates the strenght of the attack (100%)
    saveTag = "ViT-L-16, ViT-32(ImageNet21K), p100"
    device = torch.device("cuda")
    #Attack parameters
    numAttackSamples = 1000
    epsForAttacks = 0.031
    clipMin = 0.0
    clipMax = 1.0
    #Parameters of training the synthetic model
    imgSize = 224
    batchSize = 32
    numClasses = 10
    numIterations = 4
    epochsPerIteration = 10
    epsForAug = 0.1  #when generating synthetic data, this value is eps for FGSM used to generate synthetic data
    learningRate = (3e-2) / 2  #Learning rate of the synthetic model
    #Load the training dataset, validation dataset and the defense
    valLoader, defense = LoadShuffleDefenseAndCIFAR10()
    trainLoader = DMP.GetCIFAR10Training(imgSize, batchSize)
    #Get the clean data
    xTest, yTest = DMP.DataLoaderToTensor(valLoader)
    cleanLoader = DMP.GetCorrectlyIdentifiedSamplesBalancedDefense(
        defense, numAttackSamples, valLoader, numClasses)
    #Create the synthetic model
    syntheticDir = "Models//imagenet21k_ViT-B_32.npz"
    config = CONFIGS["ViT-B_32"]
    syntheticModel = VisionTransformer(config,
                                       imgSize,
                                       zero_head=True,
                                       num_classes=numClasses)
    syntheticModel.load_from(numpy.load(syntheticDir))
    syntheticModel.to(device)
    #Do the attack
    oracle = defense
    dataLoaderForTraining = trainLoader
    optimizerName = "sgd"
    #Last line does the attack
    AttackWrappersAdaptiveBlackBox.AdaptiveAttack(
        saveTag, device, oracle, syntheticModel, numIterations,
        epochsPerIteration, epsForAug, learningRate, optimizerName,
        dataLoaderForTraining, cleanLoader, numClasses, epsForAttacks, clipMin,
        clipMax)
Esempio n. 4
0
 def AddLoader(self, dataLoaderName, dataLoader):
     #Torch limits the amount of data we can save to disk so we must use numpy to save
     #torch.save(dataLoader, self.homeDir+dataLoaderName)
     #First convert the tensor to a dataloader
     xDataPytorch, yDataPytorch = DMP.DataLoaderToTensor(dataLoader)
     #Second conver the pytorch arrays to numpy arrays for saving
     xDataNumpy = xDataPytorch.cpu().detach().numpy()
     yDataNumpy = yDataPytorch.cpu().detach().numpy()
     #Save the data using numpy
     numpy.save(self.homeDir + dataLoaderName + "XData", xDataNumpy)
     numpy.save(self.homeDir + dataLoaderName + "YData", yDataNumpy)
     #Save the file location string so we can re-load later
     self.dataLoaderDirList.append(dataLoaderName)
     #Delete the dataloader and associated variables from memory
     del dataLoader
     del xDataPytorch
     del yDataPytorch
     del xDataNumpy
     del yDataNumpy
Esempio n. 5
0
 def validateD(self, dataLoader):
     #Basic variable setup
     numSamples = len(dataLoader.dataset)
     xTest, yTest = DMP.DataLoaderToTensor(dataLoader)
     #Randomly select which samples are predicted by which model
     sampleAssignments = numpy.random.randint(0, self.numModels,
                                              (numSamples, ))
     acc = 0
     #Go through the models, get the sample subset they need to predict on, then do the prediction
     for modelIndex in range(0, self.numModels):
         currentModelPlus = self.modelPlusList[modelIndex]
         #Filter the data to get the samples only the currrent model should predict on
         dataLoaderSubset = self.filterSamplesIntoDataLoader(
             modelIndex, sampleAssignments, xTest, yTest,
             currentModelPlus.batchSize)
         #Get the array of correct predictions
         currentAccArray = currentModelPlus.validateDA(dataLoaderSubset)
         acc = acc + currentAccArray.sum()
     #We have all the correcly predicted samples, now compute the final accuracy
     acc = acc / float(numSamples)
     return acc
def RaySAttack(model, epsMax, queryLimit, cleanLoader):
    xClean, yClean = DMP.DataLoaderToTensor(cleanLoader)
    rayS = RayS(model, epsilon=epsMax, order = np.inf)
    xAdv = torch.zeros((xClean.shape[0], xClean.shape[1], xClean.shape[2], xClean.shape[3]))
    #Go through and attack the samples 
    for i in range(0, xClean.shape[0]):
        print(i)
        start = time.time()
        #yCurrent = torch.zeros((1,))
        #yCurrent[0] = 
        xAdvCurrent, stop_queries, dist, isLessDist = rayS.attack_hard_label(xClean[i].cuda(), yClean[i].cuda(), target=None, query_limit=queryLimit, seed=None)
        xAdvCurrent = xAdvCurrent.cpu().detach()
        dist = torch.dist(xAdvCurrent, xClean[i], np.inf)
        if dist>epsMax:
            print("Attack failed, returning clean sample instead.")
            xAdv[i] = xClean[i]
        else:
            xAdv[i] = xAdvCurrent
        end = time.time()
        print("Time Elapsed:", end-start)
    #Put solution in dataloader and return 
    advLoader = DMP.TensorToDataLoader(xAdv, yClean, transforms = None, batchSize = cleanLoader.batch_size, randomizer = None)
    return advLoader
def GetFirstCorrectlyOverlappingSamplesBalanced(device, sampleNum, numClasses,
                                                dataLoader, modelPlusList):
    numModels = len(modelPlusList)
    totalSampleNum = len(dataLoader.dataset)
    #First check if modelA needs resize
    xTestOrig, yTestOrig = DMP.DataLoaderToTensor(dataLoader)
    #We need to resize first
    if modelPlusList[0].imgSizeH != xTestOrig.shape[2] or modelPlusList[
            0].imgSizeW != xTestOrig.shape[3]:
        xTestOrigResize = torch.zeros(xTestOrig.shape[0], 3,
                                      modelPlusList[0].imgSizeH,
                                      modelPlusList[0].imgSizeW)
        rs = torchvision.transforms.Resize(
            (modelPlusList[0].imgSizeH,
             modelPlusList[0].imgSizeW))  #resize the samples for model A
        #Go through every sample
        for i in range(0, xTestOrig.shape[0]):
            xTestOrigResize[i] = rs(
                xTestOrig[i])  #resize to match dimensions required by modelA
        #Make a new dataloader
        dataLoader = DMP.TensorToDataLoader(xTestOrigResize,
                                            yTestOrig,
                                            transforms=None,
                                            batchSize=dataLoader.batch_size,
                                            randomizer=None)
    #Get accuracy array for each model
    accArrayCumulative = torch.zeros(
        totalSampleNum
    )  #Create an array with one entry for ever sample in the dataset
    for i in range(0, numModels):
        accArray = modelPlusList[i].validateDA(dataLoader)
        accArrayCumulative = accArrayCumulative + accArray
    #Do some basic error checking
    if sampleNum % numClasses != 0:
        raise ValueError(
            "Number of samples not divisable by the number of classes")
    #Basic variable setup
    samplePerClassCount = torch.zeros(
        numClasses)  #keep track of samples per class
    maxRequireSamplesPerClass = int(
        sampleNum / numClasses)  #Max number of samples we need per class
    xTest, yTest = DMP.DataLoaderToTensor(
        dataLoader)  #Get all the data as tensors
    #Memory for the solution
    xClean = torch.zeros(sampleNum, 3, modelPlusList[0].imgSizeH,
                         modelPlusList[0].imgSizeW)
    yClean = torch.zeros(sampleNum)
    sampleIndexer = 0
    #Go through all the samples
    for i in range(0, totalSampleNum):
        currentClass = int(yTest[i])
        #Check to make sure all classifiers identify the sample correctly AND we don't have enough of this class yet
        if accArrayCumulative[i] == numModels and samplePerClassCount[
                currentClass] < maxRequireSamplesPerClass:
            #xClean[sampleIndexer] = rs(xTest[i]) #resize to match dimensions required by modelA
            xClean[sampleIndexer] = xTest[i]
            yClean[sampleIndexer] = yTest[i]
            sampleIndexer = sampleIndexer + 1  #update the indexer
            samplePerClassCount[currentClass] = samplePerClassCount[
                currentClass] + 1  #Update the number of samples for this class
    #Check the over all number of samples as well
    if sampleIndexer != sampleNum:
        print("Not enough clean samples found.")
    #Do some error checking on the classes
    for i in range(0, numClasses):
        if samplePerClassCount[i] != maxRequireSamplesPerClass:
            print(samplePerClassCount[i])
            raise ValueError("We didn't find enough of class: " + str(i))
    #Conver the solution into a dataloader
    cleanDataLoader = DMP.TensorToDataLoader(
        xClean,
        yClean,
        transforms=None,
        batchSize=modelPlusList[0].batchSize,
        randomizer=None)
    #Do one last check to make sure all samples identify the clean loader correctly
    for i in range(0, numModels):
        cleanAcc = modelPlusList[i].validateD(cleanDataLoader)
        if cleanAcc != 1.0:
            print("Clean Acc " + modelPlusList[i].modelName + ":", cleanAcc)
            raise ValueError("The clean accuracy is not 1.0")
    #All error checking done, return the clean balanced loader
    return cleanDataLoader