Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
YIYAYIYAYOUCHENG committed Sep 13, 2021
1 parent c361f2a commit 23586d9
Show file tree
Hide file tree
Showing 19 changed files with 737 additions and 0 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added src/__pycache__/mask.cpython-37.pyc
Binary file not shown.
Binary file added src/__pycache__/spectra_gen.cpython-37.pyc
Binary file not shown.
Binary file added src/__pycache__/to_explain.cpython-37.pyc
Binary file not shown.
Binary file added src/__pycache__/to_rank.cpython-37.pyc
Binary file not shown.
Binary file added src/__pycache__/utils.cpython-37.pyc
Binary file not shown.
19 changes: 19 additions & 0 deletions src/mask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import numpy as np

def find_mask(x, p=2/32):
sp=x.shape
h=int(sp[0]*p)
if h<1: h=1
tmp_x=x.copy()
bg_x=x.copy()

for iindex, _ in np.ndenumerate(x):
i0=iindex[0]
i1=iindex[1]
region=tmp_x[ np.max([i0-h,0]) : np.min([i0+h, sp[0]]), np.max([i1-h,0]):np.min([i1+h,sp[1]])]
v=np.min(region)
for j in range(0, (sp[2])):
#bg_x[i0][i1][j]=v
bg_x[i0][i1][j]=np.mean(region[:,:,j])

return bg_x
138 changes: 138 additions & 0 deletions src/sfl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

from keras.preprocessing import image
from keras.applications import vgg16
from keras.applications.vgg16 import VGG16
from keras.applications import inception_v3, mobilenet, xception
from keras.models import load_model
import matplotlib.pyplot as plt

import argparse
import os
import numpy as np

from utils import *
from to_explain import *

def main():
parser=argparse.ArgumentParser(description='To explain neural network decisions' )
parser.add_argument(
'--model', dest='model', default='-1', help='the input neural network model (.h5)')
parser.add_argument("--inputs", dest="inputs", default="-1",
help="the input test data directory", metavar="DIR")
parser.add_argument("--outputs", dest="outputs", default="outs",
help="the outputput test data directory", metavar="DIR")
parser.add_argument("--measures", dest="measures", default=['tarantula', 'zoltar', 'ochiai', 'wong-ii'],
help="the measures", metavar="zoltar, tarantula ...", nargs='+')
parser.add_argument("--measure", dest="measure", default="None",
help="the measure", metavar="zoltar, tarantula ...")
parser.add_argument("--mnist-dataset", dest="mnist", help="MNIST dataset", action="store_true")
parser.add_argument("--normalized-input", dest="normalized", help="To normalize the input", action="store_true")
parser.add_argument("--cifar10-dataset", dest="cifar10", help="CIFAR-10 dataset", action="store_true")
parser.add_argument("--grayscale", dest="grayscale", help="MNIST dataset", action="store_true")
parser.add_argument("--vgg16-model", dest='vgg16', help="vgg16 model", action="store_true")
parser.add_argument("--inception-v3-model", dest='inception_v3', help="inception v3 model", action="store_true")
parser.add_argument("--xception-model", dest='xception', help="Xception model", action="store_true")
parser.add_argument("--mobilenet-model", dest='mobilenet', help="mobilenet model", action="store_true")
parser.add_argument("--attack", dest='attack', help="to atatck", action="store_true")
parser.add_argument("--text-only", dest='text_only', help="for efficiency", action="store_true")
parser.add_argument("--input-rows", dest="img_rows", default="224",
help="input rows", metavar="INT")
parser.add_argument("--input-cols", dest="img_cols", default="224",
help="input cols", metavar="INT")
parser.add_argument("--input-channels", dest="img_channels", default="3",
help="input channels", metavar="INT")
parser.add_argument("--top-classes", dest="top_classes", default="1",
help="check the top-xx classifications", metavar="INT")
parser.add_argument("--adversarial-ub", dest="adv_ub", default="1.",
help="upper bound on the adversarial percentage (0, 1]", metavar="FLOAT")
parser.add_argument("--adversarial-lb", dest="adv_lb", default="0.",
help="lower bound on the adversarial percentage (0, 1]", metavar="FLOAT")
parser.add_argument("--adversarial-value", dest="adv_value", default="234",
help="adversarial value", metavar="FLOAT")
parser.add_argument("--testgen-factor", dest="testgen_factor", default="0.2",
help="test generation factor (0, 1]", metavar="FLOAT")
parser.add_argument("--testgen-size", dest="testgen_size", default="2000",
help="testgen size ", metavar="INT")
parser.add_argument("--testgen-iterations", dest="testgen_iter", default="1",
help="to control the testgen iteration", metavar="INT")

args=parser.parse_args()

img_rows, img_cols, img_channels = int(args.img_rows), int(args.img_cols), int(args.img_channels)

