class FazlybSDPAdaptor(RealAdaptorBase): """ SDP from Fazlyb et al """ def __init__(self, dataset, model, timeout=30): super(FazlybSDPAdaptor, self).__init__(dataset, model) cp.settings.SOLVE_TIME = timeout def prepare_solver(self, in_shape): self.prebound = IntervalFastLinBound(self.new_model, in_shape, self.in_min, self.in_max) def verify(self, input, label, norm_type, radius): """ Here we overwrite the base class verify() method """ in_shape = list(input.shape) # only support Linfty norm assert norm_type == 'inf' if self.new_model is None: # init at the first time before = time() print(f"Init model for {self.__class__.__name__}...") self.build_new_model(input) self.prepare_solver(in_shape) after = time() print( "Init done, time", str(datetime.timedelta(seconds=(after - before))), ) # firstly check the clean prediction input = self.input_preprocess(input) xs = input.unsqueeze(0) clean_preds = self.model(xs.cuda()).detach().cpu().numpy() clean_pred = np.argmax(clean_preds[0]) if clean_pred != label: return False m_radius = radius / self.coef input = input.contiguous().view(-1) self.prebound.calculate_bound(input, m_radius) bl = [ np.maximum(self.prebound.l[i], 0) if i > 0 else self.prebound.l[i] for i in range(len(self.prebound.l)) ] bu = [ np.maximum(self.prebound.u[i], 0) if i > 0 else self.prebound.u[i] for i in range(len(self.prebound.u)) ] pv = BaselinePointVerifierExt(self.new_model, in_shape, self.in_min, self.in_max) for i in range(get_num_classes(self.dataset)): if i != label: pv.create_cmat(input, label, i, m_radius, bl, bu) pv.run() if pv.prob.status not in ['unbounded', 'unbounded_inaccurate' ] and pv.prob.value > 0.: return False return True
class MILPAdaptor(RealAdaptorBase): """ MILP from Tjeng et al """ def __init__(self, dataset, model, timeout=30): super(MILPAdaptor, self).__init__(dataset, model) self.timeout = timeout def prepare_solver(self, in_shape): self.prebound = IntervalFastLinBound(self.new_model, in_shape, self.in_min, self.in_max) self.bound = MILPVerifier(self.new_model, in_shape, self.in_min, self.in_max) def verify(self, input, label, norm_type, radius): """ Here we overwrite the base class verify() method """ # only support Linfty norm assert norm_type == 'inf' if self.new_model is None: # init at the first time before = time() print(f"Init model for {self.__class__.__name__}...") in_shape = list(input.shape) self.build_new_model(input) self.prepare_solver(in_shape) after = time() print( "Init done, time", str(datetime.timedelta(seconds=(after - before))), ) # firstly check the clean prediction input = self.input_preprocess(input) xs = input.unsqueeze(0) clean_preds = self.model(xs.cuda()).detach().cpu().numpy() clean_pred = np.argmax(clean_preds[0]) if clean_pred != label: return False m_radius = radius / self.coef input = input.contiguous().view(-1) self.prebound.calculate_bound(input, m_radius) self.bound.construct(self.prebound.l, self.prebound.u, input, m_radius) for i in range(get_num_classes(self.dataset)): if i != label: self.bound.prepare_verify(label, i) try: # self.bound.prob.solve(verbose=True) # model.setParam(GRB.Param.TimeLimit, timeout) self.bound.prob.solve(solver=cp.GUROBI, verbose=False, BestObjStop=-1e-6, TimeLimit=70, Threads=20) except: return False print(self.bound.prob.status, self.bound.prob.value, file=sys.stderr) if self.bound.prob.status not in [ 'optimal' ] or self.bound.prob.value < 0.: return False return True