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 getNodes(self, activeNodes): node = activeNodes[0] for (act, nextNode) in self.tree[node]: (spansPath, numSpansPath, _) = self.actions[act] self.imagesOnTree[nextNode] = applyManipulation( self.imagesOnTree[node], spansPath, numSpansPath) activeNodes.append(nextNode) return activeNodes[1:]
def initialiseLeafNode(self,index,parentIndex,newSpans,newNumSpans): nprint("initialising a leaf node %s from the node %s"%(index,parentIndex)) self.spans[index] = mergeTwoDicts(self.spans[parentIndex],newSpans) self.numSpans[index] = 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 terminatedByControlledSearch(self,index): activations1 = applyManipulation(self.activations,self.spans[index],self.numSpans[index]) (distMethod,distVal) = controlledSearch if distMethod == "euclidean": dist = euclideanDistance(activations1,self.activations) elif distMethod == "L1": dist = l1Distance(activations1,self.activations) elif distMethod == "Percentage": dist = diffPercent(activations1,self.activations) elif distMethod == "NumDiffs": dist = diffPercent(activations1,self.activations) nprint("terminated by controlled search") return dist > distVal
def terminatedByControlledSearch(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) (distMethod, distVal) = controlledSearch if distMethod == "euclidean": dist = euclideanDistance(image1, self.image) elif distMethod == "L1": dist = l1Distance(image1, self.image) elif distMethod == "Percentage": dist = diffPercent(image1, self.image) elif distMethod == "NumDiffs": dist = diffPercent(image1, self.image) print "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) = NN.predictWithImage(self.model, image1) #print euclideanDistance(self.image,image1), newConfident, newClass (distMethod, distVal) = controlledSearch if distMethod == "euclidean": dist = 1 - euclideanDistance(image1, self.image) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "L1": dist = 1 - l1Distance(image1, self.image) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "Percentage": dist = 1 - diffPercent(image1, self.image) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "NumDiffs": dist = self.image.size - diffPercent(image1, self.image) * self.image.size termValue = 0.0 termByDist = dist < self.image.size - 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 scrutinizePath(self,spanPath,numSpanPath,changedClass): lastSpanPath = copy.deepcopy(spanPath) for key, (span,numSpan,_) in self.actions.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 terminalNode(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) (newClass, _) = NN.predictWithImage(self.model, image1) return newClass != self.originalClass
def diffPercent(self, index): activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) return diffPercent(self.activations, activations1)
def l0Dist(self, index): activations1 = applyManipulation(self.activations, self.spans[index], self.numSpans[index]) return 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 sampleNextSndRound(self, spansPath, numSpansPath, depth, availableActionIDs, usedActionIDs, accDims, d): activations1 = applyManipulation(self.activations, spansPath, numSpansPath) (newClass, newConfident) = self.predictWithActivations(activations1) (distMethod, distVal) = controlledSearch distVal = distVal / float(2) print("second depth-first search in %s" % (distVal)) if distMethod == "euclidean": dist = 1 - euclideanDistance(activations1, self.pocketActivations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "L1": dist = 1 - l1Distance(activations1, self.pocketActivations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "Percentage": dist = 1 - diffPercent(activations1, self.pocketActivations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "NumDiffs": dist = self.activations.size - diffPercent( activations1, self.pocketActivations) * self.pocketActivations.size termValue = 0.0 termByDist = dist < self.pocketActivations.size - distVal if newClass == self.originalClass: # and newClass == dataBasics.next_index(self.originalClass,self.originalClass): nprint( "sampling a path ends in a terminal node with depth %s... " % depth) self.pocketTree.addOnePath(dist, spansPath, numSpansPath) print("found a pocket!") return (depth == 0, dist) elif termByDist == True: nprint( "sampling a path ends by controlled search with depth %s ... " % depth) return (depth == 0, termValue) elif list(set(availableActionIDs) - set(usedActionIDs)) == []: nprint( "sampling a path ends with depth %s because no more actions can be taken ... " % depth) return (depth == 0, termValue) else: #print("continue sampling node ... ") #allChildren = initialisePixelSets(self.model,self.activations,spansPath.keys()) 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) newSpanPath = self.mergeSpan(spansPath, span) newNumSpanPath = self.mergeNumSpan(numSpansPath, numSpan) activations2 = applyManipulation(self.activations, newSpanPath, newNumSpanPath) (newClass2, newConfident2) = self.predictWithActivations(activations2) confGap2 = newConfident - newConfident2 if newClass2 == newClass: accDims.append((randomActionIndex, confGap2)) else: accDims.append((randomActionIndex, 1.0)) return self.sampleNextSndRound(newSpanPath, newNumSpanPath, depth + 1, availableActionIDs, usedActionIDs, accDims, d)
def sampleNext(self): activations1 = applyManipulation(self.activations,self.spansPath,self.numSpansPath) (newClass,newConfident) = self.predictWithActivations(activations1) (distMethod,distVal) = controlledSearch if distMethod == "euclidean": dist = 1 - euclideanDistance(activations1,self.activations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "L1": dist = 1 - l1Distance(activations1,self.activations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "Percentage": dist = 1 - diffPercent(activations1,self.activations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "NumDiffs": dist = self.activations.size - diffPercent(activations1,self.activations) * self.activations.size termValue = 0.0 termByDist = dist < self.activations.size - distVal #if termByDist == False and newConfident < 0.5 and self.depth <= 3: # termByDist = True if newClass != self.originalClass and newConfident > effectiveConfidenceWhenChanging: # and newClass == dataBasics.next_index(self.originalClass,self.originalClass): nprint("sampling a path ends in a terminal node with self.depth %s... "%self.depth) (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) if self.bestCase[0] < dist: self.bestCase = (dist,self.spansPath,self.numSpansPath) return (self.depth == 0, dist) elif termByDist == True: nprint("sampling a path ends by controlled search with self.depth %s ... "%self.depth) self.re_training.addDatum(activations1,self.originalClass) return (self.depth == 0, termValue) elif list(set(self.availableActionIDs)-set(self.usedActionIDs)) == []: 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)-set(self.usedActionIDs))) #random.randint(0, len(allChildren)-1) (span,numSpan,_) = self.actions[randomActionIndex] self.availableActionIDs.remove(randomActionIndex) self.usedActionIDs.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.availableActionIDs = self.availableActionIDs self.usedActionIDs = self.usedActionIDs self.accDims = self.accDims self.d = self.d return self.sampleNext()
def handleOne(model, dc, startIndexOfImage): # get an image to interpolate global np image = NN.getImage(model, startIndexOfImage) print("the shape of the input is " + str(image.shape)) if dataset == "twoDcurve": image = np.array([3.58747339, 1.11101673]) dc.initialiseIndex(startIndexOfImage) originalImage = copy.deepcopy(image) if checkingMode == "stepwise": k = startLayer elif checkingMode == "specificLayer": k = maxLayer while k <= maxLayer: layerType = getLayerType(model, k) 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) = NN.predictWithImage(model, image) origClassStr = dataBasics.LABELS(int(originalClass)) path0 = "%s/%s_original_as_%s_with_confidence_%s.png" % ( directory_pic_string, startIndexOfImage, origClassStr, originalConfident) dataBasics.save(-1, originalImage, path0) # for every layer f = 0 while f < numOfFeatures: f += 1 print( "\n================================================================" ) print("Round %s of layer %s for image %s" % (f, k, startIndexOfImage)) index = st.getOneUnexplored() imageIndex = copy.deepcopy(index) # for every image # start from the first hidden layer t = 0 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 = directory_pic_string + "/temp.png" print "current operated image is saved into %s" % (path2) dataBasics.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, 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, startIndexOfImage, 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 = 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) = reportInfo(image, wk) print "euclidean distance %s" % (euclideanDistance( image, rk[0])) print "L1 distance %s" % (l1Distance(image, rk[0])) print "manipulated percentage distance %s\n" % ( 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 "manipulated percentage distance %s\n" % (percent) dc.addEuclideanDistance(eudist) dc.addl1Distance(l1dist) (ocl, ocf) = NN.predictWithImage(model, wk[0]) dc.addConfidence(ocf) break if f == numOfFeatures: print "(6) no adversarial example is found in this layer within the distance restriction." st.destructor() elif layerType in ["Input"] and k < 0: print "directly handling the image ... " dc.initialiseLayer(k) (originalClass, originalConfident) = NN.predictWithImage(model, image) origClassStr = dataBasics.LABELS(int(originalClass)) path0 = "%s/%s_original_as_%s_with_confidence_%s.png" % ( directory_pic_string, startIndexOfImage, origClassStr, originalConfident) dataBasics.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 <= 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) percent = st.diffPercent(st.rootIndex) diffs = st.diffImage(st.rootIndex) print "euclidean distance %s" % (eudist) print "L1 distance %s" % (l1dist) print "manipulated percentage distance %s" % (percent) print "manipulated dimensions %s" % (diffs) start_time_level = time.time() runningTime_level = 0 childTerminated = False while runningTime_level <= 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" % (directory_pic_string, startIndexOfImage, len(diffs)) dataBasics.save(-1, image1, path0) (newClass, newConfident) = NN.predictWithImage(model, 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" % (directory_pic_string, startIndexOfImage) dataBasics.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) = NN.predictWithImage(model, image1) newClassStr = dataBasics.LABELS(int(newClass)) re = newClass != originalClass path0 = "%s/%s_%s_modified_into_%s_with_confidence_%s.png" % ( directory_pic_string, startIndexOfImage, origClassStr, newClassStr, newConfident) dataBasics.save(-1, image1, path0) #print np.max(image1), np.min(image1) print("difference between images: %s" % (diffImage(image, image1))) #plt.imshow(image1 * 255, cmap=mpl.cm.Greys) #plt.show() if re == True: eudist = euclideanDistance(st.image, image1) l1dist = l1Distance(st.image, image1) percent = diffPercent(st.image, image1) print "euclidean distance %s" % (eudist) print "L1 distance %s" % (l1dist) 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.addManipulationPercentage(percent) st.destructor() else: print("do not know how to handle the layer %s of type %s" % (k, layerType)) return runningTime = time.time() - start_time dc.addRunningTime(runningTime) if re == True and exitWhen == "foundFirst": break k += 1 print("Please refer to the file %s for statistics." % (dc.fileName)) if re == True: return True else: return False
def l0Dist(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) return l0Distance(self.image, image1)
def diffPercent(self, index): image1 = applyManipulation(self.image, self.spans[index], self.numSpans[index]) return diffPercent(self.image, image1)
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) = controlledSearch if distMethod == "euclidean": dist = 1000 - euclideanDistance(activations1, self.activations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "L1": dist = 1000 - l1Distance(activations1, self.activations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "Percentage": dist = 1 - diffPercent(activations1, self.activations) termValue = 0.0 termByDist = dist < 1 - distVal elif distMethod == "NumDiffs": dist = self.activations.size - diffPercent( activations1, self.activations) * self.activations.size termValue = 0.0 termByDist = dist < self.activations.size - distVal #if termByDist == False and newConfident < 0.5 and self.depth <= 3: # termByDist = True if newClass != self.originalClass and newConfident > effectiveConfidenceWhenChanging: # and newClass == dataBasics.next_index(self.originalClass,self.originalClass): 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.png" % ( directory_pic_string, startIndexOfImage, self.numConverge) dataBasics.save(-1, activations1, path0) return (self.depth == 0, dist) elif termByDist == True: 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])) == []: 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)