| @@ -42,6 +42,6 @@ Dataset used: [COCO2017](<https://cocodataset.org/>) | |||
| # Quick start | |||
| You can download the pre-trained model checkpoint file [here](<https://www.mindspore.cn/resources/hub/details?2505/MindSpore/ascend/0.7/fasterrcnn_v1.0_coco2017>). | |||
| ``` | |||
| python coco_attack_pgd.py --ann_file [VAL_JSON_FILE] --pre_trained [PRETRAINED_CHECKPOINT_FILE] | |||
| python coco_attack_pgd.py --pre_trained [PRETRAINED_CHECKPOINT_FILE] | |||
| ``` | |||
| > Adversarial samples will be generated and saved as pickle file. | |||
| @@ -33,7 +33,6 @@ from src.dataset import data_to_mindrecord_byte_image, create_fasterrcnn_dataset | |||
| set_seed(1) | |||
| parser = argparse.ArgumentParser(description='FasterRCNN attack') | |||
| parser.add_argument('--ann_file', type=str, required=True, help='Ann file path.') | |||
| parser.add_argument('--pre_trained', type=str, required=True, help='pre-trained ckpt file path for target model.') | |||
| parser.add_argument('--device_id', type=int, default=0, help='Device id, default is 0.') | |||
| parser.add_argument('--num', type=int, default=5, help='Number of adversarial examples.') | |||
| @@ -55,7 +54,7 @@ class WithLossCell(Cell): | |||
| self._backbone = backbone | |||
| self._loss_fn = loss_fn | |||
| def construct(self, img_data, img_metas, gt_bboxes, gt_labels, gt_num): | |||
| def construct(self, img_data, img_metas, gt_bboxes, gt_labels, gt_num, *labels): | |||
| loss1, loss2, loss3, loss4, loss5, loss6 = self._backbone(img_data, img_metas, gt_bboxes, gt_labels, gt_num) | |||
| return self._loss_fn(loss1, loss2, loss3, loss4, loss5, loss6) | |||
| @@ -74,8 +73,8 @@ class GradWrapWithLoss(Cell): | |||
| self._grad_all = GradOperation(get_all=True, sens_param=False) | |||
| self._network = network | |||
| def construct(self, img_data, img_metas, gt_bboxes, gt_labels, gt_num): | |||
| gout = self._grad_all(self._network)(img_data, img_metas, gt_bboxes, gt_labels, gt_num) | |||
| def construct(self, *inputs): | |||
| gout = self._grad_all(self._network)(*inputs) | |||
| return gout[0] | |||
| @@ -84,7 +83,6 @@ if __name__ == '__main__': | |||
| mindrecord_dir = config.mindrecord_dir | |||
| mindrecord_file = os.path.join(mindrecord_dir, prefix) | |||
| pre_trained = args.pre_trained | |||
| ann_file = args.ann_file | |||
| print("CHECKING MINDRECORD FILES ...") | |||
| if not os.path.exists(mindrecord_file): | |||
| @@ -116,7 +114,7 @@ if __name__ == '__main__': | |||
| num = args.num | |||
| num_batches = num // config.test_batch_size | |||
| channel = 3 | |||
| adv_samples = [0] * (num_batches * config.test_batch_size) | |||
| adv_samples = [0]*(num_batches*config.test_batch_size) | |||
| adv_id = 0 | |||
| for data in ds.create_dict_iterator(num_epochs=num_batches): | |||
| img_data = data['image'] | |||
| @@ -125,11 +123,13 @@ if __name__ == '__main__': | |||
| gt_labels = data['label'] | |||
| gt_num = data['valid_num'] | |||
| adv_img = attack.generate(img_data.asnumpy(), \ | |||
| (img_metas.asnumpy(), gt_bboxes.asnumpy(), gt_labels.asnumpy(), gt_num.asnumpy())) | |||
| adv_img = attack.generate((img_data.asnumpy(), \ | |||
| img_metas.asnumpy(), gt_bboxes.asnumpy(), gt_labels.asnumpy(), gt_num.asnumpy()), gt_labels.asnumpy()) | |||
| for item in adv_img: | |||
| adv_samples[adv_id] = item | |||
| adv_id += 1 | |||
| if adv_id >= num_batches*config.test_batch_size: | |||
| break | |||
| pickle.dump(adv_samples, open('adv_samples.pkl', 'wb')) | |||
| print('Generate adversarial samples complete.') | |||
| @@ -41,7 +41,7 @@ class Attack: | |||
| their labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Samples based on which adversarial | |||
| inputs (Union[numpy.ndarray, tuple]): Samples based on which adversarial | |||
| examples are generated. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -55,21 +55,30 @@ class Attack: | |||
| >>> labels = np.array([3, 0]) | |||
| >>> advs = attack.batch_generate(inputs, labels, batch_size=2) | |||
| """ | |||
| inputs_image = inputs[0] if isinstance(inputs, tuple) else inputs | |||
| if isinstance(inputs, tuple): | |||
| for i, inputs_item in enumerate(inputs): | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'inputs[{}]'.format(i), inputs_item) | |||
| if isinstance(labels, tuple): | |||
| for i, labels_item in enumerate(labels): | |||
| arr_x, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'labels[{}]'.format(i), labels_item) | |||
| else: | |||
| arr_x, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs', inputs_image, \ | |||
| 'labels', labels) | |||
| arr_x = inputs | |||
| arr_y = labels | |||
| len_x = arr_x.shape[0] | |||
| len_x = inputs_image.shape[0] | |||
| batch_size = check_int_positive('batch_size', batch_size) | |||
| batches = int(len_x / batch_size) | |||
| rest = len_x - batches*batch_size | |||
| res = [] | |||
| for i in range(batches): | |||
| x_batch = arr_x[i*batch_size: (i + 1)*batch_size] | |||
| if isinstance(arr_x, tuple): | |||
| x_batch = tuple([sub_items[i*batch_size: (i + 1)*batch_size] for sub_items in arr_x]) | |||
| else: | |||
| x_batch = arr_x[i*batch_size: (i + 1)*batch_size] | |||
| if isinstance(arr_y, tuple): | |||
| y_batch = tuple([sub_labels[i*batch_size: (i + 1)*batch_size] for sub_labels in arr_y]) | |||
| else: | |||
| @@ -79,12 +88,14 @@ class Attack: | |||
| res.append(adv_x[1] if isinstance(adv_x, tuple) else adv_x) | |||
| if rest != 0: | |||
| x_batch = arr_x[batches*batch_size:] | |||
| if isinstance(arr_x, tuple): | |||
| x_batch = tuple([sub_items[batches*batch_size:] for sub_items in arr_x]) | |||
| else: | |||
| x_batch = arr_x[batches*batch_size:] | |||
| if isinstance(arr_y, tuple): | |||
| y_batch = tuple([sub_labels[batches*batch_size:] for sub_labels in arr_y]) | |||
| else: | |||
| y_batch = arr_y[batches*batch_size:] | |||
| y_batch = arr_y[batches*batch_size:] | |||
| adv_x = self.generate(x_batch, y_batch) | |||
| # Black-attack methods will return 3 values, just get the second. | |||
| res.append(adv_x[1] if isinstance(adv_x, tuple) else adv_x) | |||
| @@ -98,7 +109,7 @@ class Attack: | |||
| Generate adversarial examples based on normal samples and their labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Samples based on which adversarial | |||
| inputs (Union[numpy.ndarray, tuple]): Samples based on which adversarial | |||
| examples are generated. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -78,8 +78,7 @@ class SaltAndPepperNoiseAttack(Attack): | |||
| Examples: | |||
| >>> adv_list = attack.generate(([[0.1, 0.2, 0.6], | |||
| >>> [0.3, 0, 0.4]], | |||
| >>> [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0], | |||
| >>> [0, , 0, 1, 0, 0, 0, 0, 0, 0, 0]]) | |||
| >>> [1, 2]) | |||
| """ | |||
| arr_x, arr_y = check_pair_numpy_param('inputs', inputs, 'labels', | |||
| labels) | |||
| @@ -83,7 +83,7 @@ class GradientMethod(Attack): | |||
| Generate adversarial examples based on input samples and original/target labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Benign input samples used as references to create | |||
| inputs (Union[numpy.ndarray, tuple]): Benign input samples used as references to create | |||
| adversarial examples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -91,14 +91,19 @@ class GradientMethod(Attack): | |||
| Returns: | |||
| numpy.ndarray, generated adversarial examples. | |||
| """ | |||
| inputs_image = inputs[0] if isinstance(inputs, tuple) else inputs | |||
| if isinstance(inputs, tuple): | |||
| for i, inputs_item in enumerate(inputs): | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'inputs[{}]'.format(i), inputs_item) | |||
| if isinstance(labels, tuple): | |||
| for i, labels_item in enumerate(labels): | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'labels[{}]'.format(i), labels_item) | |||
| else: | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs', inputs_image, \ | |||
| 'labels', labels) | |||
| self._dtype = inputs.dtype | |||
| self._dtype = inputs_image.dtype | |||
| gradient = self._gradient(inputs, labels) | |||
| # use random method or not | |||
| if self._alpha is not None: | |||
| @@ -111,10 +116,10 @@ class GradientMethod(Attack): | |||
| if self._bounds is not None: | |||
| clip_min, clip_max = self._bounds | |||
| perturbation = perturbation*(clip_max - clip_min) | |||
| adv_x = inputs + perturbation | |||
| adv_x = inputs_image + perturbation | |||
| adv_x = np.clip(adv_x, clip_min, clip_max) | |||
| else: | |||
| adv_x = inputs + perturbation | |||
| adv_x = inputs_image + perturbation | |||
| return adv_x | |||
| @abstractmethod | |||
| @@ -123,7 +128,7 @@ class GradientMethod(Attack): | |||
| Calculate gradients based on input samples and original/target labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Benign input samples used as references to | |||
| inputs (Union[numpy.ndarray, tuple]): Benign input samples used as references to | |||
| create adversarial examples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -184,20 +189,26 @@ class FastGradientMethod(GradientMethod): | |||
| Calculate gradients based on input samples and original/target labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Input sample. | |||
| inputs (Union[numpy.ndarray, tuple]): Input sample. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| Returns: | |||
| numpy.ndarray, gradient of inputs. | |||
| """ | |||
| if isinstance(inputs, tuple): | |||
| inputs_tensor = tuple() | |||
| for item in inputs: | |||
| inputs_tensor += (Tensor(item),) | |||
| else: | |||
| inputs_tensor = (Tensor(inputs),) | |||
| if isinstance(labels, tuple): | |||
| labels_tensor = tuple() | |||
| for item in labels: | |||
| labels_tensor += (Tensor(item),) | |||
| else: | |||
| labels_tensor = (Tensor(labels),) | |||
| out_grad = self._grad_all(Tensor(inputs), *labels_tensor) | |||
| out_grad = self._grad_all(*inputs_tensor, *labels_tensor) | |||
| if isinstance(out_grad, tuple): | |||
| out_grad = out_grad[0] | |||
| gradient = out_grad.asnumpy() | |||
| @@ -297,20 +308,26 @@ class FastGradientSignMethod(GradientMethod): | |||
| labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Input samples. | |||
| labels (union[numpy.ndarray, tuple]): original/target labels. \ | |||
| inputs (Union[numpy.ndarray, tuple]): Input samples. | |||
| labels (Union[numpy.ndarray, tuple]): original/target labels. \ | |||
| for each input if it has more than one label, it is wrapped in a tuple. | |||
| Returns: | |||
| numpy.ndarray, gradient of inputs. | |||
| """ | |||
| if isinstance(inputs, tuple): | |||
| inputs_tensor = tuple() | |||
| for item in inputs: | |||
| inputs_tensor += (Tensor(item),) | |||
| else: | |||
| inputs_tensor = (Tensor(inputs),) | |||
| if isinstance(labels, tuple): | |||
| labels_tensor = tuple() | |||
| for item in labels: | |||
| labels_tensor += (Tensor(item),) | |||
| else: | |||
| labels_tensor = (Tensor(labels),) | |||
| out_grad = self._grad_all(Tensor(inputs), *labels_tensor) | |||
| out_grad = self._grad_all(*inputs_tensor, *labels_tensor) | |||
| if isinstance(out_grad, tuple): | |||
| out_grad = out_grad[0] | |||
| gradient = out_grad.asnumpy() | |||
| @@ -141,7 +141,7 @@ class IterativeGradientMethod(Attack): | |||
| Generate adversarial examples based on input samples and original/target labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Benign input samples used as references to create | |||
| inputs (Union[numpy.ndarray, tuple]): Benign input samples used as references to create | |||
| adversarial examples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -210,7 +210,7 @@ class BasicIterativeMethod(IterativeGradientMethod): | |||
| Simple iterative FGSM method to generate adversarial examples. | |||
| Args: | |||
| inputs (numpy.ndarray): Benign input samples used as references to | |||
| inputs (Union[numpy.ndarray, tuple]): Benign input samples used as references to | |||
| create adversarial examples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -223,36 +223,45 @@ class BasicIterativeMethod(IterativeGradientMethod): | |||
| >>> [[0, 0, 1, 0, 0, 0, 0, 0, 0, 0], | |||
| >>> [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]]) | |||
| """ | |||
| inputs_image = inputs[0] if isinstance(inputs, tuple) else inputs | |||
| if isinstance(inputs, tuple): | |||
| for i, inputs_item in enumerate(inputs): | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'inputs[{}]'.format(i), inputs_item) | |||
| if isinstance(labels, tuple): | |||
| for i, labels_item in enumerate(labels): | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'labels[{}]'.format(i), labels_item) | |||
| else: | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs', inputs_image, \ | |||
| 'labels', labels) | |||
| arr_x = inputs | |||
| arr_x = inputs_image | |||
| if self._bounds is not None: | |||
| clip_min, clip_max = self._bounds | |||
| clip_diff = clip_max - clip_min | |||
| for _ in range(self._nb_iter): | |||
| if 'self._prob' in globals(): | |||
| d_inputs = _transform_inputs(inputs, self._prob) | |||
| d_inputs = _transform_inputs(inputs_image, self._prob) | |||
| else: | |||
| d_inputs = inputs | |||
| d_inputs = inputs_image | |||
| if isinstance(inputs, tuple): | |||
| d_inputs = (d_inputs,) + inputs[1:] | |||
| adv_x = self._attack.generate(d_inputs, labels) | |||
| perturs = np.clip(adv_x - arr_x, (0 - self._eps)*clip_diff, | |||
| self._eps*clip_diff) | |||
| adv_x = arr_x + perturs | |||
| inputs = adv_x | |||
| inputs_image = adv_x | |||
| else: | |||
| for _ in range(self._nb_iter): | |||
| if 'self._prob' in globals(): | |||
| d_inputs = _transform_inputs(inputs, self._prob) | |||
| d_inputs = _transform_inputs(inputs_image, self._prob) | |||
| else: | |||
| d_inputs = inputs | |||
| d_inputs = inputs_image | |||
| if isinstance(inputs, tuple): | |||
| d_inputs = (inputs_image,) + inputs[1:] | |||
| adv_x = self._attack.generate(d_inputs, labels) | |||
| adv_x = np.clip(adv_x, arr_x - self._eps, arr_x + self._eps) | |||
| inputs = adv_x | |||
| inputs_image = adv_x | |||
| return adv_x | |||
| @@ -299,7 +308,7 @@ class MomentumIterativeMethod(IterativeGradientMethod): | |||
| Generate adversarial examples based on input data and origin/target labels. | |||
| Args: | |||
| inputs (numpy.ndarray): Benign input samples used as references to | |||
| inputs (Union[numpy.ndarray, tuple]): Benign input samples used as references to | |||
| create adversarial examples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -313,42 +322,57 @@ class MomentumIterativeMethod(IterativeGradientMethod): | |||
| >>> [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0], | |||
| >>> [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]]) | |||
| """ | |||
| inputs_image = inputs[0] if isinstance(inputs, tuple) else inputs | |||
| if isinstance(inputs, tuple): | |||
| for i, inputs_item in enumerate(inputs): | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'inputs[{}]'.format(i), inputs_item) | |||
| if isinstance(labels, tuple): | |||
| for i, labels_item in enumerate(labels): | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'labels[{}]'.format(i), labels_item) | |||
| else: | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs', inputs_image, \ | |||
| 'labels', labels) | |||
| arr_x = inputs | |||
| arr_x = inputs_image | |||
| momentum = 0 | |||
| if self._bounds is not None: | |||
| clip_min, clip_max = self._bounds | |||
| clip_diff = clip_max - clip_min | |||
| for _ in range(self._nb_iter): | |||
| if 'self._prob' in globals(): | |||
| d_inputs = _transform_inputs(inputs, self._prob) | |||
| d_inputs = _transform_inputs(inputs_image, self._prob) | |||
| else: | |||
| d_inputs = inputs | |||
| d_inputs = inputs_image | |||
| if isinstance(inputs, tuple): | |||
| d_inputs = (d_inputs,) + inputs[1:] | |||
| gradient = self._gradient(d_inputs, labels) | |||
| momentum = self._decay_factor*momentum + gradient | |||
| adv_x = d_inputs + self._eps_iter*np.sign(momentum) | |||
| if isinstance(d_inputs, tuple): | |||
| adv_x = d_inputs[0] + self._eps_iter*np.sign(momentum) | |||
| else: | |||
| adv_x = d_inputs + self._eps_iter*np.sign(momentum) | |||
| perturs = np.clip(adv_x - arr_x, (0 - self._eps)*clip_diff, | |||
| self._eps*clip_diff) | |||
| adv_x = arr_x + perturs | |||
| adv_x = np.clip(adv_x, clip_min, clip_max) | |||
| inputs = adv_x | |||
| inputs_image = adv_x | |||
| else: | |||
| for _ in range(self._nb_iter): | |||
| if 'self._prob' in globals(): | |||
| d_inputs = _transform_inputs(inputs, self._prob) | |||
| d_inputs = _transform_inputs(inputs_image, self._prob) | |||
| else: | |||
| d_inputs = inputs | |||
| d_inputs = inputs_image | |||
| if isinstance(inputs, tuple): | |||
| d_inputs = (d_inputs,) + inputs[1:] | |||
| gradient = self._gradient(d_inputs, labels) | |||
| momentum = self._decay_factor*momentum + gradient | |||
| adv_x = d_inputs + self._eps_iter*np.sign(momentum) | |||
| if isinstance(d_inputs, tuple): | |||
| adv_x = d_inputs[0] + self._eps_iter*np.sign(momentum) | |||
| else: | |||
| adv_x = d_inputs + self._eps_iter*np.sign(momentum) | |||
| adv_x = np.clip(adv_x, arr_x - self._eps, arr_x + self._eps) | |||
| inputs = adv_x | |||
| inputs_image = adv_x | |||
| return adv_x | |||
| def _gradient(self, inputs, labels): | |||
| @@ -356,7 +380,7 @@ class MomentumIterativeMethod(IterativeGradientMethod): | |||
| Calculate the gradient of input samples. | |||
| Args: | |||
| inputs (numpy.ndarray): Input samples. | |||
| inputs (Union[numpy.ndarray, tuple]): Input samples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -368,13 +392,19 @@ class MomentumIterativeMethod(IterativeGradientMethod): | |||
| >>> [[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]) | |||
| """ | |||
| # get grad of loss over x | |||
| if isinstance(inputs, tuple): | |||
| inputs_tensor = tuple() | |||
| for item in inputs: | |||
| inputs_tensor += (Tensor(item),) | |||
| else: | |||
| inputs_tensor = (Tensor(inputs),) | |||
| if isinstance(labels, tuple): | |||
| labels_tensor = tuple() | |||
| for item in labels: | |||
| labels_tensor += (Tensor(item),) | |||
| else: | |||
| labels_tensor = (Tensor(labels),) | |||
| out_grad = self._loss_grad(Tensor(inputs), *labels_tensor) | |||
| out_grad = self._loss_grad(*inputs_tensor, *labels_tensor) | |||
| if isinstance(out_grad, tuple): | |||
| out_grad = out_grad[0] | |||
| gradient = out_grad.asnumpy() | |||
| @@ -429,7 +459,7 @@ class ProjectedGradientDescent(BasicIterativeMethod): | |||
| perturbation is normalized by projected method with parameter norm_level . | |||
| Args: | |||
| inputs (numpy.ndarray): Benign input samples used as references to | |||
| inputs (Union[numpy.ndarray, tuple]): Benign input samples used as references to | |||
| create adversarial examples. | |||
| labels (Union[numpy.ndarray, tuple]): Original/target labels. \ | |||
| For each input if it has more than one label, it is wrapped in a tuple. | |||
| @@ -443,14 +473,19 @@ class ProjectedGradientDescent(BasicIterativeMethod): | |||
| >>> [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1], | |||
| >>> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) | |||
| """ | |||
| inputs_image = inputs[0] if isinstance(inputs, tuple) else inputs | |||
| if isinstance(inputs, tuple): | |||
| for i, inputs_item in enumerate(inputs): | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'inputs[{}]'.format(i), inputs_item) | |||
| if isinstance(labels, tuple): | |||
| for i, labels_item in enumerate(labels): | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs_image', inputs_image, \ | |||
| 'labels[{}]'.format(i), labels_item) | |||
| else: | |||
| inputs, _ = check_pair_numpy_param('inputs', inputs, \ | |||
| _ = check_pair_numpy_param('inputs', inputs_image, \ | |||
| 'labels', labels) | |||
| arr_x = inputs | |||
| arr_x = inputs_image | |||
| if self._bounds is not None: | |||
| clip_min, clip_max = self._bounds | |||
| clip_diff = clip_max - clip_min | |||
| @@ -462,7 +497,10 @@ class ProjectedGradientDescent(BasicIterativeMethod): | |||
| perturs = np.clip(perturs, (0 - self._eps)*clip_diff, | |||
| self._eps*clip_diff) | |||
| adv_x = arr_x + perturs | |||
| inputs = adv_x | |||
| if isinstance(inputs, tuple): | |||
| inputs = (adv_x,) + inputs[1:] | |||
| else: | |||
| inputs = adv_x | |||
| else: | |||
| for _ in range(self._nb_iter): | |||
| adv_x = self._attack.generate(inputs, labels) | |||
| @@ -471,7 +509,10 @@ class ProjectedGradientDescent(BasicIterativeMethod): | |||
| norm_level=self._norm_level) | |||
| adv_x = arr_x + perturs | |||
| adv_x = np.clip(adv_x, arr_x - self._eps, arr_x + self._eps) | |||
| inputs = adv_x | |||
| if isinstance(inputs, tuple): | |||
| inputs = (adv_x,) + inputs[1:] | |||
| else: | |||
| inputs = adv_x | |||
| return adv_x | |||
| @@ -580,7 +621,7 @@ def _transform_inputs(inputs, prob, low=29, high=33, full_aug=False): | |||
| tran_outputs.append(np.array(p_sample).astype(np.float) / 255) | |||
| if full_aug: | |||
| # gaussian noise | |||
| tran_outputs = np.random.normal(tran_outputs.shape) + tran_outputs | |||
| tran_outputs = np.random.normal(np.array(tran_outputs).shape) + tran_outputs | |||
| tran_outputs.extend(raw_inputs) | |||
| if not np.any(tran_outputs-raw_inputs): | |||
| LOGGER.error(TAG, 'the transform function does not take effect.') | |||
| @@ -351,8 +351,8 @@ class Fuzzer: | |||
| for param_name in selected_param: | |||
| transform.__setattr__('_' + str(param_name), | |||
| selected_param[param_name]) | |||
| mutate_sample = transform.generate([seed[0].astype(np.float32)], | |||
| [seed[1]])[0] | |||
| mutate_sample = transform.generate(np.array([seed[0].astype(np.float32)]), | |||
| np.array([seed[1]]))[0] | |||
| if method not in self._pixel_value_trans_list: | |||
| only_pixel_trans = 1 | |||
| mutate_sample = [mutate_sample, seed[1], only_pixel_trans] | |||
| @@ -72,7 +72,15 @@ class Net2(Cell): | |||
| def construct(self, inputs1, inputs2): | |||
| out1 = self._relu(inputs1) | |||
| out2 = self._relu(inputs2) | |||
| return out1 + out2 | |||
| return out1 + out2, out1 - out2 | |||
| class LossNet(Cell): | |||
| """ | |||
| Loss function for test. | |||
| """ | |||
| def construct(self, loss1, loss2, labels1, labels2): | |||
| return loss1 + loss2 - labels1 - labels2 | |||
| class WithLossCell(Cell): | |||
| @@ -82,9 +90,9 @@ class WithLossCell(Cell): | |||
| self._backbone = backbone | |||
| self._loss_fn = loss_fn | |||
| def construct(self, inputs1, inputs2, labels): | |||
| def construct(self, inputs1, inputs2, labels1, labels2): | |||
| out = self._backbone(inputs1, inputs2) | |||
| return self._loss_fn(out, labels) | |||
| return self._loss_fn(*out, labels1, labels2) | |||
| class GradWrapWithLoss(Cell): | |||
| @@ -98,8 +106,8 @@ class GradWrapWithLoss(Cell): | |||
| self._grad_all = GradOperation(get_all=True, sens_param=False) | |||
| self._network = network | |||
| def construct(self, inputs1, inputs2, labels): | |||
| gout = self._grad_all(self._network)(inputs1, inputs2, labels) | |||
| def construct(self, *inputs): | |||
| gout = self._grad_all(self._network)(*inputs) | |||
| return gout[0] | |||
| @@ -285,18 +293,17 @@ def test_fast_gradient_method_multi_inputs(): | |||
| Fast gradient method unit test. | |||
| """ | |||
| context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") | |||
| input_np = np.asarray([[0.1, 0.2, 0.7]]).astype(np.float32) | |||
| anno_np = np.asarray([[0.4, 0.8, 0.5]]).astype(np.float32) | |||
| label = np.asarray([2], np.int32) | |||
| label = np.eye(3)[label].astype(np.float32) | |||
| inputs1 = np.asarray([[0.1, 0.2, 0.7]]).astype(np.float32) | |||
| inputs2 = np.asarray([[0.4, 0.8, 0.5]]).astype(np.float32) | |||
| labels1 = np.expand_dims(np.eye(3)[1].astype(np.float32), axis=0) | |||
| labels2 = np.expand_dims(np.eye(3)[2].astype(np.float32), axis=0) | |||
| loss_fn = SoftmaxCrossEntropyWithLogits(sparse=False) | |||
| with_loss_cell = WithLossCell(Net2(), loss_fn) | |||
| with_loss_cell = WithLossCell(Net2(), LossNet()) | |||
| grad_with_loss_net = GradWrapWithLoss(with_loss_cell) | |||
| attack = FastGradientMethod(grad_with_loss_net) | |||
| ms_adv_x = attack.generate(input_np, (anno_np, label)) | |||
| ms_adv_x = attack.generate((inputs1, inputs2), (labels1, labels2)) | |||
| assert np.any(ms_adv_x != input_np), 'Fast gradient method: generate value' \ | |||
| assert np.any(ms_adv_x != inputs1), 'Fast gradient method: generate value' \ | |||
| ' must not be equal to original value.' | |||
| @@ -332,18 +339,17 @@ def test_batch_generate_multi_inputs(): | |||
| Fast gradient method unit test. | |||
| """ | |||
| context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") | |||
| input_np = np.random.random([10, 3]).astype(np.float32) | |||
| anno_np = np.random.random([10, 3]).astype(np.float32) | |||
| label = np.random.randint(0, 3, [10]) | |||
| label = np.eye(3)[label].astype(np.float32) | |||
| inputs1 = np.asarray([[0.1, 0.2, 0.7]]).astype(np.float32) | |||
| inputs2 = np.asarray([[0.4, 0.8, 0.5]]).astype(np.float32) | |||
| labels1 = np.expand_dims(np.eye(3)[1].astype(np.float32), axis=0) | |||
| labels2 = np.expand_dims(np.eye(3)[2].astype(np.float32), axis=0) | |||
| loss_fn = SoftmaxCrossEntropyWithLogits(sparse=False) | |||
| with_loss_cell = WithLossCell(Net2(), loss_fn) | |||
| with_loss_cell = WithLossCell(Net2(), LossNet()) | |||
| grad_with_loss_net = GradWrapWithLoss(with_loss_cell) | |||
| attack = FastGradientMethod(grad_with_loss_net) | |||
| ms_adv_x = attack.generate(input_np, (anno_np, label)) | |||
| ms_adv_x = attack.generate((inputs1, inputs2), (labels1, labels2)) | |||
| assert np.any(ms_adv_x != input_np), 'Fast gradient method: generate value' \ | |||
| assert np.any(ms_adv_x != inputs1), 'Fast gradient method: generate value' \ | |||
| ' must not be equal to original value.' | |||