示例#1
0
 def filterSamplesIntoDataLoader(self, modelIndex, sampleAssignments, xTest,
                                 yTest, batchSize):
     numSamples = xTest.shape[0]
     count = 0
     #First determine how many samples the model needs to evaluate
     for i in range(0, numSamples):
         if sampleAssignments[i] == modelIndex:
             count = count + 1
     #We now know how many samples we need to evalute on, time to save them
     xSubset = torch.zeros(
         (count, xTest.shape[1], xTest.shape[2], xTest.shape[3]))
     ySubset = torch.zeros((count))
     #Go through and get the samples
     currentIndex = 0
     for i in range(0, numSamples):
         if sampleAssignments[i] == modelIndex:
             xSubset[currentIndex] = xTest[i]
             ySubset[currentIndex] = yTest[i]
             currentIndex = currentIndex + 1
     #Do some basic error checkings
     if currentIndex != count:
         raise ValueError(
             "Something went wrong in the indexing, expected count did not match actual count."
         )
     #Put the data into a dataloader and return
     dataLoaderSubset = DMP.TensorToDataLoader(xSubset,
                                               ySubset,
                                               transforms=None,
                                               batchSize=batchSize,
                                               randomizer=None)
     return dataLoaderSubset
示例#2
0
def MIMNativePytorch(device, dataLoader, model, decayFactor, epsilonMax,
                     epsilonStep, numSteps, clipMin, clipMax, targeted):
    model.eval()  #Change model to evaluation mode for the attack
    #Generate variables for storing the adversarial examples
    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)
    xAdv = torch.zeros(numSamples, xShape[0], xShape[1], xShape[2])
    yClean = torch.zeros(numSamples)
    advSampleIndex = 0
    batchSize = 0  #just do dummy initalization, will be filled in later
    loss = torch.nn.CrossEntropyLoss()
    tracker = 0
    #Go through each sample
    for xData, yData in dataLoader:
        batchSize = xData.shape[
            0]  #Get the batch size so we know indexing for saving later
        tracker = tracker + batchSize
        print("Processing up to sample=", tracker)
        #Put the data from the batch onto the device
        xAdvCurrent = xData.to(device)
        yCurrent = yData.type(torch.LongTensor).to(device)
        # Set requires_grad attribute of tensor. Important for attack. (Pytorch comment, not mine)
        #Initalize memory for the gradient momentum
        gMomentum = torch.zeros(batchSize, xShape[0], xShape[1], xShape[2])
        #Do the attack for a number of steps
        for attackStep in range(0, numSteps):
            xAdvCurrent.requires_grad = True
            outputs = model(xAdvCurrent)
            model.zero_grad()
            cost = loss(outputs, yCurrent).to(device)
            cost.backward()
            #Update momentum term
            gMomentum = decayFactor * gMomentum + GradientNormalizedByL1(
                xAdvCurrent.grad)
            #Update the adversarial sample
            if targeted == True:
                advTemp = xAdvCurrent - (epsilonStep *
                                         torch.sign(gMomentum)).to(device)
            else:
                advTemp = xAdvCurrent + (epsilonStep *
                                         torch.sign(gMomentum)).to(device)
            #Adding clipping to maintain the range
            xAdvCurrent = torch.clamp(advTemp, min=clipMin,
                                      max=clipMax).detach_()
        #Save the adversarial images from the batch
        for j in range(0, batchSize):
            xAdv[advSampleIndex] = xAdvCurrent[j]
            yClean[advSampleIndex] = yData[j]
            advSampleIndex = advSampleIndex + 1  #increment the sample index
    #All samples processed, now time to save in a dataloader and return
    advLoader = DMP.TensorToDataLoader(
        xAdv,
        yClean,
        transforms=None,
        batchSize=dataLoader.batch_size,
        randomizer=None)  #use the same batch size as the original loader
    return advLoader