## some common used datasets
if args.mnist:
img_rows, img_cols, img_channels = 28, 28, 1
elif args.cifar10:
img_rows, img_cols, img_channels = 32, 32, 3
elif args.inception_v3 or args.xception:
img_rows, img_cols, img_channels = 299, 299, 3

## to load the input DNN model
if args.model!='-1':
dnn=load_model(args.model)
elif args.vgg16:
print ('to load VGG16')
dnn=VGG16()
print ('done')
elif args.mobilenet:
dnn=mobilenet.MobileNet()
elif args.inception_v3:
dnn=inception_v3.InceptionV3()
elif args.xception:
dnn=xception.Xception()
else:
raise Exception ('A DNN model needs to be provided...')

## to load the input data
fnames=[]
xs=[]
if args.inputs!='-1':
for path, subdirs, files in os.walk(args.inputs):
for name in files:
fname=(os.path.join(path, name))
if fname.endswith('.jpg') or fname.endswith('.png') or fname.endswith('.JPEG'):
if args.grayscale is True or args.mnist:
x=image.load_img(fname, target_size=(img_rows, img_cols), color_mode = "grayscale")
x=np.expand_dims(x,axis=2)
else:
x=image.load_img(fname, target_size=(img_rows, img_cols))
x=np.expand_dims(x,axis=0)
xs.append(x)
fnames.append(fname)
else:
raise Exception ('What do you want me to do?')
xs=np.vstack(xs)
xs = xs.reshape(xs.shape[0], img_rows, img_cols, img_channels)
print ('Total data loaded:', len(xs))

eobj=explain_objectt(dnn, xs)
eobj.outputs=args.outputs
eobj.top_classes=int(args.top_classes)
eobj.adv_ub=float(args.adv_ub)
eobj.adv_lb=float(args.adv_lb)
eobj.adv_value=float(args.adv_value)
eobj.testgen_factor=float(args.testgen_factor)
eobj.testgen_size=int(args.testgen_size)
eobj.testgen_iter=int(args.testgen_iter)
eobj.vgg16=args.vgg16
eobj.mnist=args.mnist
eobj.cifar10=args.cifar10
eobj.inception_v3=args.inception_v3
eobj.xception=args.xception
eobj.mobilenet=args.mobilenet
eobj.attack=args.attack
eobj.text_only=args.text_only
eobj.normalized=args.normalized
eobj.fnames=fnames
measures = []
if not args.measure=='None':
measures.append(args.measure)
else: measures = args.measures
eobj.measures=measures

to_explain(eobj)

if __name__=="__main__":
main()

138 changes: 138 additions & 0 deletions src/spectra_gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import numpy as np
from utils import *

def spectra_sym_gen(eobj, x, y, adv_value=1, testgen_factor=.2, testgen_size=0):


v_type=type(adv_value)
model=eobj.model
failing=[]
passing=[]

#inputs=[]
sp=x.shape
x_flag=np.zeros(sp, dtype=bool)
portion=int(sp[0]*testgen_factor)
incr=1/6*portion
if portion<1: portion=1
L0=np.array(np.arange(x.size))
L0=np.reshape(L0, sp)

while (not np.all(x_flag)) or len(passing)+len(failing)<testgen_size:
#print ('####', len(passing), len(failing))
t=x.copy()

i0=np.random.randint(0,sp[0])
i1=np.random.randint(0,sp[1])

h=portion
region=L0[ np.max([i0-h,0]) : np.min([i0+h, sp[0]]), np.max([i1-h,0]):np.min([i1+h,sp[1]])].flatten()

L=region #L0[0:portion]
if v_type==np.ndarray:
np.put(t, L, adv_value.take(L))
else:
np.put(t, L, adv_value)
x_flag.flat[L]=True #np.put(x, L, True)
new_y=np.argsort(model.predict(sbfl_preprocess(eobj, np.array([t]))))[0][-eobj.top_classes:]
is_adv=(len(np.intersect1d(y, new_y))==0)

if is_adv:
failing.append(t)
## to find a passing
ite=h #testgen_factor
while ite>1: #ite>0.01:
t2=x.copy()
#ite=ite-1#ite//2 #ite=(ite+0)/2
ite=int(ite-incr)
if ite<1: break
region=L0[ np.max([i0-ite,0]) : np.min([i0+ite, sp[0]]), np.max([i1-ite,0]):np.min([i1+ite,sp[1]])].flatten()

L=region #L0[0:portion]
if v_type==np.ndarray:
np.put(t, L, adv_value.take(L))
else:
np.put(t, L, adv_value)
x_flag.flat[L]=True #np.put(x, L, True)
new_y=np.argsort(model.predict(sbfl_preprocess(eobj, np.array([t]))))[0][-eobj.top_classes:]
#is_adv=(len(np.intersect1d(y, new_y))==0)
#ite-=0.01
#L2=L0[0:int(ite/testgen_factor*portion)]
#if v_type==np.ndarray:
# np.put(t2, L2, adv_value.take(L2))
#else:
# np.put(t2, L2, adv_value)
#new_y=np.argsort(model.predict(sbfl_preprocess(eobj, np.array([t2]))))[0][-eobj.top_classes:]
##print (y, new_y)
if (len(np.intersect1d(y, new_y))!=0):
passing.append(t2)
break

