def applyManipulationToGetImage(self, spans, numSpans): activations1 = applyManipulation(self.activations, spans, numSpans) if self.layer > -1: return np.squeeze( self.autoencoder.predict(np.expand_dims(activations1, axis=0))) else: return activations1
def terminatedByControlledSearch(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) (distMethod, distVal) = cfg.controlledSearch if distMethod == "euclidean": dist = basics.euclideanDistance(image1, self.image) elif distMethod == "L1": dist = basics.l1Distance(image1, self.image) elif distMethod == "Percentage": dist = basics.diffPercent(image1, self.image) elif distMethod == "NumDiffs": dist = basics.diffPercent(image1, self.image) print "terminated by controlled search" return dist > distVal
def terminatedByControlledSearch(self, index): activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) (distMethod, distVal) = cfg.controlledSearch if distMethod == "euclidean": dist = basics.euclideanDistance(activations1, self.activations) elif distMethod == "L1": dist = basics.l1Distance(activations1, self.activations) elif distMethod == "Percentage": dist = basics.diffPercent(activations1, self.activations) elif distMethod == "NumDiffs": dist = basics.diffPercent(activations1, self.activations) basics.nprint("terminated by controlled search") return dist > distVal
def sampleNext(self, spansPath, numSpansPath, depth, availableActionIDs, usedActionIDs): #print spansPath.keys() image1 = applyManipulation(self.image, spansPath, numSpansPath) (newClass, newConfident) = self.model.predict(image1) #print euclideanDistance(self.image,image1), newConfident, newClass (distMethod, distVal) = cfg.controlledSearch if distMethod == "euclidean": dist = basics.euclideanDistance(image1, self.image) termValue = 0.0 termByDist = dist > distVal elif distMethod == "L1": dist = basics.l1Distance(image1, self.image) termValue = 0.0 termByDist = dist > distVal elif distMethod == "Percentage": dist = basics.diffPercent(image1, self.image) termValue = 0.0 termByDist = dist > distVal elif distMethod == "NumDiffs": dist = basics.diffPercent(image1, self.image) * self.image.size termValue = 0.0 termByDist = dist > distVal if newClass != self.originalClass: print("sampling a path ends in a terminal node with depth %s... " % depth) if self.bestCase[0] < dist: self.bestCase = (dist, spansPath, numSpansPath) return (depth == 0, dist) elif termByDist == True: print( "sampling a path ends by controlled search with depth %s ... " % depth) return (depth == 0, termValue) else: randomActionIndex = random.choice( list(set(availableActionIDs) - set(usedActionIDs)) ) #random.randint(0, len(allChildren)-1) (span, numSpan, _) = self.actions[randomActionIndex] availableActionIDs.remove(randomActionIndex) usedActionIDs.append(randomActionIndex) #print span.keys() newSpanPath = self.mergeSpan(spansPath, span) newNumSpanPath = self.mergeNumSpan(numSpansPath, numSpan) return self.sampleNext(newSpanPath, newNumSpanPath, depth + 1, availableActionIDs, usedActionIDs)
def initialiseLeafNode(self, index, parentIndex, newSpans, newNumSpans): basics.nprint("initialising a leaf node %s from the node %s" % (index, parentIndex)) self.spans[index] = basics.mergeTwoDicts(self.spans[parentIndex], newSpans) self.numSpans[index] = basics.mergeTwoDicts(self.numSpans[parentIndex], newNumSpans) self.cost[index] = 0 self.parent[index] = parentIndex self.children[index] = [] self.fullyExpanded[index] = False self.numberOfVisited[index] = 0 activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) self.re_training.addDatum(activations1, self.originalClass, self.originalClass)
def scrutinizePath(self, spanPath, numSpanPath, changedClass): lastSpanPath = copy.deepcopy(spanPath) for i in self.actions.keys(): if i != 0: for key, (span, numSpan, _) in self.actions[i].iteritems(): if set(span.keys()).issubset(set(spanPath.keys())): tempSpanPath = copy.deepcopy(spanPath) tempNumSpanPath = copy.deepcopy(numSpanPath) for k in span.keys(): tempSpanPath.pop(k) tempNumSpanPath.pop(k) activations1 = applyManipulation( self.activations, tempSpanPath, tempNumSpanPath) (newClass, newConfident ) = self.predictWithActivations(activations1) #if changedClass == newClass: if newClass != self.originalClass and newConfident > effectiveConfidenceWhenChanging: for k in span.keys(): spanPath.pop(k) numSpanPath.pop(k) if len(lastSpanPath.keys()) != len(spanPath.keys()): return self.scrutinizePath(spanPath, numSpanPath, changedClass) else: return (spanPath, numSpanPath)
def diffPercent(self, index): activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) return basics.diffPercent(self.activations, activations1)
def l0Dist(self, index): activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) return basics.l0Distance(self.activations, activations1)
def terminalNode(self, index): activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) (newClass, _) = self.predictWithActivations(activations1) return newClass != self.originalClass
def sampleNext(self, k): #print("k=%s"%k) #for j in self.keypoints: # print(len(self.availableActionIDs[j])) #print("oooooooo") activations1 = applyManipulation(self.activations, self.spansPath, self.numSpansPath) (newClass, newConfident) = self.predictWithActivations(activations1) (distMethod, distVal) = cfg.controlledSearch if distMethod == "euclidean": dist = basics.euclideanDistance(activations1, self.activations) termValue = 0.0 termByDist = dist > distVal elif distMethod == "L1": dist = basics.l1Distance(activations1, self.activations) termValue = 0.0 termByDist = dist > distVal elif distMethod == "Percentage": dist = basics.diffPercent(activations1, self.activations) termValue = 0.0 termByDist = dist > distVal elif distMethod == "NumDiffs": dist = basics.diffPercent(activations1, self.activations) * self.activations.size termValue = 0.0 termByDist = dist > distVal #if termByDist == False and newConfident < 0.5 and self.depth <= 3: # termByDist = True #self.re_training.addDatum(activations1,self.originalClass,newClass) if newClass != self.originalClass and newConfident > effectiveConfidenceWhenChanging: # and newClass == dataBasics.next_index(self.originalClass,self.originalClass): basics.nprint( "sampling a path ends in a terminal node with self.depth %s... " % self.depth) #print("L1 distance: %s"%(l1Distance(self.activations,activations1))) #print(self.activations.shape) #print(activations1.shape) #print("L1 distance with KL: %s"%(withKL(l1Distance(self.activations,activations1),self.activations,activations1))) (self.spansPath, self.numSpansPath) = self.scrutinizePath(self.spansPath, self.numSpansPath, newClass) #self.decisionTree.addOnePath(dist,self.spansPath,self.numSpansPath) self.numAdv += 1 #self.analyseAdv.addAdv(activations1) self.getUsefulPixels(self.accDims, self.d) self.re_training.addDatum(activations1, self.originalClass, newClass) if self.bestCase[0] < dist: self.numConverge += 1 self.bestCase = (dist, self.spansPath, self.numSpansPath) path0 = "%s/%s_currentBest_%s_as_%s_with_confidence_%s.png" % ( cfg.directory_pic_string, cfg.startIndexOfImage, self.numConverge, self.dataset.labels( int(newClass)), newConfident) self.dataset.save(-1, activations1, path0) return (self.depth == 0, dist) elif termByDist == True: basics.nprint( "sampling a path ends by controlled search with self.depth %s ... " % self.depth) self.re_training.addDatum(activations1, self.originalClass, newClass) return (self.depth == 0, termValue) elif list( set(self.availableActionIDs[k]) - set(self.usedActionIDs[k])) == []: basics.nprint( "sampling a path ends with self.depth %s because no more actions can be taken ... " % self.depth) return (self.depth == 0, termValue) else: #print("continue sampling node ... ") #allChildren = initialisePixelSets(self.model,self.activations,self.spansPath.keys()) randomActionIndex = random.choice( list( set(self.availableActionIDs[k]) - set(self.usedActionIDs[k])) ) #random.randint(0, len(allChildren)-1) if k == 0: span = {} numSpan = {} else: (span, numSpan, _) = self.actions[k][randomActionIndex] self.availableActionIDs[k].remove(randomActionIndex) self.usedActionIDs[k].append(randomActionIndex) newSpanPath = self.mergeSpan(self.spansPath, span) newNumSpanPath = self.mergeNumSpan(self.numSpansPath, numSpan) activations2 = applyManipulation(self.activations, newSpanPath, newNumSpanPath) (newClass2, newConfident2) = self.predictWithActivations(activations2) confGap2 = newConfident - newConfident2 if newClass2 == newClass: self.accDims.append((randomActionIndex, confGap2)) else: self.accDims.append((randomActionIndex, 1.0)) self.spansPath = newSpanPath self.numSpansPath = newNumSpanPath self.depth = self.depth + 1 self.accDims = self.accDims self.d = self.d if k == 0: return self.sampleNext(randomActionIndex) else: return self.sampleNext(0)
def handleOne(model, dataset, dc, imgIdx): print(imgIdx) # get an image to interpolate image = dataset.getTestImage(imgIdx) print("the shape of the input is " + str(image.shape)) if cfg.dataset == "twoDcurve": image = np.array([3.58747339, 1.11101673]) dc.initialiseIndex(imgIdx) originalImage = copy.deepcopy(image) if cfg.checkingMode == "stepwise": k = cfg.startLayer elif cfg.checkingMode == "specificLayer": k = cfg.maxLayer while k <= cfg.maxLayer: layerType = model.getLayerType(k) re = False start_time = time.time() # only these layers need to be checked if layerType in ["Convolution2D", "Conv2D", "Dense", "InputLayer" ] and k >= 0: dc.initialiseLayer(k) st = SearchTree(image, k) st.addImages(model, [image]) print( "\n================================================================" ) print "\nstart checking the safety of layer " + str(k) (originalClass, originalConfident) = model.predict(image) origClassStr = dataset.labels(int(originalClass)) path0 = "%s/%s_original_as_%s_with_confidence_%s.png" % ( cfg.directory_pic_string, imgIdx, origClassStr, originalConfident) dataset.save(-1, originalImage, path0) # for every layer f = 0 while f < cfg.numOfFeatures: f += 1 print( "\n================================================================" ) print("Round %s of layer %s for image %s" % (f, k, imgIdx)) index = st.getOneUnexplored() imageIndex = copy.deepcopy(index) # for every image # start from the first hidden layer t = 0 re = False while True and index != (-1, -1): # pick the first element of the queue print "(1) get a manipulated input ..." (image0, span, numSpan, numDimsToMani, _) = st.getInfo(index) print "current layer: %s." % (t) print "current index: %s." % (str(index)) path2 = cfg.directory_pic_string + "/temp.png" print "current operated image is saved into %s" % (path2) dataset.save(index[0], image0, path2) print "(2) synthesise region from %s..." % (span.keys()) # ne: next region, i.e., e_{k+1} #print "manipulated: %s"%(st.manipulated[t]) (nextSpan, nextNumSpan, numDimsToMani) = regionSynth(model, cfg.dataset, image0, st.manipulated[t], t, span, numSpan, numDimsToMani) st.addManipulated(t, nextSpan.keys()) (nextSpan, nextNumSpan, npre) = precisionSynth(model, image0, t, span, numSpan, nextSpan, nextNumSpan) print "dimensions to be considered: %s" % (nextSpan) print "spans for the dimensions: %s" % (nextNumSpan) if t == k: # only after reaching the k layer, it is counted as a pass print "(3) safety analysis ..." # wk for the set of counterexamples # rk for the set of images that need to be considered in the next precision # rs remembers how many input images have been processed in the last round # nextSpan and nextNumSpan are revised by considering the precision npre (nextSpan, nextNumSpan, rs, wk, rk) = safety_analysis(model, dataset, t, imgIdx, st, index, nextSpan, nextNumSpan, npre) if len(rk) > 0: rk = (zip(*rk))[0] print "(4) add new images ..." random.seed(time.time()) if len(rk) > numOfPointsAfterEachFeature: rk = random.sample( rk, numOfPointsAfterEachFeature) diffs = basics.diffImage(image0, rk[0]) print( "the dimensions of the images that are changed in the this round: %s" % diffs) if len(diffs) == 0: st.clearManipulated(k) return st.addImages(model, rk) st.removeProcessed(imageIndex) (re, percent, eudist, l1dist, l0dist) = reportInfo(image, wk) print "euclidean distance %s" % ( basics.euclideanDistance(image, rk[0])) print "L1 distance %s" % (basics.l1Distance( image, rk[0])) print "L0 distance %s" % (basics.l0Distance( image, rk[0])) print "manipulated percentage distance %s\n" % ( basics.diffPercent(image, rk[0])) break else: st.removeProcessed(imageIndex) break else: print "(3) add new intermediate node ..." index = st.addIntermediateNode(image0, nextSpan, nextNumSpan, npre, numDimsToMani, index) re = False t += 1 if re == True: dc.addManipulationPercentage(percent) print "euclidean distance %s" % (eudist) print "L1 distance %s" % (l1dist) print "L0 distance %s" % (l0dist) print "manipulated percentage distance %s\n" % (percent) dc.addEuclideanDistance(eudist) dc.addl1Distance(l1dist) dc.addl0Distance(l0dist) (ocl, ocf) = model.predict(wk[0]) dc.addConfidence(ocf) break if f == cfg.numOfFeatures: print "(6) no adversarial example is found in this layer within the distance restriction." st.destructor() elif layerType in ["Input" ] and k < 0 and mcts_mode == "sift_twoPlayer": print "directly handling the image ... " dc.initialiseLayer(k) (originalClass, originalConfident) = model.predict(image) origClassStr = dataset.labels(int(originalClass)) path0 = "%s/%s_original_as_%s_with_confidence_%s.png" % ( cfg.directory_pic_string, imgIdx, origClassStr, originalConfident) dataset.save(-1, originalImage, path0) # initialise a search tree st = MCTSTwoPlayer(model, model, image, image, -1, "cooperator", dataset) st.initialiseActions() st.setManipulationType("sift_twoPlayer") start_time_all = time.time() runningTime_all = 0 numberOfMoves = 0 while st.terminalNode( st.rootIndex ) == False and st.terminatedByControlledSearch( st.rootIndex ) == False and runningTime_all <= cfg.MCTS_all_maximal_time: print("the number of moves we have made up to now: %s" % (numberOfMoves)) eudist = st.euclideanDist(st.rootIndex) l1dist = st.l1Dist(st.rootIndex) l0dist = st.l0Dist(st.rootIndex) percent = st.diffPercent(st.rootIndex) diffs = st.diffImage(st.rootIndex) print("euclidean distance %s" % (eudist)) print("L1 distance %s" % (l1dist)) print("L0 distance %s" % (l0dist)) print("manipulated percentage distance %s" % (percent)) print("manipulated dimensions %s" % (diffs)) start_time_level = time.time() runningTime_level = 0 childTerminated = False while runningTime_level <= cfg.MCTS_level_maximal_time: (leafNode, availableActions) = st.treeTraversal(st.rootIndex) newNodes = st.initialiseExplorationNode( leafNode, availableActions) for node in newNodes: (childTerminated, value) = st.sampling(node, availableActions) #if childTerminated == True: break st.backPropagation(node, value) #if childTerminated == True: break runningTime_level = time.time() - start_time_level basics.nprint("best possible one is %s" % (str(st.bestCase))) bestChild = st.bestChild(st.rootIndex) #st.collectUselessPixels(st.rootIndex) st.makeOneMove(bestChild) image1 = st.applyManipulationToGetImage( st.spans[st.rootIndex], st.numSpans[st.rootIndex]) diffs = st.diffImage(st.rootIndex) path0 = "%s/%s_temp_%s.png" % (cfg.directory_pic_string, imgIdx, len(diffs)) dataset.save(-1, image1, path0) (newClass, newConfident) = model.predict(image1) print("confidence: %s" % (newConfident)) if childTerminated == True: break # store the current best (_, bestSpans, bestNumSpans) = st.bestCase image1 = st.applyManipulationToGetImage( bestSpans, bestNumSpans) path0 = "%s/%s_currentBest.png" % (cfg.directory_pic_string, imgIdx) dataset.save(-1, image1, path0) numberOfMoves += 1 runningTime_all = time.time() - start_time_all (_, bestSpans, bestNumSpans) = st.bestCase #image1 = applyManipulation(st.image,st.spans[st.rootIndex],st.numSpans[st.rootIndex]) image1 = st.applyManipulationToGetImage(bestSpans, bestNumSpans) (newClass, newConfident) = model.predict(image1) newClassStr = dataset.labels(int(newClass)) re = newClass != originalClass if re == True: path0 = "%s/%s_%s_%s_modified_into_%s_with_confidence_%s.png" % ( cfg.directory_pic_string, imgIdx, "sift_twoPlayer", origClassStr, newClassStr, newConfident) dataset.save(-1, image1, path0) path0 = "%s/%s_diff.png" % (cfg.directory_pic_string, imgIdx) dataset.save(-1, np.subtract(image, image1), path0) print( "\nfound an adversary image within prespecified bounded computational resource. The following is its information: " ) print("difference between images: %s" % (basics.diffImage(image, image1))) print("number of adversarial examples found: %s" % (st.numAdv)) eudist = basics.euclideanDistance(st.image, image1) l1dist = basics.l1Distance(st.image, image1) l0dist = basics.l0Distance(st.image, image1) percent = basics.diffPercent(st.image, image1) print("euclidean distance %s" % (eudist)) print("L1 distance %s" % (l1dist)) print("L0 distance %s" % (l0dist)) print("manipulated percentage distance %s" % (percent)) print("class is changed into %s with confidence %s\n" % (newClassStr, newConfident)) dc.addRunningTime(time.time() - start_time_all) dc.addConfidence(newConfident) dc.addManipulationPercentage(percent) dc.addEuclideanDistance(eudist) dc.addl1Distance(l1dist) dc.addl0Distance(l0dist) #path0="%s/%s_original_as_%s_heatmap.png"%(directory_pic_string,imgIdx,origClassStr) #plt.imshow(GMM(image),interpolation='none') #plt.savefig(path0) #path1="%s/%s_%s_%s_modified_into_%s_heatmap.png"%(directory_pic_string,imgIdx,"sift_twoPlayer", origClassStr,newClassStr) #plt.imshow(GMM(image1),interpolation='none') #plt.savefig(path1) else: print( "\nfailed to find an adversary image within prespecified bounded computational resource. " ) elif layerType in ["Input"] and k < 0 and mcts_mode == "singlePlayer": print "directly handling the image ... " dc.initialiseLayer(k) (originalClass, originalConfident) = model.predict(image) origClassStr = dataset.labels(int(originalClass)) path0 = "%s/%s_original_as_%s_with_confidence_%s.png" % ( cfg.directory_pic_string, imgIdx, origClassStr, originalConfident) dataset.save(-1, originalImage, path0) # initialise a search tree st = SearchMCTS(model, image, k) st.initialiseActions() start_time_all = time.time() runningTime_all = 0 numberOfMoves = 0 while st.terminalNode( st.rootIndex ) == False and st.terminatedByControlledSearch( st.rootIndex ) == False and runningTime_all <= cfg.MCTS_all_maximal_time: print("the number of moves we have made up to now: %s" % (numberOfMoves)) eudist = st.euclideanDist(st.rootIndex) l1dist = st.l1Dist(st.rootIndex) l0dist = st.l0Dist(st.rootIndex) percent = st.diffPercent(st.rootIndex) diffs = st.diffImage(st.rootIndex) print "euclidean distance %s" % (eudist) print "L1 distance %s" % (l1dist) print "L0 distance %s" % (l0dist) print "manipulated percentage distance %s" % (percent) print "manipulated dimensions %s" % (diffs) start_time_level = time.time() runningTime_level = 0 childTerminated = False while runningTime_level <= cfg.MCTS_level_maximal_time: (leafNode, availableActions) = st.treeTraversal(st.rootIndex) newNodes = st.initialiseExplorationNode( leafNode, availableActions) for node in newNodes: (childTerminated, value) = st.sampling(node, availableActions) if childTerminated == True: break st.backPropagation(node, value) if childTerminated == True: break runningTime_level = time.time() - start_time_level print("best possible one is %s" % (st.showBestCase())) bestChild = st.bestChild(st.rootIndex) #st.collectUselessPixels(st.rootIndex) st.makeOneMove(bestChild) image1 = applyManipulation(st.image, st.spans[st.rootIndex], st.numSpans[st.rootIndex]) diffs = st.diffImage(st.rootIndex) path0 = "%s/%s_temp_%s.png" % (cfg.directory_pic_string, imgIdx, len(diffs)) dataset.save(-1, image1, path0) (newClass, newConfident) = model.predict(image1) print "confidence: %s" % (newConfident) if childTerminated == True: break # store the current best (_, bestSpans, bestNumSpans) = st.bestCase image1 = applyManipulation(st.image, bestSpans, bestNumSpans) path0 = "%s/%s_currentBest.png" % (cfg.directory_pic_string, imgIdx) dataset.save(-1, image1, path0) runningTime_all = time.time() - runningTime_all numberOfMoves += 1 (_, bestSpans, bestNumSpans) = st.bestCase #image1 = applyManipulation(st.image,st.spans[st.rootIndex],st.numSpans[st.rootIndex]) image1 = applyManipulation(st.image, bestSpans, bestNumSpans) (newClass, newConfident) = model.predict(image1) newClassStr = dataset.labels(int(newClass)) re = newClass != originalClass path0 = "%s/%s_%s_modified_into_%s_with_confidence_%s.png" % ( cfg.directory_pic_string, imgIdx, origClassStr, newClassStr, newConfident) dataset.save(-1, image1, path0) #print np.max(image1), np.min(image1) print("difference between images: %s" % (basics.diffImage(image, image1))) #plt.imshow(image1 * 255, cmap=mpl.cm.Greys) #plt.show() if re == True: eudist = basics.euclideanDistance(st.image, image1) l1dist = basics.l1Distance(st.image, image1) l0dist = basics.l0Distance(st.image, image1) percent = basics.diffPercent(st.image, image1) print "euclidean distance %s" % (eudist) print "L1 distance %s" % (l1dist) print "L0 distance %s" % (l0dist) print "manipulated percentage distance %s" % (percent) print "class is changed into %s with confidence %s\n" % ( newClassStr, newConfident) dc.addEuclideanDistance(eudist) dc.addl1Distance(l1dist) dc.addl0Distance(l0dist) dc.addManipulationPercentage(percent) st.destructor() else: print("layer %s is of type %s, skipping" % (k, layerType)) #return runningTime = time.time() - start_time dc.addRunningTime(runningTime) if re == True and cfg.exitWhen == "foundFirst": break k += 1 print("Please refer to the file %s for statistics." % (dc.fileName)) return re
def diffPercent(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) return basics.diffPercent(self.image, image1)
def l0Dist(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) return basics.l0Distance(self.image, image1)
def terminalNode(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) (newClass, _) = self.model.predict(image1) return newClass != self.originalClass