示例#3
0
 def GetLoaderAtIndex(self, index):
     currentDataLoaderDir = self.homeDir + self.dataLoaderDirList[index]
     #First load the numpy arrays
     xData = numpy.load(currentDataLoaderDir + "XData.npy")
     yData = numpy.load(currentDataLoaderDir + "YData.npy")
     #Create a dataloader
     currentDataLoader = DMP.TensorToDataLoader(torch.from_numpy(xData),
                                                torch.from_numpy(yData),
                                                transforms=None,
                                                batchSize=self.batchSize,
                                                randomizer=None)
     #currentDataLoader = torch.load(currentDataLoaderDir)
     #Do some memory clean up
     del xData
     del yData
     return currentDataLoader
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
示例#5
0
 def formatDataLoader(self, dataLoader):
     sampleShape = DMP.GetOutputShape(dataLoader)
     #Check if we need to do resizing, if not just return the original loader
     if sampleShape[1] == self.imgSizeH and sampleShape[2] == self.imgSizeW:
         return dataLoader
     else:  #We need to do resizing
         print("Resize required. Processing now.")
         p = torchvision.transforms.ToPILImage()
         t = torchvision.transforms.ToTensor()
         numSamples = len(dataLoader.dataset)
         sampleShape = DMP.GetOutputShape(
             dataLoader)  #Get the output shape from the dataloader
         sampleIndex = 0
         batchTracker = 0
         xData = torch.zeros(numSamples, sampleShape[0], self.imgSizeH,
                             self.imgSizeW)
         yData = torch.zeros(numSamples)
         #Go through and process the data in batches...kind of
         for i, (input, target) in enumerate(dataLoader):
             batchSize = input.shape[
                 0]  #Get the number of samples used in each batch
             #print("Resize processing up to=", batchTracker)
             batchTracker = batchTracker + batchSize
             #Save the samples from the batch in a separate tensor
             for batchIndex in range(0, batchSize):
                 #Convert to pil image, resize, convert back to tensor
                 xData[sampleIndex] = t(
                     self.resizeTransform(p(input[batchIndex])))
                 yData[sampleIndex] = target[batchIndex]
                 sampleIndex = sampleIndex + 1  #increment the sample index
         #All the data has been resized, time to put in the dataloader
         newDataLoader = DMP.TensorToDataLoader(xData,
                                                yData,
                                                transforms=None,
                                                batchSize=self.batchSize,
                                                randomizer=None)
         #Note we don't use the original batch size because the image may have become larger
         #i.e. to large to fit in GPU memory so we use the batch specified in the ModelPlus constructor
         return newDataLoader
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
示例#7
0
def FGSMNativePytorch(device, dataLoader, model, epsilonMax, clipMin, clipMax,
                      targeted):
    model.eval()  #Change model to evaluation mode for the attack
    #Generate variables for storing the adversarial examples
    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)
    xAdv = torch.zeros(numSamples, xShape[0], xShape[1], xShape[2])
    yClean = torch.zeros(numSamples)
    advSampleIndex = 0
    batchSize = 0  #just do dummy initalization, will be filled in later
    #Go through each sample
    tracker = 0
    for xData, yData in dataLoader:
        batchSize = xData.shape[
            0]  #Get the batch size so we know indexing for saving later
        tracker = tracker + batchSize
        #print("Processing up to sample=", tracker)
        #Put the data from the batch onto the device
        xDataTemp = torch.from_numpy(xData.cpu().detach().numpy()).to(device)
        yData = yData.type(torch.LongTensor).to(device)
        # Set requires_grad attribute of tensor. Important for attack. (Pytorch comment, not mine)
        xDataTemp.requires_grad = True
        # Forward pass the data through the model
        output = model(xDataTemp)
        # Calculate the loss
        loss = torch.nn.CrossEntropyLoss(ignore_index=10,
                                         size_average=True,
                                         reduce=True)
        # Zero all existing gradients
        model.zero_grad()
        # Calculate gradients of model in backward pass
        cost = loss(output, yData).to(device)
        cost.backward()
        # Collect datagrad
        #xDataGrad = xDataTemp.grad.data
        ###Here we actual compute the adversarial sample
        # Collect the element-wise sign of the data gradient
        signDataGrad = xDataTemp.grad.data.sign()
        # Create the perturbed image by adjusting each pixel of the input image
        #print("xData:", xData.is_cuda)
        #print("SignGrad:", signDataGrad.is_cuda)
        if targeted == True:
            perturbedImage = xData - epsilonMax * signDataGrad.cpu().detach(
            )  #Go negative of gradient
        else:
            perturbedImage = xData + epsilonMax * signDataGrad.cpu().detach()
        # Adding clipping to maintain the range
        perturbedImage = torch.clamp(perturbedImage, clipMin, clipMax)
        #Save the adversarial images from the batch
        for j in range(0, batchSize):
            xAdv[advSampleIndex] = perturbedImage[j]
            yClean[advSampleIndex] = yData[j]
            advSampleIndex = advSampleIndex + 1  #increment the sample index
        #Not sure if we need this but do some memory clean up
        del xDataTemp
        del signDataGrad
        torch.cuda.empty_cache()
    #All samples processed, now time to save in a dataloader and return
    advLoader = DMP.TensorToDataLoader(
        xAdv,
        yClean,
        transforms=None,
        batchSize=dataLoader.batch_size,
        randomizer=None)  #use the same batch size as the original loader
    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