else:
passing.append(t)
## to find a failing
ite=h #testgen_factor
while ite<sp[0]/2: #0.99:
t2=x.copy()
#ite=ite+1#ite*2
ite=int(ite+incr)
if ite>sp[0]/2: break
region=L0[ np.max([i0-ite,0]) : np.min([i0+ite, sp[0]]), np.max([i1-ite,0]):np.min([i1+ite,sp[1]])].flatten()

L=region #L0[0:portion]
if v_type==np.ndarray:
np.put(t, L, adv_value.take(L))
else:
np.put(t, L, adv_value)
x_flag.flat[L]=True #np.put(x, L, True)
new_y=np.argsort(model.predict(sbfl_preprocess(eobj, np.array([t]))))[0][-eobj.top_classes:]
#t2=x.copy()
#ite=(ite+1)/2
##ite+=0.01
#L2=L0[0:int(ite/testgen_factor*portion)]
#if v_type==np.ndarray:
# np.put(t2, L2, adv_value.take(L2))
#else:
# np.put(t2, L2, adv_value)
#new_y=np.argsort(model.predict(sbfl_preprocess(eobj, np.array([t2]))))[0][-eobj.top_classes:]
if (len(np.intersect1d(y, new_y))==0):
failing.append(t2)
x_flag.flat[L]=True
break

return np.array(passing), np.array(failing)

def spectra_gen(x, adv_value=1, testgen_factor=0.01, testgen_size=0):

#print (adv_value, testgen_factor, testgen_size)
v_type=type(adv_value)

inputs=[]
sp=x.shape
x_flag=np.zeros(sp, dtype=bool)
portion=int(x.size*testgen_factor) #int(x.size/sp[2]*testgen_factor)

while (not np.all(x_flag)) or len(inputs)<testgen_size:
t=x.copy()
L=np.random.choice(x.size, portion)
if v_type==np.ndarray:
#t.flat[L]=adv_value.take(L)
np.put(t, L, adv_value.take(L))
else:
#t.flat[L]=adv_value
np.put(t, L, adv_value)
x_flag.flat[L]=True #np.put(x, L, True)
#for pos in L:
# ipos=np.unravel_index(pos,sp)
# #if v_type==np.ndarray:
# # t.flat[pos]=adv_value.flat[pos]
# #else: t.flat[pos]=adv_value
# #x_flag.flat[pos]=True #np.put(x, L, True)
# for j in range(0, sp[2]):
# if v_type==np.ndarray:
# t[ipos[0]][ipos[1]][j]=adv_value[ipos[0]][ipos[1]][j]
# else:
# t[ipos[0]][ipos[1]][j]=adv_value
# x_flag[ipos[0]][ipos[1]][j]=True
inputs.append(t)
return inputs
58 changes: 58 additions & 0 deletions src/to_attack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

import numpy as np
from utils import *
from sbfl import *

def to_attack(eobj, ind, origin_data, bg_v, init_step, step_incr):

v_type=type(bg_v)

top_classes=eobj.top_classes
sp=origin_data.shape

x=origin_data
model=eobj.model
y=np.argsort(model.predict(sbfl_preprocess(eobj,np.array([x]))))[0][-top_classes:]

latest_step=ind.size

#im=np.ones(sp)
#im=np.multiply(im, bg_v)
im=x.copy()
im_flag=np.zeros(im.shape, dtype=bool)

pos=ind.size-1
old_count=1
count=1

adv_v=0

while pos>=0:

ipos=np.unravel_index(ind[pos], sp)
if not im_flag[ipos]:
for k in range(0,sp[2]):
if type(bg_v)==np.ndarray:
im[ipos[0]][ipos[1]][k]=bg_v[ipos[0]][ipos[1]][k]
else:
im[ipos[0]][ipos[1]][k]=bg_v
im_flag[ipos[0]][ipos[1]][k]=True
count+=1

pos-=1

if count<init_step: continue ## to start from a partial image

if count>5000: break

if count-old_count>=step_incr:
old_count=count

adv_v=model.predict(sbfl_preprocess(eobj, np.array([im])))
adv_y=np.argsort(adv_v)[0][-top_classes:]
if len(np.intersect1d(y, adv_y))==0:
#if np.sort(adv_v)[0][-top_classes:][0]>.5:
return im, count, np.sort(adv_v)[0][-top_classes:]

return x, x.size//sp[2], [None]

Loading

0 comments on commit 23586d9

Please sign in to comment.